From 612036408bb02037b4d7084f42b248ab75bd5a2b Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Fri, 28 May 2021 15:11:37 -0700 Subject: [PATCH 001/352] Rename Client to client --- {Client => client}/.dockerignore | 0 {Client => client}/.eslintrc.json | 0 {Client => client}/.gitattributes | 0 {Client => client}/.gitignore | 0 {Client => client}/.vscode/settings.json | 0 {Client => client}/Dockerfile | 0 {Client => client}/README.md | 0 {Client => client}/babel.config.js | 0 {Client => client}/build.bat | 0 {Client => client}/gulp.bat | 0 {Client => client}/gulpfile.js | 0 {Client => client}/package-lock.json | 0 {Client => client}/package.json | 0 {Client => client}/server/main.js | 0 {Client => client}/server/toxy-proxy.js | 0 {Client => client}/src/Web.config | 0 {Client => client}/src/html/buildinfo.hbs | 0 {Client => client}/src/html/index.hbs | 0 {Client => client}/src/images/blueline.png | Bin {Client => client}/src/images/gov/bceid_logo.png | Bin {Client => client}/src/images/gov/favicon.png | Bin {Client => client}/src/images/gov/gov3_bc_logo.png | Bin {Client => client}/src/images/gov/hets.jpg | Bin {Client => client}/src/images/greyline.png | Bin {Client => client}/src/js/App.jsx | 0 {Client => client}/src/js/actionTypes.js | 0 {Client => client}/src/js/actions.js | 0 {Client => client}/src/js/api.js | 0 {Client => client}/src/js/components/Authorize.jsx | 0 {Client => client}/src/js/components/BadgeLabel.jsx | 0 .../src/js/components/CheckboxControl.jsx | 0 {Client => client}/src/js/components/ColDisplay.jsx | 0 {Client => client}/src/js/components/Confirm.jsx | 0 {Client => client}/src/js/components/Countdown.jsx | 0 .../src/js/components/DateControl.jsx | 0 .../src/js/components/DeleteButton.jsx | 0 .../src/js/components/DropdownControl.jsx | 0 {Client => client}/src/js/components/EditButton.jsx | 0 {Client => client}/src/js/components/Favourites.jsx | 0 .../src/js/components/FileAttachDialog.jsx | 0 {Client => client}/src/js/components/FilePicker.jsx | 0 {Client => client}/src/js/components/FileUpload.jsx | 0 .../src/js/components/FilterDropdown.jsx | 0 {Client => client}/src/js/components/Form.jsx | 0 {Client => client}/src/js/components/FormDialog.jsx | 0 .../src/js/components/FormInputControl.jsx | 0 {Client => client}/src/js/components/History.jsx | 0 .../src/js/components/LinkControl.jsx | 0 {Client => client}/src/js/components/Mailto.jsx | 0 .../src/js/components/ModalDialog.jsx | 0 .../src/js/components/MultiDropdown.jsx | 0 .../src/js/components/OverlayTrigger.jsx | 0 .../src/js/components/PageOrientation.jsx | 0 .../src/js/components/PrintButton.jsx | 0 .../src/js/components/ReturnButton.jsx | 0 .../src/js/components/RootCloseMenu.jsx | 0 .../src/js/components/SearchControl.jsx | 0 {Client => client}/src/js/components/SortTable.jsx | 0 {Client => client}/src/js/components/Spinner.jsx | 0 .../src/js/components/StatusDropdown.jsx | 0 .../src/js/components/TableControl.jsx | 0 .../src/js/components/TooltipButton.jsx | 0 .../src/js/components/Unimplemented.jsx | 0 {Client => client}/src/js/components/Watermark.jsx | 0 .../src/js/components/ui/AddButtonContainer.jsx | 0 .../src/js/components/ui/PageHeader.jsx | 0 .../src/js/components/ui/SearchBar.jsx | 0 .../src/js/components/ui/SubHeader.jsx | 0 {Client => client}/src/js/constants.js | 0 {Client => client}/src/js/history.js | 0 {Client => client}/src/js/init.js | 0 {Client => client}/src/js/reducers/all.js | 0 {Client => client}/src/js/reducers/lookups.js | 0 {Client => client}/src/js/reducers/models.js | 0 {Client => client}/src/js/reducers/search.js | 0 {Client => client}/src/js/reducers/ui.js | 0 {Client => client}/src/js/reducers/user.js | 0 {Client => client}/src/js/reducers/version.js | 0 .../src/js/selectors/history-selectors.js | 0 {Client => client}/src/js/selectors/ui-selectors.js | 0 {Client => client}/src/js/store.js | 0 {Client => client}/src/js/utils/array.js | 0 {Client => client}/src/js/utils/date.js | 0 {Client => client}/src/js/utils/http.js | 0 {Client => client}/src/js/utils/routes.js | 0 {Client => client}/src/js/utils/string.js | 0 {Client => client}/src/js/utils/string_test.js | 0 {Client => client}/src/js/views/404.jsx | 0 {Client => client}/src/js/views/AitReport.jsx | 0 {Client => client}/src/js/views/BusinessOwner.jsx | 0 {Client => client}/src/js/views/BusinessPortal.jsx | 0 {Client => client}/src/js/views/DistrictAdmin.jsx | 0 {Client => client}/src/js/views/Equipment.jsx | 0 {Client => client}/src/js/views/EquipmentDetail.jsx | 0 {Client => client}/src/js/views/EquipmentTable.jsx | 0 {Client => client}/src/js/views/Footer.jsx | 0 {Client => client}/src/js/views/HiringReport.jsx | 0 {Client => client}/src/js/views/Home.jsx | 0 {Client => client}/src/js/views/Main.jsx | 0 {Client => client}/src/js/views/OvertimeRates.jsx | 0 {Client => client}/src/js/views/Owners.jsx | 0 {Client => client}/src/js/views/OwnersDetail.jsx | 0 {Client => client}/src/js/views/Projects.jsx | 0 {Client => client}/src/js/views/ProjectsDetail.jsx | 0 .../src/js/views/RentalAgreementsDetail.jsx | 0 {Client => client}/src/js/views/RentalRequests.jsx | 0 .../src/js/views/RentalRequestsDetail.jsx | 0 {Client => client}/src/js/views/Roles.jsx | 0 {Client => client}/src/js/views/RolesDetail.jsx | 0 {Client => client}/src/js/views/Rollover.jsx | 0 {Client => client}/src/js/views/SeniorityList.jsx | 0 {Client => client}/src/js/views/StatusLetters.jsx | 0 {Client => client}/src/js/views/TimeEntry.jsx | 0 {Client => client}/src/js/views/TopNav.jsx | 0 {Client => client}/src/js/views/Users.jsx | 0 {Client => client}/src/js/views/UsersDetail.jsx | 0 {Client => client}/src/js/views/Version.jsx | 0 {Client => client}/src/js/views/WcbCglCoverage.jsx | 0 .../src/js/views/dialogs/AttachmentAddDialog.jsx | 0 .../src/js/views/dialogs/AttachmentEditDialog.jsx | 0 .../src/js/views/dialogs/CloneDialog.jsx | 0 .../src/js/views/dialogs/ConditionAddEditDialog.jsx | 0 .../src/js/views/dialogs/ConfirmDialog.jsx | 0 .../src/js/views/dialogs/ConfirmForceHireDialog.jsx | 0 .../src/js/views/dialogs/ContactsEditDialog.jsx | 0 .../src/js/views/dialogs/DistrictEditDialog.jsx | 0 .../dialogs/DistrictEquipmentTypeAddEditDialog.jsx | 0 .../src/js/views/dialogs/DocumentsListDialog.jsx | 0 .../src/js/views/dialogs/EquipmentAddDialog.jsx | 0 .../views/dialogs/EquipmentChangeStatusDialog.jsx | 0 .../src/js/views/dialogs/EquipmentEditDialog.jsx | 0 .../dialogs/EquipmentRentalRatesEditDialog.jsx | 0 .../js/views/dialogs/EquipmentTransferDialog.jsx | 0 .../src/js/views/dialogs/ErrorDialog.jsx | 0 .../src/js/views/dialogs/HireOfferEditDialog.jsx | 0 .../src/js/views/dialogs/NotesAddDialog.jsx | 0 .../src/js/views/dialogs/NotesDialog.jsx | 0 .../src/js/views/dialogs/OvertimeRateEditDialog.jsx | 0 .../js/views/dialogs/OwnerChangeStatusDialog.jsx | 0 .../src/js/views/dialogs/OwnersAddDialog.jsx | 0 .../src/js/views/dialogs/OwnersEditDialog.jsx | 0 .../src/js/views/dialogs/OwnersPolicyEditDialog.jsx | 0 .../src/js/views/dialogs/ProjectsAddDialog.jsx | 0 .../src/js/views/dialogs/ProjectsEditDialog.jsx | 0 .../dialogs/RentalAgreementOvertimeNotesDialog.jsx | 0 .../js/views/dialogs/RentalAgreementsEditDialog.jsx | 0 .../js/views/dialogs/RentalConditionsEditDialog.jsx | 0 .../src/js/views/dialogs/RentalRatesEditDialog.jsx | 0 .../js/views/dialogs/RentalRequestsAddDialog.jsx | 0 .../js/views/dialogs/RentalRequestsEditDialog.jsx | 0 .../src/js/views/dialogs/SeniorityEditDialog.jsx | 0 .../src/js/views/dialogs/TimeEntryDialog.jsx | 0 .../src/js/views/dialogs/UserRoleAddDialog.jsx | 0 .../src/js/views/dialogs/UsersEditDialog.jsx | 0 {Client => client}/src/robots.txt | 0 {Client => client}/src/sass/components/all.scss | 0 .../src/sass/components/badge-label.scss | 0 .../src/sass/components/clone-dialog.scss | 0 .../src/sass/components/date-control.scss | 0 .../src/sass/components/dropdown-control.scss | 0 .../src/sass/components/favourites.scss | 0 .../src/sass/components/file-upload.scss | 0 .../src/sass/components/filter-dropdown.scss | 0 .../src/sass/components/form-dialog.scss | 0 .../src/sass/components/form-input-control.scss | 0 {Client => client}/src/sass/components/history.scss | 0 .../src/sass/components/link-control.scss | 0 .../src/sass/components/multi-dropdown.scss | 0 .../src/sass/components/print-button.scss | 0 .../src/sass/components/return-button.scss | 0 .../src/sass/components/search-control.scss | 0 .../src/sass/components/sort-table.scss | 0 .../sass/components/ui/add-button-container.scss | 0 .../src/sass/components/ui/page-header.scss | 0 .../src/sass/components/ui/search-bar.scss | 0 .../src/sass/components/ui/subheader.scss | 0 {Client => client}/src/sass/gov3.scss | 0 {Client => client}/src/sass/header.scss | 0 {Client => client}/src/sass/init.scss | 0 {Client => client}/src/sass/main.scss | 0 {Client => client}/src/sass/mixins.scss | 0 {Client => client}/src/sass/print.scss | 0 {Client => client}/src/sass/variables.scss | 0 {Client => client}/src/sass/views/all.scss | 0 .../src/sass/views/business-portal.scss | 0 {Client => client}/src/sass/views/dialogs/all.scss | 0 .../src/sass/views/dialogs/contacts-edit.scss | 0 .../src/sass/views/dialogs/documents-list.scss | 0 .../src/sass/views/dialogs/equipment-transfer.scss | 0 .../src/sass/views/dialogs/error-dialog.scss | 0 .../src/sass/views/dialogs/notes.scss | 0 .../src/sass/views/dialogs/rental-rates-edit.scss | 0 .../src/sass/views/district-admin.scss | 0 .../src/sass/views/equipment-list.scss | 0 {Client => client}/src/sass/views/home.scss | 0 {Client => client}/src/sass/views/owners.scss | 0 {Client => client}/src/sass/views/projects.scss | 0 .../src/sass/views/rental-agreements.scss | 0 .../src/sass/views/rental-requests.scss | 0 {Client => client}/src/sass/views/roles.scss | 0 {Client => client}/src/sass/views/rollover.scss | 0 {Client => client}/src/sass/views/users.scss | 0 {Client => client}/test/index.html | 0 {Client => client}/test/spec/load.js | 0 {Client => client}/typings/node/node.d.ts | 0 {Client => client}/webpack.config.js | 0 206 files changed, 0 insertions(+), 0 deletions(-) rename {Client => client}/.dockerignore (100%) rename {Client => client}/.eslintrc.json (100%) rename {Client => client}/.gitattributes (100%) rename {Client => client}/.gitignore (100%) rename {Client => client}/.vscode/settings.json (100%) rename {Client => client}/Dockerfile (100%) rename {Client => client}/README.md (100%) rename {Client => client}/babel.config.js (100%) rename {Client => client}/build.bat (100%) rename {Client => client}/gulp.bat (100%) rename {Client => client}/gulpfile.js (100%) rename {Client => client}/package-lock.json (100%) rename {Client => client}/package.json (100%) rename {Client => client}/server/main.js (100%) rename {Client => client}/server/toxy-proxy.js (100%) rename {Client => client}/src/Web.config (100%) rename {Client => client}/src/html/buildinfo.hbs (100%) rename {Client => client}/src/html/index.hbs (100%) rename {Client => client}/src/images/blueline.png (100%) rename {Client => client}/src/images/gov/bceid_logo.png (100%) rename {Client => client}/src/images/gov/favicon.png (100%) rename {Client => client}/src/images/gov/gov3_bc_logo.png (100%) rename {Client => client}/src/images/gov/hets.jpg (100%) rename {Client => client}/src/images/greyline.png (100%) rename {Client => client}/src/js/App.jsx (100%) rename {Client => client}/src/js/actionTypes.js (100%) rename {Client => client}/src/js/actions.js (100%) rename {Client => client}/src/js/api.js (100%) rename {Client => client}/src/js/components/Authorize.jsx (100%) rename {Client => client}/src/js/components/BadgeLabel.jsx (100%) rename {Client => client}/src/js/components/CheckboxControl.jsx (100%) rename {Client => client}/src/js/components/ColDisplay.jsx (100%) rename {Client => client}/src/js/components/Confirm.jsx (100%) rename {Client => client}/src/js/components/Countdown.jsx (100%) rename {Client => client}/src/js/components/DateControl.jsx (100%) rename {Client => client}/src/js/components/DeleteButton.jsx (100%) rename {Client => client}/src/js/components/DropdownControl.jsx (100%) rename {Client => client}/src/js/components/EditButton.jsx (100%) rename {Client => client}/src/js/components/Favourites.jsx (100%) rename {Client => client}/src/js/components/FileAttachDialog.jsx (100%) rename {Client => client}/src/js/components/FilePicker.jsx (100%) rename {Client => client}/src/js/components/FileUpload.jsx (100%) rename {Client => client}/src/js/components/FilterDropdown.jsx (100%) rename {Client => client}/src/js/components/Form.jsx (100%) rename {Client => client}/src/js/components/FormDialog.jsx (100%) rename {Client => client}/src/js/components/FormInputControl.jsx (100%) rename {Client => client}/src/js/components/History.jsx (100%) rename {Client => client}/src/js/components/LinkControl.jsx (100%) rename {Client => client}/src/js/components/Mailto.jsx (100%) rename {Client => client}/src/js/components/ModalDialog.jsx (100%) rename {Client => client}/src/js/components/MultiDropdown.jsx (100%) rename {Client => client}/src/js/components/OverlayTrigger.jsx (100%) rename {Client => client}/src/js/components/PageOrientation.jsx (100%) rename {Client => client}/src/js/components/PrintButton.jsx (100%) rename {Client => client}/src/js/components/ReturnButton.jsx (100%) rename {Client => client}/src/js/components/RootCloseMenu.jsx (100%) rename {Client => client}/src/js/components/SearchControl.jsx (100%) rename {Client => client}/src/js/components/SortTable.jsx (100%) rename {Client => client}/src/js/components/Spinner.jsx (100%) rename {Client => client}/src/js/components/StatusDropdown.jsx (100%) rename {Client => client}/src/js/components/TableControl.jsx (100%) rename {Client => client}/src/js/components/TooltipButton.jsx (100%) rename {Client => client}/src/js/components/Unimplemented.jsx (100%) rename {Client => client}/src/js/components/Watermark.jsx (100%) rename {Client => client}/src/js/components/ui/AddButtonContainer.jsx (100%) rename {Client => client}/src/js/components/ui/PageHeader.jsx (100%) rename {Client => client}/src/js/components/ui/SearchBar.jsx (100%) rename {Client => client}/src/js/components/ui/SubHeader.jsx (100%) rename {Client => client}/src/js/constants.js (100%) rename {Client => client}/src/js/history.js (100%) rename {Client => client}/src/js/init.js (100%) rename {Client => client}/src/js/reducers/all.js (100%) rename {Client => client}/src/js/reducers/lookups.js (100%) rename {Client => client}/src/js/reducers/models.js (100%) rename {Client => client}/src/js/reducers/search.js (100%) rename {Client => client}/src/js/reducers/ui.js (100%) rename {Client => client}/src/js/reducers/user.js (100%) rename {Client => client}/src/js/reducers/version.js (100%) rename {Client => client}/src/js/selectors/history-selectors.js (100%) rename {Client => client}/src/js/selectors/ui-selectors.js (100%) rename {Client => client}/src/js/store.js (100%) rename {Client => client}/src/js/utils/array.js (100%) rename {Client => client}/src/js/utils/date.js (100%) rename {Client => client}/src/js/utils/http.js (100%) rename {Client => client}/src/js/utils/routes.js (100%) rename {Client => client}/src/js/utils/string.js (100%) rename {Client => client}/src/js/utils/string_test.js (100%) rename {Client => client}/src/js/views/404.jsx (100%) rename {Client => client}/src/js/views/AitReport.jsx (100%) rename {Client => client}/src/js/views/BusinessOwner.jsx (100%) rename {Client => client}/src/js/views/BusinessPortal.jsx (100%) rename {Client => client}/src/js/views/DistrictAdmin.jsx (100%) rename {Client => client}/src/js/views/Equipment.jsx (100%) rename {Client => client}/src/js/views/EquipmentDetail.jsx (100%) rename {Client => client}/src/js/views/EquipmentTable.jsx (100%) rename {Client => client}/src/js/views/Footer.jsx (100%) rename {Client => client}/src/js/views/HiringReport.jsx (100%) rename {Client => client}/src/js/views/Home.jsx (100%) rename {Client => client}/src/js/views/Main.jsx (100%) rename {Client => client}/src/js/views/OvertimeRates.jsx (100%) rename {Client => client}/src/js/views/Owners.jsx (100%) rename {Client => client}/src/js/views/OwnersDetail.jsx (100%) rename {Client => client}/src/js/views/Projects.jsx (100%) rename {Client => client}/src/js/views/ProjectsDetail.jsx (100%) rename {Client => client}/src/js/views/RentalAgreementsDetail.jsx (100%) rename {Client => client}/src/js/views/RentalRequests.jsx (100%) rename {Client => client}/src/js/views/RentalRequestsDetail.jsx (100%) rename {Client => client}/src/js/views/Roles.jsx (100%) rename {Client => client}/src/js/views/RolesDetail.jsx (100%) rename {Client => client}/src/js/views/Rollover.jsx (100%) rename {Client => client}/src/js/views/SeniorityList.jsx (100%) rename {Client => client}/src/js/views/StatusLetters.jsx (100%) rename {Client => client}/src/js/views/TimeEntry.jsx (100%) rename {Client => client}/src/js/views/TopNav.jsx (100%) rename {Client => client}/src/js/views/Users.jsx (100%) rename {Client => client}/src/js/views/UsersDetail.jsx (100%) rename {Client => client}/src/js/views/Version.jsx (100%) rename {Client => client}/src/js/views/WcbCglCoverage.jsx (100%) rename {Client => client}/src/js/views/dialogs/AttachmentAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/AttachmentEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/CloneDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ConditionAddEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ConfirmDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ConfirmForceHireDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ContactsEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/DistrictEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/DocumentsListDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/EquipmentAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/EquipmentEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/EquipmentTransferDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ErrorDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/HireOfferEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/NotesAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/NotesDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/OvertimeRateEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/OwnerChangeStatusDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/OwnersAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/OwnersEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/OwnersPolicyEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ProjectsAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/ProjectsEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalAgreementsEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalConditionsEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalRatesEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalRequestsAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/RentalRequestsEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/SeniorityEditDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/TimeEntryDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/UserRoleAddDialog.jsx (100%) rename {Client => client}/src/js/views/dialogs/UsersEditDialog.jsx (100%) rename {Client => client}/src/robots.txt (100%) rename {Client => client}/src/sass/components/all.scss (100%) rename {Client => client}/src/sass/components/badge-label.scss (100%) rename {Client => client}/src/sass/components/clone-dialog.scss (100%) rename {Client => client}/src/sass/components/date-control.scss (100%) rename {Client => client}/src/sass/components/dropdown-control.scss (100%) rename {Client => client}/src/sass/components/favourites.scss (100%) rename {Client => client}/src/sass/components/file-upload.scss (100%) rename {Client => client}/src/sass/components/filter-dropdown.scss (100%) rename {Client => client}/src/sass/components/form-dialog.scss (100%) rename {Client => client}/src/sass/components/form-input-control.scss (100%) rename {Client => client}/src/sass/components/history.scss (100%) rename {Client => client}/src/sass/components/link-control.scss (100%) rename {Client => client}/src/sass/components/multi-dropdown.scss (100%) rename {Client => client}/src/sass/components/print-button.scss (100%) rename {Client => client}/src/sass/components/return-button.scss (100%) rename {Client => client}/src/sass/components/search-control.scss (100%) rename {Client => client}/src/sass/components/sort-table.scss (100%) rename {Client => client}/src/sass/components/ui/add-button-container.scss (100%) rename {Client => client}/src/sass/components/ui/page-header.scss (100%) rename {Client => client}/src/sass/components/ui/search-bar.scss (100%) rename {Client => client}/src/sass/components/ui/subheader.scss (100%) rename {Client => client}/src/sass/gov3.scss (100%) rename {Client => client}/src/sass/header.scss (100%) rename {Client => client}/src/sass/init.scss (100%) rename {Client => client}/src/sass/main.scss (100%) rename {Client => client}/src/sass/mixins.scss (100%) rename {Client => client}/src/sass/print.scss (100%) rename {Client => client}/src/sass/variables.scss (100%) rename {Client => client}/src/sass/views/all.scss (100%) rename {Client => client}/src/sass/views/business-portal.scss (100%) rename {Client => client}/src/sass/views/dialogs/all.scss (100%) rename {Client => client}/src/sass/views/dialogs/contacts-edit.scss (100%) rename {Client => client}/src/sass/views/dialogs/documents-list.scss (100%) rename {Client => client}/src/sass/views/dialogs/equipment-transfer.scss (100%) rename {Client => client}/src/sass/views/dialogs/error-dialog.scss (100%) rename {Client => client}/src/sass/views/dialogs/notes.scss (100%) rename {Client => client}/src/sass/views/dialogs/rental-rates-edit.scss (100%) rename {Client => client}/src/sass/views/district-admin.scss (100%) rename {Client => client}/src/sass/views/equipment-list.scss (100%) rename {Client => client}/src/sass/views/home.scss (100%) rename {Client => client}/src/sass/views/owners.scss (100%) rename {Client => client}/src/sass/views/projects.scss (100%) rename {Client => client}/src/sass/views/rental-agreements.scss (100%) rename {Client => client}/src/sass/views/rental-requests.scss (100%) rename {Client => client}/src/sass/views/roles.scss (100%) rename {Client => client}/src/sass/views/rollover.scss (100%) rename {Client => client}/src/sass/views/users.scss (100%) rename {Client => client}/test/index.html (100%) rename {Client => client}/test/spec/load.js (100%) rename {Client => client}/typings/node/node.d.ts (100%) rename {Client => client}/webpack.config.js (100%) diff --git a/Client/.dockerignore b/client/.dockerignore similarity index 100% rename from Client/.dockerignore rename to client/.dockerignore diff --git a/Client/.eslintrc.json b/client/.eslintrc.json similarity index 100% rename from Client/.eslintrc.json rename to client/.eslintrc.json diff --git a/Client/.gitattributes b/client/.gitattributes similarity index 100% rename from Client/.gitattributes rename to client/.gitattributes diff --git a/Client/.gitignore b/client/.gitignore similarity index 100% rename from Client/.gitignore rename to client/.gitignore diff --git a/Client/.vscode/settings.json b/client/.vscode/settings.json similarity index 100% rename from Client/.vscode/settings.json rename to client/.vscode/settings.json diff --git a/Client/Dockerfile b/client/Dockerfile similarity index 100% rename from Client/Dockerfile rename to client/Dockerfile diff --git a/Client/README.md b/client/README.md similarity index 100% rename from Client/README.md rename to client/README.md diff --git a/Client/babel.config.js b/client/babel.config.js similarity index 100% rename from Client/babel.config.js rename to client/babel.config.js diff --git a/Client/build.bat b/client/build.bat similarity index 100% rename from Client/build.bat rename to client/build.bat diff --git a/Client/gulp.bat b/client/gulp.bat similarity index 100% rename from Client/gulp.bat rename to client/gulp.bat diff --git a/Client/gulpfile.js b/client/gulpfile.js similarity index 100% rename from Client/gulpfile.js rename to client/gulpfile.js diff --git a/Client/package-lock.json b/client/package-lock.json similarity index 100% rename from Client/package-lock.json rename to client/package-lock.json diff --git a/Client/package.json b/client/package.json similarity index 100% rename from Client/package.json rename to client/package.json diff --git a/Client/server/main.js b/client/server/main.js similarity index 100% rename from Client/server/main.js rename to client/server/main.js diff --git a/Client/server/toxy-proxy.js b/client/server/toxy-proxy.js similarity index 100% rename from Client/server/toxy-proxy.js rename to client/server/toxy-proxy.js diff --git a/Client/src/Web.config b/client/src/Web.config similarity index 100% rename from Client/src/Web.config rename to client/src/Web.config diff --git a/Client/src/html/buildinfo.hbs b/client/src/html/buildinfo.hbs similarity index 100% rename from Client/src/html/buildinfo.hbs rename to client/src/html/buildinfo.hbs diff --git a/Client/src/html/index.hbs b/client/src/html/index.hbs similarity index 100% rename from Client/src/html/index.hbs rename to client/src/html/index.hbs diff --git a/Client/src/images/blueline.png b/client/src/images/blueline.png similarity index 100% rename from Client/src/images/blueline.png rename to client/src/images/blueline.png diff --git a/Client/src/images/gov/bceid_logo.png b/client/src/images/gov/bceid_logo.png similarity index 100% rename from Client/src/images/gov/bceid_logo.png rename to client/src/images/gov/bceid_logo.png diff --git a/Client/src/images/gov/favicon.png b/client/src/images/gov/favicon.png similarity index 100% rename from Client/src/images/gov/favicon.png rename to client/src/images/gov/favicon.png diff --git a/Client/src/images/gov/gov3_bc_logo.png b/client/src/images/gov/gov3_bc_logo.png similarity index 100% rename from Client/src/images/gov/gov3_bc_logo.png rename to client/src/images/gov/gov3_bc_logo.png diff --git a/Client/src/images/gov/hets.jpg b/client/src/images/gov/hets.jpg similarity index 100% rename from Client/src/images/gov/hets.jpg rename to client/src/images/gov/hets.jpg diff --git a/Client/src/images/greyline.png b/client/src/images/greyline.png similarity index 100% rename from Client/src/images/greyline.png rename to client/src/images/greyline.png diff --git a/Client/src/js/App.jsx b/client/src/js/App.jsx similarity index 100% rename from Client/src/js/App.jsx rename to client/src/js/App.jsx diff --git a/Client/src/js/actionTypes.js b/client/src/js/actionTypes.js similarity index 100% rename from Client/src/js/actionTypes.js rename to client/src/js/actionTypes.js diff --git a/Client/src/js/actions.js b/client/src/js/actions.js similarity index 100% rename from Client/src/js/actions.js rename to client/src/js/actions.js diff --git a/Client/src/js/api.js b/client/src/js/api.js similarity index 100% rename from Client/src/js/api.js rename to client/src/js/api.js diff --git a/Client/src/js/components/Authorize.jsx b/client/src/js/components/Authorize.jsx similarity index 100% rename from Client/src/js/components/Authorize.jsx rename to client/src/js/components/Authorize.jsx diff --git a/Client/src/js/components/BadgeLabel.jsx b/client/src/js/components/BadgeLabel.jsx similarity index 100% rename from Client/src/js/components/BadgeLabel.jsx rename to client/src/js/components/BadgeLabel.jsx diff --git a/Client/src/js/components/CheckboxControl.jsx b/client/src/js/components/CheckboxControl.jsx similarity index 100% rename from Client/src/js/components/CheckboxControl.jsx rename to client/src/js/components/CheckboxControl.jsx diff --git a/Client/src/js/components/ColDisplay.jsx b/client/src/js/components/ColDisplay.jsx similarity index 100% rename from Client/src/js/components/ColDisplay.jsx rename to client/src/js/components/ColDisplay.jsx diff --git a/Client/src/js/components/Confirm.jsx b/client/src/js/components/Confirm.jsx similarity index 100% rename from Client/src/js/components/Confirm.jsx rename to client/src/js/components/Confirm.jsx diff --git a/Client/src/js/components/Countdown.jsx b/client/src/js/components/Countdown.jsx similarity index 100% rename from Client/src/js/components/Countdown.jsx rename to client/src/js/components/Countdown.jsx diff --git a/Client/src/js/components/DateControl.jsx b/client/src/js/components/DateControl.jsx similarity index 100% rename from Client/src/js/components/DateControl.jsx rename to client/src/js/components/DateControl.jsx diff --git a/Client/src/js/components/DeleteButton.jsx b/client/src/js/components/DeleteButton.jsx similarity index 100% rename from Client/src/js/components/DeleteButton.jsx rename to client/src/js/components/DeleteButton.jsx diff --git a/Client/src/js/components/DropdownControl.jsx b/client/src/js/components/DropdownControl.jsx similarity index 100% rename from Client/src/js/components/DropdownControl.jsx rename to client/src/js/components/DropdownControl.jsx diff --git a/Client/src/js/components/EditButton.jsx b/client/src/js/components/EditButton.jsx similarity index 100% rename from Client/src/js/components/EditButton.jsx rename to client/src/js/components/EditButton.jsx diff --git a/Client/src/js/components/Favourites.jsx b/client/src/js/components/Favourites.jsx similarity index 100% rename from Client/src/js/components/Favourites.jsx rename to client/src/js/components/Favourites.jsx diff --git a/Client/src/js/components/FileAttachDialog.jsx b/client/src/js/components/FileAttachDialog.jsx similarity index 100% rename from Client/src/js/components/FileAttachDialog.jsx rename to client/src/js/components/FileAttachDialog.jsx diff --git a/Client/src/js/components/FilePicker.jsx b/client/src/js/components/FilePicker.jsx similarity index 100% rename from Client/src/js/components/FilePicker.jsx rename to client/src/js/components/FilePicker.jsx diff --git a/Client/src/js/components/FileUpload.jsx b/client/src/js/components/FileUpload.jsx similarity index 100% rename from Client/src/js/components/FileUpload.jsx rename to client/src/js/components/FileUpload.jsx diff --git a/Client/src/js/components/FilterDropdown.jsx b/client/src/js/components/FilterDropdown.jsx similarity index 100% rename from Client/src/js/components/FilterDropdown.jsx rename to client/src/js/components/FilterDropdown.jsx diff --git a/Client/src/js/components/Form.jsx b/client/src/js/components/Form.jsx similarity index 100% rename from Client/src/js/components/Form.jsx rename to client/src/js/components/Form.jsx diff --git a/Client/src/js/components/FormDialog.jsx b/client/src/js/components/FormDialog.jsx similarity index 100% rename from Client/src/js/components/FormDialog.jsx rename to client/src/js/components/FormDialog.jsx diff --git a/Client/src/js/components/FormInputControl.jsx b/client/src/js/components/FormInputControl.jsx similarity index 100% rename from Client/src/js/components/FormInputControl.jsx rename to client/src/js/components/FormInputControl.jsx diff --git a/Client/src/js/components/History.jsx b/client/src/js/components/History.jsx similarity index 100% rename from Client/src/js/components/History.jsx rename to client/src/js/components/History.jsx diff --git a/Client/src/js/components/LinkControl.jsx b/client/src/js/components/LinkControl.jsx similarity index 100% rename from Client/src/js/components/LinkControl.jsx rename to client/src/js/components/LinkControl.jsx diff --git a/Client/src/js/components/Mailto.jsx b/client/src/js/components/Mailto.jsx similarity index 100% rename from Client/src/js/components/Mailto.jsx rename to client/src/js/components/Mailto.jsx diff --git a/Client/src/js/components/ModalDialog.jsx b/client/src/js/components/ModalDialog.jsx similarity index 100% rename from Client/src/js/components/ModalDialog.jsx rename to client/src/js/components/ModalDialog.jsx diff --git a/Client/src/js/components/MultiDropdown.jsx b/client/src/js/components/MultiDropdown.jsx similarity index 100% rename from Client/src/js/components/MultiDropdown.jsx rename to client/src/js/components/MultiDropdown.jsx diff --git a/Client/src/js/components/OverlayTrigger.jsx b/client/src/js/components/OverlayTrigger.jsx similarity index 100% rename from Client/src/js/components/OverlayTrigger.jsx rename to client/src/js/components/OverlayTrigger.jsx diff --git a/Client/src/js/components/PageOrientation.jsx b/client/src/js/components/PageOrientation.jsx similarity index 100% rename from Client/src/js/components/PageOrientation.jsx rename to client/src/js/components/PageOrientation.jsx diff --git a/Client/src/js/components/PrintButton.jsx b/client/src/js/components/PrintButton.jsx similarity index 100% rename from Client/src/js/components/PrintButton.jsx rename to client/src/js/components/PrintButton.jsx diff --git a/Client/src/js/components/ReturnButton.jsx b/client/src/js/components/ReturnButton.jsx similarity index 100% rename from Client/src/js/components/ReturnButton.jsx rename to client/src/js/components/ReturnButton.jsx diff --git a/Client/src/js/components/RootCloseMenu.jsx b/client/src/js/components/RootCloseMenu.jsx similarity index 100% rename from Client/src/js/components/RootCloseMenu.jsx rename to client/src/js/components/RootCloseMenu.jsx diff --git a/Client/src/js/components/SearchControl.jsx b/client/src/js/components/SearchControl.jsx similarity index 100% rename from Client/src/js/components/SearchControl.jsx rename to client/src/js/components/SearchControl.jsx diff --git a/Client/src/js/components/SortTable.jsx b/client/src/js/components/SortTable.jsx similarity index 100% rename from Client/src/js/components/SortTable.jsx rename to client/src/js/components/SortTable.jsx diff --git a/Client/src/js/components/Spinner.jsx b/client/src/js/components/Spinner.jsx similarity index 100% rename from Client/src/js/components/Spinner.jsx rename to client/src/js/components/Spinner.jsx diff --git a/Client/src/js/components/StatusDropdown.jsx b/client/src/js/components/StatusDropdown.jsx similarity index 100% rename from Client/src/js/components/StatusDropdown.jsx rename to client/src/js/components/StatusDropdown.jsx diff --git a/Client/src/js/components/TableControl.jsx b/client/src/js/components/TableControl.jsx similarity index 100% rename from Client/src/js/components/TableControl.jsx rename to client/src/js/components/TableControl.jsx diff --git a/Client/src/js/components/TooltipButton.jsx b/client/src/js/components/TooltipButton.jsx similarity index 100% rename from Client/src/js/components/TooltipButton.jsx rename to client/src/js/components/TooltipButton.jsx diff --git a/Client/src/js/components/Unimplemented.jsx b/client/src/js/components/Unimplemented.jsx similarity index 100% rename from Client/src/js/components/Unimplemented.jsx rename to client/src/js/components/Unimplemented.jsx diff --git a/Client/src/js/components/Watermark.jsx b/client/src/js/components/Watermark.jsx similarity index 100% rename from Client/src/js/components/Watermark.jsx rename to client/src/js/components/Watermark.jsx diff --git a/Client/src/js/components/ui/AddButtonContainer.jsx b/client/src/js/components/ui/AddButtonContainer.jsx similarity index 100% rename from Client/src/js/components/ui/AddButtonContainer.jsx rename to client/src/js/components/ui/AddButtonContainer.jsx diff --git a/Client/src/js/components/ui/PageHeader.jsx b/client/src/js/components/ui/PageHeader.jsx similarity index 100% rename from Client/src/js/components/ui/PageHeader.jsx rename to client/src/js/components/ui/PageHeader.jsx diff --git a/Client/src/js/components/ui/SearchBar.jsx b/client/src/js/components/ui/SearchBar.jsx similarity index 100% rename from Client/src/js/components/ui/SearchBar.jsx rename to client/src/js/components/ui/SearchBar.jsx diff --git a/Client/src/js/components/ui/SubHeader.jsx b/client/src/js/components/ui/SubHeader.jsx similarity index 100% rename from Client/src/js/components/ui/SubHeader.jsx rename to client/src/js/components/ui/SubHeader.jsx diff --git a/Client/src/js/constants.js b/client/src/js/constants.js similarity index 100% rename from Client/src/js/constants.js rename to client/src/js/constants.js diff --git a/Client/src/js/history.js b/client/src/js/history.js similarity index 100% rename from Client/src/js/history.js rename to client/src/js/history.js diff --git a/Client/src/js/init.js b/client/src/js/init.js similarity index 100% rename from Client/src/js/init.js rename to client/src/js/init.js diff --git a/Client/src/js/reducers/all.js b/client/src/js/reducers/all.js similarity index 100% rename from Client/src/js/reducers/all.js rename to client/src/js/reducers/all.js diff --git a/Client/src/js/reducers/lookups.js b/client/src/js/reducers/lookups.js similarity index 100% rename from Client/src/js/reducers/lookups.js rename to client/src/js/reducers/lookups.js diff --git a/Client/src/js/reducers/models.js b/client/src/js/reducers/models.js similarity index 100% rename from Client/src/js/reducers/models.js rename to client/src/js/reducers/models.js diff --git a/Client/src/js/reducers/search.js b/client/src/js/reducers/search.js similarity index 100% rename from Client/src/js/reducers/search.js rename to client/src/js/reducers/search.js diff --git a/Client/src/js/reducers/ui.js b/client/src/js/reducers/ui.js similarity index 100% rename from Client/src/js/reducers/ui.js rename to client/src/js/reducers/ui.js diff --git a/Client/src/js/reducers/user.js b/client/src/js/reducers/user.js similarity index 100% rename from Client/src/js/reducers/user.js rename to client/src/js/reducers/user.js diff --git a/Client/src/js/reducers/version.js b/client/src/js/reducers/version.js similarity index 100% rename from Client/src/js/reducers/version.js rename to client/src/js/reducers/version.js diff --git a/Client/src/js/selectors/history-selectors.js b/client/src/js/selectors/history-selectors.js similarity index 100% rename from Client/src/js/selectors/history-selectors.js rename to client/src/js/selectors/history-selectors.js diff --git a/Client/src/js/selectors/ui-selectors.js b/client/src/js/selectors/ui-selectors.js similarity index 100% rename from Client/src/js/selectors/ui-selectors.js rename to client/src/js/selectors/ui-selectors.js diff --git a/Client/src/js/store.js b/client/src/js/store.js similarity index 100% rename from Client/src/js/store.js rename to client/src/js/store.js diff --git a/Client/src/js/utils/array.js b/client/src/js/utils/array.js similarity index 100% rename from Client/src/js/utils/array.js rename to client/src/js/utils/array.js diff --git a/Client/src/js/utils/date.js b/client/src/js/utils/date.js similarity index 100% rename from Client/src/js/utils/date.js rename to client/src/js/utils/date.js diff --git a/Client/src/js/utils/http.js b/client/src/js/utils/http.js similarity index 100% rename from Client/src/js/utils/http.js rename to client/src/js/utils/http.js diff --git a/Client/src/js/utils/routes.js b/client/src/js/utils/routes.js similarity index 100% rename from Client/src/js/utils/routes.js rename to client/src/js/utils/routes.js diff --git a/Client/src/js/utils/string.js b/client/src/js/utils/string.js similarity index 100% rename from Client/src/js/utils/string.js rename to client/src/js/utils/string.js diff --git a/Client/src/js/utils/string_test.js b/client/src/js/utils/string_test.js similarity index 100% rename from Client/src/js/utils/string_test.js rename to client/src/js/utils/string_test.js diff --git a/Client/src/js/views/404.jsx b/client/src/js/views/404.jsx similarity index 100% rename from Client/src/js/views/404.jsx rename to client/src/js/views/404.jsx diff --git a/Client/src/js/views/AitReport.jsx b/client/src/js/views/AitReport.jsx similarity index 100% rename from Client/src/js/views/AitReport.jsx rename to client/src/js/views/AitReport.jsx diff --git a/Client/src/js/views/BusinessOwner.jsx b/client/src/js/views/BusinessOwner.jsx similarity index 100% rename from Client/src/js/views/BusinessOwner.jsx rename to client/src/js/views/BusinessOwner.jsx diff --git a/Client/src/js/views/BusinessPortal.jsx b/client/src/js/views/BusinessPortal.jsx similarity index 100% rename from Client/src/js/views/BusinessPortal.jsx rename to client/src/js/views/BusinessPortal.jsx diff --git a/Client/src/js/views/DistrictAdmin.jsx b/client/src/js/views/DistrictAdmin.jsx similarity index 100% rename from Client/src/js/views/DistrictAdmin.jsx rename to client/src/js/views/DistrictAdmin.jsx diff --git a/Client/src/js/views/Equipment.jsx b/client/src/js/views/Equipment.jsx similarity index 100% rename from Client/src/js/views/Equipment.jsx rename to client/src/js/views/Equipment.jsx diff --git a/Client/src/js/views/EquipmentDetail.jsx b/client/src/js/views/EquipmentDetail.jsx similarity index 100% rename from Client/src/js/views/EquipmentDetail.jsx rename to client/src/js/views/EquipmentDetail.jsx diff --git a/Client/src/js/views/EquipmentTable.jsx b/client/src/js/views/EquipmentTable.jsx similarity index 100% rename from Client/src/js/views/EquipmentTable.jsx rename to client/src/js/views/EquipmentTable.jsx diff --git a/Client/src/js/views/Footer.jsx b/client/src/js/views/Footer.jsx similarity index 100% rename from Client/src/js/views/Footer.jsx rename to client/src/js/views/Footer.jsx diff --git a/Client/src/js/views/HiringReport.jsx b/client/src/js/views/HiringReport.jsx similarity index 100% rename from Client/src/js/views/HiringReport.jsx rename to client/src/js/views/HiringReport.jsx diff --git a/Client/src/js/views/Home.jsx b/client/src/js/views/Home.jsx similarity index 100% rename from Client/src/js/views/Home.jsx rename to client/src/js/views/Home.jsx diff --git a/Client/src/js/views/Main.jsx b/client/src/js/views/Main.jsx similarity index 100% rename from Client/src/js/views/Main.jsx rename to client/src/js/views/Main.jsx diff --git a/Client/src/js/views/OvertimeRates.jsx b/client/src/js/views/OvertimeRates.jsx similarity index 100% rename from Client/src/js/views/OvertimeRates.jsx rename to client/src/js/views/OvertimeRates.jsx diff --git a/Client/src/js/views/Owners.jsx b/client/src/js/views/Owners.jsx similarity index 100% rename from Client/src/js/views/Owners.jsx rename to client/src/js/views/Owners.jsx diff --git a/Client/src/js/views/OwnersDetail.jsx b/client/src/js/views/OwnersDetail.jsx similarity index 100% rename from Client/src/js/views/OwnersDetail.jsx rename to client/src/js/views/OwnersDetail.jsx diff --git a/Client/src/js/views/Projects.jsx b/client/src/js/views/Projects.jsx similarity index 100% rename from Client/src/js/views/Projects.jsx rename to client/src/js/views/Projects.jsx diff --git a/Client/src/js/views/ProjectsDetail.jsx b/client/src/js/views/ProjectsDetail.jsx similarity index 100% rename from Client/src/js/views/ProjectsDetail.jsx rename to client/src/js/views/ProjectsDetail.jsx diff --git a/Client/src/js/views/RentalAgreementsDetail.jsx b/client/src/js/views/RentalAgreementsDetail.jsx similarity index 100% rename from Client/src/js/views/RentalAgreementsDetail.jsx rename to client/src/js/views/RentalAgreementsDetail.jsx diff --git a/Client/src/js/views/RentalRequests.jsx b/client/src/js/views/RentalRequests.jsx similarity index 100% rename from Client/src/js/views/RentalRequests.jsx rename to client/src/js/views/RentalRequests.jsx diff --git a/Client/src/js/views/RentalRequestsDetail.jsx b/client/src/js/views/RentalRequestsDetail.jsx similarity index 100% rename from Client/src/js/views/RentalRequestsDetail.jsx rename to client/src/js/views/RentalRequestsDetail.jsx diff --git a/Client/src/js/views/Roles.jsx b/client/src/js/views/Roles.jsx similarity index 100% rename from Client/src/js/views/Roles.jsx rename to client/src/js/views/Roles.jsx diff --git a/Client/src/js/views/RolesDetail.jsx b/client/src/js/views/RolesDetail.jsx similarity index 100% rename from Client/src/js/views/RolesDetail.jsx rename to client/src/js/views/RolesDetail.jsx diff --git a/Client/src/js/views/Rollover.jsx b/client/src/js/views/Rollover.jsx similarity index 100% rename from Client/src/js/views/Rollover.jsx rename to client/src/js/views/Rollover.jsx diff --git a/Client/src/js/views/SeniorityList.jsx b/client/src/js/views/SeniorityList.jsx similarity index 100% rename from Client/src/js/views/SeniorityList.jsx rename to client/src/js/views/SeniorityList.jsx diff --git a/Client/src/js/views/StatusLetters.jsx b/client/src/js/views/StatusLetters.jsx similarity index 100% rename from Client/src/js/views/StatusLetters.jsx rename to client/src/js/views/StatusLetters.jsx diff --git a/Client/src/js/views/TimeEntry.jsx b/client/src/js/views/TimeEntry.jsx similarity index 100% rename from Client/src/js/views/TimeEntry.jsx rename to client/src/js/views/TimeEntry.jsx diff --git a/Client/src/js/views/TopNav.jsx b/client/src/js/views/TopNav.jsx similarity index 100% rename from Client/src/js/views/TopNav.jsx rename to client/src/js/views/TopNav.jsx diff --git a/Client/src/js/views/Users.jsx b/client/src/js/views/Users.jsx similarity index 100% rename from Client/src/js/views/Users.jsx rename to client/src/js/views/Users.jsx diff --git a/Client/src/js/views/UsersDetail.jsx b/client/src/js/views/UsersDetail.jsx similarity index 100% rename from Client/src/js/views/UsersDetail.jsx rename to client/src/js/views/UsersDetail.jsx diff --git a/Client/src/js/views/Version.jsx b/client/src/js/views/Version.jsx similarity index 100% rename from Client/src/js/views/Version.jsx rename to client/src/js/views/Version.jsx diff --git a/Client/src/js/views/WcbCglCoverage.jsx b/client/src/js/views/WcbCglCoverage.jsx similarity index 100% rename from Client/src/js/views/WcbCglCoverage.jsx rename to client/src/js/views/WcbCglCoverage.jsx diff --git a/Client/src/js/views/dialogs/AttachmentAddDialog.jsx b/client/src/js/views/dialogs/AttachmentAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/AttachmentAddDialog.jsx rename to client/src/js/views/dialogs/AttachmentAddDialog.jsx diff --git a/Client/src/js/views/dialogs/AttachmentEditDialog.jsx b/client/src/js/views/dialogs/AttachmentEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/AttachmentEditDialog.jsx rename to client/src/js/views/dialogs/AttachmentEditDialog.jsx diff --git a/Client/src/js/views/dialogs/CloneDialog.jsx b/client/src/js/views/dialogs/CloneDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/CloneDialog.jsx rename to client/src/js/views/dialogs/CloneDialog.jsx diff --git a/Client/src/js/views/dialogs/ConditionAddEditDialog.jsx b/client/src/js/views/dialogs/ConditionAddEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ConditionAddEditDialog.jsx rename to client/src/js/views/dialogs/ConditionAddEditDialog.jsx diff --git a/Client/src/js/views/dialogs/ConfirmDialog.jsx b/client/src/js/views/dialogs/ConfirmDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ConfirmDialog.jsx rename to client/src/js/views/dialogs/ConfirmDialog.jsx diff --git a/Client/src/js/views/dialogs/ConfirmForceHireDialog.jsx b/client/src/js/views/dialogs/ConfirmForceHireDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ConfirmForceHireDialog.jsx rename to client/src/js/views/dialogs/ConfirmForceHireDialog.jsx diff --git a/Client/src/js/views/dialogs/ContactsEditDialog.jsx b/client/src/js/views/dialogs/ContactsEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ContactsEditDialog.jsx rename to client/src/js/views/dialogs/ContactsEditDialog.jsx diff --git a/Client/src/js/views/dialogs/DistrictEditDialog.jsx b/client/src/js/views/dialogs/DistrictEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/DistrictEditDialog.jsx rename to client/src/js/views/dialogs/DistrictEditDialog.jsx diff --git a/Client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx b/client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx rename to client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx diff --git a/Client/src/js/views/dialogs/DocumentsListDialog.jsx b/client/src/js/views/dialogs/DocumentsListDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/DocumentsListDialog.jsx rename to client/src/js/views/dialogs/DocumentsListDialog.jsx diff --git a/Client/src/js/views/dialogs/EquipmentAddDialog.jsx b/client/src/js/views/dialogs/EquipmentAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/EquipmentAddDialog.jsx rename to client/src/js/views/dialogs/EquipmentAddDialog.jsx diff --git a/Client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx b/client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx rename to client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx diff --git a/Client/src/js/views/dialogs/EquipmentEditDialog.jsx b/client/src/js/views/dialogs/EquipmentEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/EquipmentEditDialog.jsx rename to client/src/js/views/dialogs/EquipmentEditDialog.jsx diff --git a/Client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx b/client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx rename to client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx diff --git a/Client/src/js/views/dialogs/EquipmentTransferDialog.jsx b/client/src/js/views/dialogs/EquipmentTransferDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/EquipmentTransferDialog.jsx rename to client/src/js/views/dialogs/EquipmentTransferDialog.jsx diff --git a/Client/src/js/views/dialogs/ErrorDialog.jsx b/client/src/js/views/dialogs/ErrorDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ErrorDialog.jsx rename to client/src/js/views/dialogs/ErrorDialog.jsx diff --git a/Client/src/js/views/dialogs/HireOfferEditDialog.jsx b/client/src/js/views/dialogs/HireOfferEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/HireOfferEditDialog.jsx rename to client/src/js/views/dialogs/HireOfferEditDialog.jsx diff --git a/Client/src/js/views/dialogs/NotesAddDialog.jsx b/client/src/js/views/dialogs/NotesAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/NotesAddDialog.jsx rename to client/src/js/views/dialogs/NotesAddDialog.jsx diff --git a/Client/src/js/views/dialogs/NotesDialog.jsx b/client/src/js/views/dialogs/NotesDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/NotesDialog.jsx rename to client/src/js/views/dialogs/NotesDialog.jsx diff --git a/Client/src/js/views/dialogs/OvertimeRateEditDialog.jsx b/client/src/js/views/dialogs/OvertimeRateEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/OvertimeRateEditDialog.jsx rename to client/src/js/views/dialogs/OvertimeRateEditDialog.jsx diff --git a/Client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx b/client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx rename to client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx diff --git a/Client/src/js/views/dialogs/OwnersAddDialog.jsx b/client/src/js/views/dialogs/OwnersAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/OwnersAddDialog.jsx rename to client/src/js/views/dialogs/OwnersAddDialog.jsx diff --git a/Client/src/js/views/dialogs/OwnersEditDialog.jsx b/client/src/js/views/dialogs/OwnersEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/OwnersEditDialog.jsx rename to client/src/js/views/dialogs/OwnersEditDialog.jsx diff --git a/Client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx b/client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx rename to client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx diff --git a/Client/src/js/views/dialogs/ProjectsAddDialog.jsx b/client/src/js/views/dialogs/ProjectsAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ProjectsAddDialog.jsx rename to client/src/js/views/dialogs/ProjectsAddDialog.jsx diff --git a/Client/src/js/views/dialogs/ProjectsEditDialog.jsx b/client/src/js/views/dialogs/ProjectsEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/ProjectsEditDialog.jsx rename to client/src/js/views/dialogs/ProjectsEditDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx b/client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx rename to client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx b/client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx rename to client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalConditionsEditDialog.jsx b/client/src/js/views/dialogs/RentalConditionsEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalConditionsEditDialog.jsx rename to client/src/js/views/dialogs/RentalConditionsEditDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalRatesEditDialog.jsx b/client/src/js/views/dialogs/RentalRatesEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalRatesEditDialog.jsx rename to client/src/js/views/dialogs/RentalRatesEditDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalRequestsAddDialog.jsx b/client/src/js/views/dialogs/RentalRequestsAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalRequestsAddDialog.jsx rename to client/src/js/views/dialogs/RentalRequestsAddDialog.jsx diff --git a/Client/src/js/views/dialogs/RentalRequestsEditDialog.jsx b/client/src/js/views/dialogs/RentalRequestsEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/RentalRequestsEditDialog.jsx rename to client/src/js/views/dialogs/RentalRequestsEditDialog.jsx diff --git a/Client/src/js/views/dialogs/SeniorityEditDialog.jsx b/client/src/js/views/dialogs/SeniorityEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/SeniorityEditDialog.jsx rename to client/src/js/views/dialogs/SeniorityEditDialog.jsx diff --git a/Client/src/js/views/dialogs/TimeEntryDialog.jsx b/client/src/js/views/dialogs/TimeEntryDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/TimeEntryDialog.jsx rename to client/src/js/views/dialogs/TimeEntryDialog.jsx diff --git a/Client/src/js/views/dialogs/UserRoleAddDialog.jsx b/client/src/js/views/dialogs/UserRoleAddDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/UserRoleAddDialog.jsx rename to client/src/js/views/dialogs/UserRoleAddDialog.jsx diff --git a/Client/src/js/views/dialogs/UsersEditDialog.jsx b/client/src/js/views/dialogs/UsersEditDialog.jsx similarity index 100% rename from Client/src/js/views/dialogs/UsersEditDialog.jsx rename to client/src/js/views/dialogs/UsersEditDialog.jsx diff --git a/Client/src/robots.txt b/client/src/robots.txt similarity index 100% rename from Client/src/robots.txt rename to client/src/robots.txt diff --git a/Client/src/sass/components/all.scss b/client/src/sass/components/all.scss similarity index 100% rename from Client/src/sass/components/all.scss rename to client/src/sass/components/all.scss diff --git a/Client/src/sass/components/badge-label.scss b/client/src/sass/components/badge-label.scss similarity index 100% rename from Client/src/sass/components/badge-label.scss rename to client/src/sass/components/badge-label.scss diff --git a/Client/src/sass/components/clone-dialog.scss b/client/src/sass/components/clone-dialog.scss similarity index 100% rename from Client/src/sass/components/clone-dialog.scss rename to client/src/sass/components/clone-dialog.scss diff --git a/Client/src/sass/components/date-control.scss b/client/src/sass/components/date-control.scss similarity index 100% rename from Client/src/sass/components/date-control.scss rename to client/src/sass/components/date-control.scss diff --git a/Client/src/sass/components/dropdown-control.scss b/client/src/sass/components/dropdown-control.scss similarity index 100% rename from Client/src/sass/components/dropdown-control.scss rename to client/src/sass/components/dropdown-control.scss diff --git a/Client/src/sass/components/favourites.scss b/client/src/sass/components/favourites.scss similarity index 100% rename from Client/src/sass/components/favourites.scss rename to client/src/sass/components/favourites.scss diff --git a/Client/src/sass/components/file-upload.scss b/client/src/sass/components/file-upload.scss similarity index 100% rename from Client/src/sass/components/file-upload.scss rename to client/src/sass/components/file-upload.scss diff --git a/Client/src/sass/components/filter-dropdown.scss b/client/src/sass/components/filter-dropdown.scss similarity index 100% rename from Client/src/sass/components/filter-dropdown.scss rename to client/src/sass/components/filter-dropdown.scss diff --git a/Client/src/sass/components/form-dialog.scss b/client/src/sass/components/form-dialog.scss similarity index 100% rename from Client/src/sass/components/form-dialog.scss rename to client/src/sass/components/form-dialog.scss diff --git a/Client/src/sass/components/form-input-control.scss b/client/src/sass/components/form-input-control.scss similarity index 100% rename from Client/src/sass/components/form-input-control.scss rename to client/src/sass/components/form-input-control.scss diff --git a/Client/src/sass/components/history.scss b/client/src/sass/components/history.scss similarity index 100% rename from Client/src/sass/components/history.scss rename to client/src/sass/components/history.scss diff --git a/Client/src/sass/components/link-control.scss b/client/src/sass/components/link-control.scss similarity index 100% rename from Client/src/sass/components/link-control.scss rename to client/src/sass/components/link-control.scss diff --git a/Client/src/sass/components/multi-dropdown.scss b/client/src/sass/components/multi-dropdown.scss similarity index 100% rename from Client/src/sass/components/multi-dropdown.scss rename to client/src/sass/components/multi-dropdown.scss diff --git a/Client/src/sass/components/print-button.scss b/client/src/sass/components/print-button.scss similarity index 100% rename from Client/src/sass/components/print-button.scss rename to client/src/sass/components/print-button.scss diff --git a/Client/src/sass/components/return-button.scss b/client/src/sass/components/return-button.scss similarity index 100% rename from Client/src/sass/components/return-button.scss rename to client/src/sass/components/return-button.scss diff --git a/Client/src/sass/components/search-control.scss b/client/src/sass/components/search-control.scss similarity index 100% rename from Client/src/sass/components/search-control.scss rename to client/src/sass/components/search-control.scss diff --git a/Client/src/sass/components/sort-table.scss b/client/src/sass/components/sort-table.scss similarity index 100% rename from Client/src/sass/components/sort-table.scss rename to client/src/sass/components/sort-table.scss diff --git a/Client/src/sass/components/ui/add-button-container.scss b/client/src/sass/components/ui/add-button-container.scss similarity index 100% rename from Client/src/sass/components/ui/add-button-container.scss rename to client/src/sass/components/ui/add-button-container.scss diff --git a/Client/src/sass/components/ui/page-header.scss b/client/src/sass/components/ui/page-header.scss similarity index 100% rename from Client/src/sass/components/ui/page-header.scss rename to client/src/sass/components/ui/page-header.scss diff --git a/Client/src/sass/components/ui/search-bar.scss b/client/src/sass/components/ui/search-bar.scss similarity index 100% rename from Client/src/sass/components/ui/search-bar.scss rename to client/src/sass/components/ui/search-bar.scss diff --git a/Client/src/sass/components/ui/subheader.scss b/client/src/sass/components/ui/subheader.scss similarity index 100% rename from Client/src/sass/components/ui/subheader.scss rename to client/src/sass/components/ui/subheader.scss diff --git a/Client/src/sass/gov3.scss b/client/src/sass/gov3.scss similarity index 100% rename from Client/src/sass/gov3.scss rename to client/src/sass/gov3.scss diff --git a/Client/src/sass/header.scss b/client/src/sass/header.scss similarity index 100% rename from Client/src/sass/header.scss rename to client/src/sass/header.scss diff --git a/Client/src/sass/init.scss b/client/src/sass/init.scss similarity index 100% rename from Client/src/sass/init.scss rename to client/src/sass/init.scss diff --git a/Client/src/sass/main.scss b/client/src/sass/main.scss similarity index 100% rename from Client/src/sass/main.scss rename to client/src/sass/main.scss diff --git a/Client/src/sass/mixins.scss b/client/src/sass/mixins.scss similarity index 100% rename from Client/src/sass/mixins.scss rename to client/src/sass/mixins.scss diff --git a/Client/src/sass/print.scss b/client/src/sass/print.scss similarity index 100% rename from Client/src/sass/print.scss rename to client/src/sass/print.scss diff --git a/Client/src/sass/variables.scss b/client/src/sass/variables.scss similarity index 100% rename from Client/src/sass/variables.scss rename to client/src/sass/variables.scss diff --git a/Client/src/sass/views/all.scss b/client/src/sass/views/all.scss similarity index 100% rename from Client/src/sass/views/all.scss rename to client/src/sass/views/all.scss diff --git a/Client/src/sass/views/business-portal.scss b/client/src/sass/views/business-portal.scss similarity index 100% rename from Client/src/sass/views/business-portal.scss rename to client/src/sass/views/business-portal.scss diff --git a/Client/src/sass/views/dialogs/all.scss b/client/src/sass/views/dialogs/all.scss similarity index 100% rename from Client/src/sass/views/dialogs/all.scss rename to client/src/sass/views/dialogs/all.scss diff --git a/Client/src/sass/views/dialogs/contacts-edit.scss b/client/src/sass/views/dialogs/contacts-edit.scss similarity index 100% rename from Client/src/sass/views/dialogs/contacts-edit.scss rename to client/src/sass/views/dialogs/contacts-edit.scss diff --git a/Client/src/sass/views/dialogs/documents-list.scss b/client/src/sass/views/dialogs/documents-list.scss similarity index 100% rename from Client/src/sass/views/dialogs/documents-list.scss rename to client/src/sass/views/dialogs/documents-list.scss diff --git a/Client/src/sass/views/dialogs/equipment-transfer.scss b/client/src/sass/views/dialogs/equipment-transfer.scss similarity index 100% rename from Client/src/sass/views/dialogs/equipment-transfer.scss rename to client/src/sass/views/dialogs/equipment-transfer.scss diff --git a/Client/src/sass/views/dialogs/error-dialog.scss b/client/src/sass/views/dialogs/error-dialog.scss similarity index 100% rename from Client/src/sass/views/dialogs/error-dialog.scss rename to client/src/sass/views/dialogs/error-dialog.scss diff --git a/Client/src/sass/views/dialogs/notes.scss b/client/src/sass/views/dialogs/notes.scss similarity index 100% rename from Client/src/sass/views/dialogs/notes.scss rename to client/src/sass/views/dialogs/notes.scss diff --git a/Client/src/sass/views/dialogs/rental-rates-edit.scss b/client/src/sass/views/dialogs/rental-rates-edit.scss similarity index 100% rename from Client/src/sass/views/dialogs/rental-rates-edit.scss rename to client/src/sass/views/dialogs/rental-rates-edit.scss diff --git a/Client/src/sass/views/district-admin.scss b/client/src/sass/views/district-admin.scss similarity index 100% rename from Client/src/sass/views/district-admin.scss rename to client/src/sass/views/district-admin.scss diff --git a/Client/src/sass/views/equipment-list.scss b/client/src/sass/views/equipment-list.scss similarity index 100% rename from Client/src/sass/views/equipment-list.scss rename to client/src/sass/views/equipment-list.scss diff --git a/Client/src/sass/views/home.scss b/client/src/sass/views/home.scss similarity index 100% rename from Client/src/sass/views/home.scss rename to client/src/sass/views/home.scss diff --git a/Client/src/sass/views/owners.scss b/client/src/sass/views/owners.scss similarity index 100% rename from Client/src/sass/views/owners.scss rename to client/src/sass/views/owners.scss diff --git a/Client/src/sass/views/projects.scss b/client/src/sass/views/projects.scss similarity index 100% rename from Client/src/sass/views/projects.scss rename to client/src/sass/views/projects.scss diff --git a/Client/src/sass/views/rental-agreements.scss b/client/src/sass/views/rental-agreements.scss similarity index 100% rename from Client/src/sass/views/rental-agreements.scss rename to client/src/sass/views/rental-agreements.scss diff --git a/Client/src/sass/views/rental-requests.scss b/client/src/sass/views/rental-requests.scss similarity index 100% rename from Client/src/sass/views/rental-requests.scss rename to client/src/sass/views/rental-requests.scss diff --git a/Client/src/sass/views/roles.scss b/client/src/sass/views/roles.scss similarity index 100% rename from Client/src/sass/views/roles.scss rename to client/src/sass/views/roles.scss diff --git a/Client/src/sass/views/rollover.scss b/client/src/sass/views/rollover.scss similarity index 100% rename from Client/src/sass/views/rollover.scss rename to client/src/sass/views/rollover.scss diff --git a/Client/src/sass/views/users.scss b/client/src/sass/views/users.scss similarity index 100% rename from Client/src/sass/views/users.scss rename to client/src/sass/views/users.scss diff --git a/Client/test/index.html b/client/test/index.html similarity index 100% rename from Client/test/index.html rename to client/test/index.html diff --git a/Client/test/spec/load.js b/client/test/spec/load.js similarity index 100% rename from Client/test/spec/load.js rename to client/test/spec/load.js diff --git a/Client/typings/node/node.d.ts b/client/typings/node/node.d.ts similarity index 100% rename from Client/typings/node/node.d.ts rename to client/typings/node/node.d.ts diff --git a/Client/webpack.config.js b/client/webpack.config.js similarity index 100% rename from Client/webpack.config.js rename to client/webpack.config.js From f18b65600ff475690ba9d1c87045195c87ac179f Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Fri, 28 May 2021 15:18:14 -0700 Subject: [PATCH 002/352] Client to client --- README.md | 4 +-- client/Dockerfile | 4 +-- client/README.md | 39 +++++++++++++++--------------- openshift/client-build-config.yaml | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 6847cf4e0..44dbef6ae 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The application is being developed as an open source solution. ## Repository Map -- **Client**: The javascript source for the user interface +- **client**: The javascript source for the user interface - **Common**: A library of common methods used by various components - **FrontEnd**: The Front End server that hosts static content and proxies the API - **Server**: The API Server @@ -44,7 +44,7 @@ Refer to [this document](openshift/README.md) for OpenShift Deployment and Pipel **Client Code** The client code is tested using a Node.js application. Node.js is also used to build the client code into the deployable JavaScript application. -Run npm install from the Client directory to configure the Client build environment +Run npm install from the client directory to configure the client build environment The frameworks used for this application are React/Redux. diff --git a/client/Dockerfile b/client/Dockerfile index 64070741f..53d80e45a 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -3,12 +3,12 @@ LABEL maintainer="young-jin.chung@gov.bc.ca" COPY . /src -RUN cd /src/Client && npm ci && \ +RUN cd /src/client && npm ci && \ ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/dotnet-21-rhel7:2.1-41 -COPY --from=builder /src/Client/dist /opt/app-root/dist +COPY --from=builder /src/client/dist /opt/app-root/dist COPY --from=builder /src/FrontEnd /opt/app-root/src/FrontEnd diff --git a/client/README.md b/client/README.md index 232ccb540..50bac758f 100644 --- a/client/README.md +++ b/client/README.md @@ -1,7 +1,7 @@ # Hired Equipment Tracking System Web Application The Hired Equipment Tracking System (a.k.a. HETS) is a web application to track and hire equipment -in British Columbia. The Client/ directory is the home of of the front-end source code. +in British Columbia. The client/ directory is the home of of the front-end source code. ## Getting Started @@ -18,24 +18,25 @@ The following software requirements are required: ### Installing 1. Git clone the [repository](https://github.com/bcgov/hets) onto your local machine. - ``` - git clone git@github.com:bcgov/hets.git - ``` -2. Install the Node module dependencies. You will need to be in the hets/Client/ directory. + ``` + git clone git@github.com:bcgov/hets.git + ``` - ``` - npm install - ``` +2. Install the Node module dependencies. You will need to be in the hets/client/ directory. - **Note**: The installation of [node-sass](https://www.npmjs.com/package/node-sass) might fail - depending on the target platform because of a missing C compiler. + ``` + npm install + ``` + + **Note**: The installation of [node-sass](https://www.npmjs.com/package/node-sass) might fail + depending on the target platform because of a missing C compiler. 3. Run the local dev server - ``` - npm start - ``` + ``` + npm start + ``` Now you will be able to access the web app when you go to [http:://localhost:4375](http:://localhost:4375) @@ -50,12 +51,12 @@ to run the API server. Look for documentation in the database. [Redux](https://redux.js.org/) is used to store most of the application’s state. The application’s -[store.js](https://github.com/bcgov/hets/tree/master/Client/src/js/store.js) contains the response +[store.js](https://github.com/bcgov/hets/tree/master/client/src/js/store.js) contains the response data from any API request to be used by the React components as well as UI data. [React Router v3](https://github.com/ReactTraining/react-router/tree/v3/docs) is used to control the browser’s URL history and routing. Routes are defined in -[app.jsx](https://github.com/bcgov/hets/tree/master/Client/src/js/app.jsx) file. If a user is a +[app.jsx](https://github.com/bcgov/hets/tree/master/client/src/js/app.jsx) file. If a user is a business owner they can only access the routes at the path `/business`. All other users can access the rest of the application’s routes. @@ -71,14 +72,14 @@ The web application uses [Webpack](https://webpack.js.org/)’s the UI whenever a [React Component](https://reactjs.org/docs/react-component.html) is saved on disk. [Gulp](https://gulpjs.com/) is the tool used for the front-end build system. Inside the -[gulpfile.js](https://github.com/bcgov/hets/tree/master/Client/gulpfile.js) are defined a series of +[gulpfile.js](https://github.com/bcgov/hets/tree/master/client/gulpfile.js) are defined a series of tasks that can be run to build the project. The common ones are: 1. `gulp` — starts a local Node webserver which will watch and re-build JS, SASS, and copy static files into `dist/` 2. `gulp --production` — builds a production optimized version of the application into `dist/` 3. `gulp clean` — deletes all the files in the `dist/` directory. -3. `gulp test` — runs unit and integration tests. +4. `gulp test` — runs unit and integration tests. ### Running tests @@ -98,8 +99,8 @@ in OpenShift. ## Built With -* [React](https://reactjs.org/) - JS library for building UIs -* [React Bootstrap](https://react-bootstrap.github.io/) - UI components and styles +- [React](https://reactjs.org/) - JS library for building UIs +- [React Bootstrap](https://react-bootstrap.github.io/) - UI components and styles ## License diff --git a/openshift/client-build-config.yaml b/openshift/client-build-config.yaml index 063b26aae..95beb44c5 100644 --- a/openshift/client-build-config.yaml +++ b/openshift/client-build-config.yaml @@ -118,7 +118,7 @@ parameters: displayName: Docker File Path description: The path to the docker file defining the build. required: false - value: "Client/Dockerfile" + value: "client/Dockerfile" - name: DOTNET_STARTUP_PROJECT displayName: DotNet Startup Project description: The path to the startup project for the .Net application. From e288133a4fb997c5cf731db58901cd67515d90e1 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 09:25:26 -0700 Subject: [PATCH 003/352] kestrel to nginx --- .pipeline/lib/deploy.js | 1 - client/Dockerfile | 8 +-- client/nginx-start/start.sh | 13 ++++ client/nginx.conf.tmpl | 99 +++++++++++++++++++++++++++++ openshift/client-build-config.yaml | 43 +++---------- openshift/client-deploy-config.yaml | 21 +----- 6 files changed, 128 insertions(+), 57 deletions(-) create mode 100644 client/nginx-start/start.sh create mode 100644 client/nginx.conf.tmpl diff --git a/.pipeline/lib/deploy.js b/.pipeline/lib/deploy.js index 5a5e2bf11..45cb1a4e9 100644 --- a/.pipeline/lib/deploy.js +++ b/.pipeline/lib/deploy.js @@ -109,7 +109,6 @@ module.exports = (settings) => { VERSION: phases[phase].tag, ENV: phases[phase].phase, HOST: phases[phase].host, - ASPNETCORE_ENVIRONMENT: phases[phase].dotnet_env, CPU: phases[phase].client_cpu, MEMORY: phases[phase].client_memory, }, diff --git a/client/Dockerfile b/client/Dockerfile index 53d80e45a..c9bbdb394 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -6,11 +6,11 @@ COPY . /src RUN cd /src/client && npm ci && \ ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT -FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/dotnet-21-rhel7:2.1-41 +FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/nginx-116-rhel8:1 -COPY --from=builder /src/client/dist /opt/app-root/dist - -COPY --from=builder /src/FrontEnd /opt/app-root/src/FrontEnd +COPY --from=builder /src/client/dist/. /tmp/src +COPY --from=builder /src/nginx-start/. /tmp/src/nginx-start +COPY --from=builder /src/nginx.conf.tmpl /tmp/src/nginx.conf.tmpl RUN $STI_SCRIPTS_PATH/assemble diff --git a/client/nginx-start/start.sh b/client/nginx-start/start.sh new file mode 100644 index 000000000..0afa627a3 --- /dev/null +++ b/client/nginx-start/start.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +#echo "---> Setting window.RUNTIME_REACT_APP values ..." +#JS_PATH=~/js/env.config.js + +#echo "window.RUNTIME_REACT_APP_SSO_HOST='${REACT_APP_SSO_HOST}';" > $JS_PATH +#echo "window.RUNTIME_REACT_APP_SSO_REALM='${REACT_APP_SSO_REALM}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_SSO_CLIENT='${REACT_APP_SSO_CLIENT}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_API_HOST='${REACT_APP_API_HOST}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_DWPBI_URL='${REACT_APP_DWPBI_URL}';" >> $JS_PATH + +echo "---> Creating nginx.conf ..." +envsubst '${HETS_DEPLOY_SUFFIX}' < /tmp/src/nginx.conf.tmpl > /etc/nginx/nginx.conf \ No newline at end of file diff --git a/client/nginx.conf.tmpl b/client/nginx.conf.tmpl new file mode 100644 index 000000000..676c50fb8 --- /dev/null +++ b/client/nginx.conf.tmpl @@ -0,0 +1,99 @@ +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + + +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + gzip on; + gzip_disable "msie6"; + + gzip_comp_level 6; + gzip_min_length 1100; + gzip_buffers 16 8k; + gzip_proxied any; + gzip_types + text/plain + text/css + text/js + text/xml + text/csv + text/javascript + application/javascript + application/json + application/xml + application/vnd.google-earth.kml+xml + "application/gml+xml; version=3.2" + application/rss+xml + image/svg+xml; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /opt/app-root/etc/nginx.d/*.conf; + + server { + listen 8080 default_server; + listen [::]:8080 default_server; + server_name _; + + add_header Last-Modified $date_gmt; + add_header Cache-Control "private, no-store, no-cache, must-revalidate"; + + client_max_body_size 5M; + + location /api/ { + proxy_connect_timeout 1800; + proxy_send_timeout 1800; + proxy_read_timeout 1800; + send_timeout 1800; + + proxy_set_header HOST $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + + # proxy_hide_header WWW-Authenticate; + + proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; + } + + location /swagger/ { + proxy_set_header HOST $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080/swagger/; + } + + location / { + root /opt/app-root/src; + index index.html index.htm; + + try_files $uri /index.html =404; + } + } +} \ No newline at end of file diff --git a/openshift/client-build-config.yaml b/openshift/client-build-config.yaml index 95beb44c5..01702d5bc 100644 --- a/openshift/client-build-config.yaml +++ b/openshift/client-build-config.yaml @@ -9,7 +9,7 @@ objects: - apiVersion: "v1" kind: ImageStream metadata: - name: node + name: nginx-116-rhel8 spec: lookupPolicy: local: false @@ -17,27 +17,10 @@ objects: - annotations: null from: kind: DockerImage - name: docker.io/node:13.7-alpine3.11 + name: registry.redhat.io/rhel8/nginx-116:1-39 name: "1" referencePolicy: type: Local - - apiVersion: v1 - kind: ImageStream - metadata: - name: dotnet-21-rhel7 - labels: - shared: "true" - spec: - lookupPolicy: - local: false - tags: - - annotations: null - from: - kind: DockerImage - name: registry.redhat.io/dotnet/dotnet-21-rhel7:2.1-41 - name: "2.1-41" - referencePolicy: - type: Local - apiVersion: v1 kind: ImageStream metadata: @@ -75,16 +58,13 @@ objects: uri: ${SOURCE_REPOSITORY_URL} ref: ${SOURCE_REPOSITORY_REF} type: Git + contextDir: client strategy: - type: Docker dockerStrategy: noCache: true - env: - - name: DOTNET_STARTUP_PROJECT - value: "${DOTNET_STARTUP_PROJECT}" - dockerfilePath: "${DOCKER_FILE_PATH}" + type: Docker parameters: - - description: Name of the project (SCHOOLBUS) + - description: Name of the project (HETS) displayName: PROJECT_NAME name: PROJECT_NAME required: true @@ -114,13 +94,8 @@ parameters: name: SOURCE_REPOSITORY_REF required: false value: "master" - - name: DOCKER_FILE_PATH - displayName: Docker File Path - description: The path to the docker file defining the build. - required: false - value: "client/Dockerfile" - - name: DOTNET_STARTUP_PROJECT - displayName: DotNet Startup Project - description: The path to the startup project for the .Net application. + - description: DEPLOY_SUBDIRECTORY + displayName: DEPLOY_SUBDIRECTORY + name: DEPLOY_SUBDIRECTORY required: true - value: "FrontEnd/FrontEnd/FrontEnd.csproj" \ No newline at end of file + value: "/" \ No newline at end of file diff --git a/openshift/client-deploy-config.yaml b/openshift/client-deploy-config.yaml index abbf934c1..42733b984 100644 --- a/openshift/client-deploy-config.yaml +++ b/openshift/client-deploy-config.yaml @@ -24,15 +24,7 @@ objects: replicas: 1 selector: deploymentconfig: ${NAME}${SUFFIX} - strategy: - activeDeadlineSeconds: 21600 - rollingParams: - intervalSeconds: 1 - maxSurge: 1 - maxUnavailable: 1 - timeoutSeconds: 600 - updatePeriodSeconds: 1 - type: Rolling + strategy: {} template: metadata: labels: @@ -52,10 +44,8 @@ objects: cpu: ${CPU} memory: ${MEMORY} env: - - name: API_SERVER - value: "${PROJECT_NAME}-api${SUFFIX}:8080" - - name: ASPNETCORE_ENVIRONMENT - value: "${ASPNETCORE_ENVIRONMENT}" + - name: HETS_DEPLOY_SUFFIX + value: ${SUFFIX} test: false triggers: - imageChangeParams: @@ -130,11 +120,6 @@ parameters: name: HOST required: true value: "" - - name: ASPNETCORE_ENVIRONMENT - displayName: AspNetCore Environment - description: The ASP Net Core deployment environment setting. - required: true - value: Development - description: CPU displayName: CPU Request name: CPU From 8bfd132b31b9cc5329717f7f49353c1cf87153b4 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 09:41:58 -0700 Subject: [PATCH 004/352] fix client dockerfile --- client/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/Dockerfile b/client/Dockerfile index c9bbdb394..6f445285b 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -3,12 +3,12 @@ LABEL maintainer="young-jin.chung@gov.bc.ca" COPY . /src -RUN cd /src/client && npm ci && \ +RUN cd /src && npm ci && \ ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/nginx-116-rhel8:1 -COPY --from=builder /src/client/dist/. /tmp/src +COPY --from=builder /src/dist/. /tmp/src COPY --from=builder /src/nginx-start/. /tmp/src/nginx-start COPY --from=builder /src/nginx.conf.tmpl /tmp/src/nginx.conf.tmpl From af9dc45a3168a75a724762f3b664ede2a3aad52f Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 11:28:32 -0700 Subject: [PATCH 005/352] proxy_pass_request_headers --- client/nginx.conf.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/client/nginx.conf.tmpl b/client/nginx.conf.tmpl index 676c50fb8..a2cde8213 100644 --- a/client/nginx.conf.tmpl +++ b/client/nginx.conf.tmpl @@ -78,6 +78,7 @@ http { proxy_set_header X-Real-IP $remote_addr; # proxy_hide_header WWW-Authenticate; + proxy_pass_request_headers on; proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; } From 8c93884942e70bccd734880b46dc2d815ccf454e Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 11:36:26 -0700 Subject: [PATCH 006/352] Nginx - underscores_in_headers on --- client/nginx.conf.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/nginx.conf.tmpl b/client/nginx.conf.tmpl index a2cde8213..aa4c6fc7f 100644 --- a/client/nginx.conf.tmpl +++ b/client/nginx.conf.tmpl @@ -78,7 +78,7 @@ http { proxy_set_header X-Real-IP $remote_addr; # proxy_hide_header WWW-Authenticate; - proxy_pass_request_headers on; + underscores_in_headers on; proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; } From c6ea4b051a55750c81305f91f6b2afde724dc908 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 11:47:44 -0700 Subject: [PATCH 007/352] nginx underscores_in_headers --- client/nginx.conf.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/nginx.conf.tmpl b/client/nginx.conf.tmpl index aa4c6fc7f..f6849c97d 100644 --- a/client/nginx.conf.tmpl +++ b/client/nginx.conf.tmpl @@ -62,6 +62,7 @@ http { listen [::]:8080 default_server; server_name _; + underscores_in_headers on; add_header Last-Modified $date_gmt; add_header Cache-Control "private, no-store, no-cache, must-revalidate"; @@ -78,7 +79,6 @@ http { proxy_set_header X-Real-IP $remote_addr; # proxy_hide_header WWW-Authenticate; - underscores_in_headers on; proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; } From 655b20f8b41d86313afdfa0089eee2f250eb093e Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 12:48:40 -0700 Subject: [PATCH 008/352] removed FrontEnd --- FrontEnd/.gitignore | 278 ------------------ FrontEnd/FrontEnd.sln | 27 -- FrontEnd/FrontEnd/.gitignore | 278 ------------------ FrontEnd/FrontEnd/ApiProxyServerOptions.cs | 33 --- .../ApiProxyServerOptionsExtensions.cs | 41 --- FrontEnd/FrontEnd/FrontEnd.csproj | 60 ---- .../FrontEnd/Handlers/ApiProxyExtension.cs | 30 -- .../FrontEnd/Handlers/ApiProxyMiddleware.cs | 75 ----- FrontEnd/FrontEnd/Program.cs | 31 -- FrontEnd/FrontEnd/Startup.cs | 135 --------- FrontEnd/FrontEnd/appsettings.json | 20 -- FrontEnd/FrontEnd/web.config | 11 - 12 files changed, 1019 deletions(-) delete mode 100644 FrontEnd/.gitignore delete mode 100644 FrontEnd/FrontEnd.sln delete mode 100644 FrontEnd/FrontEnd/.gitignore delete mode 100644 FrontEnd/FrontEnd/ApiProxyServerOptions.cs delete mode 100644 FrontEnd/FrontEnd/ApiProxyServerOptionsExtensions.cs delete mode 100644 FrontEnd/FrontEnd/FrontEnd.csproj delete mode 100644 FrontEnd/FrontEnd/Handlers/ApiProxyExtension.cs delete mode 100644 FrontEnd/FrontEnd/Handlers/ApiProxyMiddleware.cs delete mode 100644 FrontEnd/FrontEnd/Program.cs delete mode 100644 FrontEnd/FrontEnd/Startup.cs delete mode 100644 FrontEnd/FrontEnd/appsettings.json delete mode 100644 FrontEnd/FrontEnd/web.config diff --git a/FrontEnd/.gitignore b/FrontEnd/.gitignore deleted file mode 100644 index 3417240e4..000000000 --- a/FrontEnd/.gitignore +++ /dev/null @@ -1,278 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates -*.vcxproj.filters - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ -#**/Properties/launchSettings.json - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/ - -*.DotSettings -*.DotSettings.user \ No newline at end of file diff --git a/FrontEnd/FrontEnd.sln b/FrontEnd/FrontEnd.sln deleted file mode 100644 index 548ca0c0c..000000000 --- a/FrontEnd/FrontEnd.sln +++ /dev/null @@ -1,27 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30804.86 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrontEnd", "FrontEnd\FrontEnd.csproj", "{292B510E-6283-4616-AD2A-D8A994FD4285}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {292B510E-6283-4616-AD2A-D8A994FD4285}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {292B510E-6283-4616-AD2A-D8A994FD4285}.Debug|Any CPU.Build.0 = Debug|Any CPU - {292B510E-6283-4616-AD2A-D8A994FD4285}.Release|Any CPU.ActiveCfg = Release|Any CPU - {292B510E-6283-4616-AD2A-D8A994FD4285}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {292B510E-6283-4616-AD2A-D8A994FD4285} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {8C753C67-A00C-4FEE-AF81-6F9F4828A94A} - EndGlobalSection -EndGlobal diff --git a/FrontEnd/FrontEnd/.gitignore b/FrontEnd/FrontEnd/.gitignore deleted file mode 100644 index 33744e26a..000000000 --- a/FrontEnd/FrontEnd/.gitignore +++ /dev/null @@ -1,278 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates -*.vcxproj.filters - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ -**/Properties/launchSettings.json - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/ - -*.DotSettings -*.DotSettings.user \ No newline at end of file diff --git a/FrontEnd/FrontEnd/ApiProxyServerOptions.cs b/FrontEnd/FrontEnd/ApiProxyServerOptions.cs deleted file mode 100644 index 867df6ac5..000000000 --- a/FrontEnd/FrontEnd/ApiProxyServerOptions.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace FrontEnd -{ - /// - /// Proxy Server Options - /// - public class ApiProxyServerOptions - { - /// - /// Proxy Server Options Constructor - /// - public ApiProxyServerOptions() - { - Scheme = "http"; - Host = "localhost"; - Port = "80"; - } - - /// - /// Scheme (http/https) - /// - public string Scheme { get; set; } - - /// - /// Host - /// - public string Host { get; set; } - - /// - /// Port - /// - public string Port { get; set; } - } -} diff --git a/FrontEnd/FrontEnd/ApiProxyServerOptionsExtensions.cs b/FrontEnd/FrontEnd/ApiProxyServerOptionsExtensions.cs deleted file mode 100644 index 8008ba1d8..000000000 --- a/FrontEnd/FrontEnd/ApiProxyServerOptionsExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Options; -using System; - -namespace FrontEnd -{ - /// - /// Proxy Server Options Extension - /// - public static class ApiProxyServerOptionsExtensions - { - /// - /// Returns Uri - /// - /// - /// - public static Uri ToUri(this ApiProxyServerOptions options) - { - int.TryParse(options.Port, out int portNumber); - UriBuilder uriBuilder = new UriBuilder(options.Scheme, options.Host, portNumber); - return uriBuilder.Uri; - } - - /// - /// Returns Proxy Options - /// - /// - /// - public static IOptions ToProxyOptions(this ApiProxyServerOptions options) - { - ProxyOptions proxyOptions = new ProxyOptions() - { - Host = options.Host, - Port = options.Port, - Scheme = options.Scheme - }; - - return Options.Create(proxyOptions); - } - } -} diff --git a/FrontEnd/FrontEnd/FrontEnd.csproj b/FrontEnd/FrontEnd/FrontEnd.csproj deleted file mode 100644 index 6bd967305..000000000 --- a/FrontEnd/FrontEnd/FrontEnd.csproj +++ /dev/null @@ -1,60 +0,0 @@ - - - - The Frontend server for the application. - Copyright� 2017, Province of British Columbia. - Frontend Server - netcoreapp2.1 - portable - false - true - FrontEnd - Exe - FrontEnd - Debug;Release - 1.9.2.0 - - - - - PreserveNewest - - - Never - - - - - - - - - - - - - - - - - - - - - All - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - \ No newline at end of file diff --git a/FrontEnd/FrontEnd/Handlers/ApiProxyExtension.cs b/FrontEnd/FrontEnd/Handlers/ApiProxyExtension.cs deleted file mode 100644 index 0b94bfb8f..000000000 --- a/FrontEnd/FrontEnd/Handlers/ApiProxyExtension.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Builder; - -namespace FrontEnd.Handlers -{ - /// - /// Proxy Extension - /// - public static class ApiProxyExtension - { - /// - /// Use Proxy Server - /// - /// - /// - /// - public static IApplicationBuilder UseApiProxyServer(this IApplicationBuilder app, string apiUrl) - { - return app.Map(apiUrl, ProxyRequest); - } - - /// - /// Proxy Request - /// - /// - private static void ProxyRequest(IApplicationBuilder app) - { - app.UseMiddleware(); - } - } -} diff --git a/FrontEnd/FrontEnd/Handlers/ApiProxyMiddleware.cs b/FrontEnd/FrontEnd/Handlers/ApiProxyMiddleware.cs deleted file mode 100644 index 2c159985e..000000000 --- a/FrontEnd/FrontEnd/Handlers/ApiProxyMiddleware.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Proxy; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.Net.Http.Headers; -using System; -using System.Threading.Tasks; - -namespace FrontEnd.Handlers -{ - /// - /// Proxy Middleware - /// - public class ApiProxyMiddleware - { - private readonly string _apiUri; - private readonly ProxyMiddleware _proxy; - private readonly ILogger _logger; - - /// - /// Proxy Middleware Constructor - /// - /// - /// - /// - public ApiProxyMiddleware(RequestDelegate next, IOptions apiServerOptions, ILoggerFactory loggerFactory) - { - _apiUri = apiServerOptions.Value.ToUri().AbsoluteUri; - _proxy = new ProxyMiddleware(next, apiServerOptions.Value.ToProxyOptions()); - _logger = loggerFactory.CreateLogger(); - } - - /// - /// The invoke method is called by the ProxyExtension class - /// - /// - /// - public async Task Invoke(HttpContext context) - { - try - { - string requestPath = context.Request.Path.Value; - _logger.LogInformation("Api Path: " + requestPath); - - // set http security headers - if (requestPath.Contains("/fonts") || - requestPath.Contains("/images")) - { - context.Response.Headers[HeaderNames.CacheControl] = "private, max-age=60"; - context.Response.Headers[HeaderNames.Expires] = "60"; - } - else - { - context.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate, private"; - context.Response.Headers[HeaderNames.Pragma] = "no-cache"; - context.Response.Headers[HeaderNames.Expires] = "-1"; - } - - context.Response.Headers["X-Frame-Options"] = "SAMEORIGIN"; - context.Response.Headers["X-XSS-Protection"] = "1; mode=block"; - context.Response.Headers["X-Content-Type-Options"] = "nosniff"; - - await _proxy.Invoke(context); - } - catch (Exception e) - { - _logger.LogError(new EventId(-1, "ApiProxyMiddleware Exception"), e, $"An unexpected exception occured while forwarding a request to the API proxy; {_apiUri}."); - context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - context.Response.ContentType = "application/json"; - await context.Response.WriteAsync($"Exception encountered forwarding a request to {_apiUri}."); - } - } - } -} - diff --git a/FrontEnd/FrontEnd/Program.cs b/FrontEnd/FrontEnd/Program.cs deleted file mode 100644 index 57b678e76..000000000 --- a/FrontEnd/FrontEnd/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; - -namespace FrontEnd -{ - /// - /// The main Program for the application. - /// - public static class Program - { - /// - /// Main - /// - /// - public static void Main(string[] args) - { - BuildWebHost(args).Run(); - } - - /// - /// Build Web Host - /// - /// - /// - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup() - .Build(); - } -} - diff --git a/FrontEnd/FrontEnd/Startup.cs b/FrontEnd/FrontEnd/Startup.cs deleted file mode 100644 index 0ff507525..000000000 --- a/FrontEnd/FrontEnd/Startup.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Logging; -using FrontEnd.Handlers; -using Microsoft.Net.Http.Headers; -using Newtonsoft.Json.Serialization; - -namespace FrontEnd -{ - /// - /// Startup Fontend Proxy - /// - public class Startup - { - /// - /// Configuration for Frontend Proxy - /// - public IConfigurationRoot Configuration { get; } - - /// - /// Startup Mvc - /// - /// - public Startup(IHostingEnvironment env) - { - IConfigurationBuilder builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); - - Configuration = builder.Build(); - } - - /// - /// Configure Mvc Pipeline Services - /// - /// - public void ConfigureServices(IServiceCollection services) - { - // enable gzip compression - services.AddResponseCompression(); - - // Add framework services. - services.AddMvc() - .AddJsonOptions( - opts => { - opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - opts.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; - - // referenceLoopHandling is set to Ignore to prevent JSON parser issues with the user / roles model. - opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; - }); - - // allow access to the Configuration object - services.AddSingleton(Configuration); - - services.Configure(ConfigureApiProxyServerOptions); - } - - /// - /// Configure Mvc Pipeline - /// - /// - /// - /// - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseResponseCompression(); - app.UseMvc(); - app.UseDefaultFiles(); - - string webFileFolder = Configuration.GetSection("Constants").GetSection("WebFileFolder").Value; - - Console.WriteLine("Web root is " + webFileFolder); - - // Only serve up static files if they exist. - FileServerOptions options = new FileServerOptions - { - FileProvider = new PhysicalFileProvider(webFileFolder), - - StaticFileOptions = - { - OnPrepareResponse = ctx => - { - ctx.Context.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate, private"; - ctx.Context.Response.Headers[HeaderNames.Pragma] = "no-cache"; - ctx.Context.Response.Headers["X-Frame-Options"] = "SAMEORIGIN"; - ctx.Context.Response.Headers["X-XSS-Protection"] = "1; mode=block"; - ctx.Context.Response.Headers["X-Content-Type-Options"] = "nosniff"; - } - } - }; - - app.UseFileServer(options); - app.UseApiProxyServer(Configuration.GetSection("Constants").GetSection("ApiPathKey").Value); - } - - private void ConfigureApiProxyServerOptions(ApiProxyServerOptions options) - { - ApiProxyServerOptions defaultConfig = Configuration.GetSection("ApiProxyServer").Get(); - - if (defaultConfig != null) - { - options.Host = defaultConfig.Host; - options.Port = defaultConfig.Port; - options.Scheme = defaultConfig.Scheme; - } - - string apiServerUri = Configuration["API_SERVER"]; - - if (apiServerUri != null) - { - string[] apiServerUriParts = apiServerUri.Split(':'); - string host = apiServerUriParts[0]; - string port = apiServerUriParts.Length > 1 ? apiServerUriParts[1] : "80"; - options.Scheme = "http"; - options.Host = host; - options.Port = port; - } - } - } -} diff --git a/FrontEnd/FrontEnd/appsettings.json b/FrontEnd/FrontEnd/appsettings.json deleted file mode 100644 index 958402061..000000000 --- a/FrontEnd/FrontEnd/appsettings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Constants": { - "VersionUrl": "/api/version", - "ApiPathKey": "/api", - "WebFileFolder": "/opt/app-root/dist" - }, - "ApiProxyServer": { - "Scheme": "http", - "Host": "localhost", - "Port": "8080" - }, - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Warning", - "System": "Warning", - "Microsoft": "Warning" - } - } -} diff --git a/FrontEnd/FrontEnd/web.config b/FrontEnd/FrontEnd/web.config deleted file mode 100644 index 3ced7c548..000000000 --- a/FrontEnd/FrontEnd/web.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file From 5c9b883d00c46d6f9e849f97cc4f97da89ba6f91 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 1 Jun 2021 15:34:07 -0700 Subject: [PATCH 009/352] audit fix --- client/package-lock.json | 67 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index b4ba9acf8..c56872381 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -864,20 +864,36 @@ }, "dependencies": { "browserslist": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.2.tgz", - "integrity": "sha512-ISS/AIAiHERJ3d45Fz0AVYKkgcy+F/eJHzKEvv1j0wwKGKD9T3BrwKr/5g45L+Y4XIK5PlTqefHciRFcfE1Jxg==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000939", - "electron-to-chromium": "^1.3.113", - "node-releases": "^1.1.8" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "dependencies": { + "electron-to-chromium": { + "version": "1.3.743", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz", + "integrity": "sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg==", + "dev": true + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", + "dev": true + } } }, "caniuse-lite": { - "version": "1.0.30000946", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000946.tgz", - "integrity": "sha512-ZVXtMoZ3Mfq69Ikv587Av+5lwGVJsG98QKUucVmtFBf0tl1kOCfLQ5o6Z2zBNis4Mx3iuH77WxEUpdP6t7f2CQ==", + "version": "1.0.30001232", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", + "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==", "dev": true } } @@ -2454,6 +2470,12 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3388,6 +3410,12 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -6227,9 +6255,9 @@ } }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "html-entities": { "version": "1.2.1", @@ -7911,15 +7939,6 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, - "node-releases": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.10.tgz", - "integrity": "sha512-KbUPCpfoBvb3oBkej9+nrU0/7xPlVhmhhUJ1PZqwIP5/1dJkRWKWD3OONjo6M2J7tSCBtDCumLwwqeI+DWWaLQ==", - "dev": true, - "requires": { - "semver": "^5.3.0" - } - }, "node-sass": { "version": "4.14.1", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", @@ -12047,9 +12066,9 @@ } }, "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, "which": { From e0a4cde342e36dca74aa5db3de5eb59d7512a912 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 3 Jun 2021 14:55:03 -0700 Subject: [PATCH 010/352] .net 2.1 to .net 3.1 (has issues with Hangfire and EF query) --- Server/HetsApi.sln | 8 +- .../SiteminderAuthenticationHandler.cs | 3 +- .../Authorization/PermissionHandler.cs | 61 ++++---- .../Controllers/AuthenticationController.cs | 5 +- .../HetsApi/Controllers/BusinessController.cs | 4 +- .../Controllers/CurrentUserController.cs | 5 +- Server/HetsApi/Controllers/ErrorController.cs | 5 +- Server/HetsApi/Controllers/HomeController.cs | 5 +- .../HetsApi/Controllers/VersionController.cs | 5 +- Server/HetsApi/Helpers/UserAccountHelper.cs | 3 +- Server/HetsApi/HetsApi.csproj | 67 ++++----- Server/HetsApi/Program.cs | 33 +++-- Server/HetsApi/Startup.cs | 135 ++++++++++-------- Server/HetsApi/web.config | 18 --- Server/HetsCommon/HetsCommon.csproj | 8 +- Server/HetsData/Helpers/OwnerHelper.cs | 6 +- Server/HetsData/HetsData.csproj | 11 +- Server/HetsReport/HetsReport.csproj | 2 +- 18 files changed, 189 insertions(+), 195 deletions(-) delete mode 100644 Server/HetsApi/web.config diff --git a/Server/HetsApi.sln b/Server/HetsApi.sln index 0616a2f33..03f8f1b31 100644 --- a/Server/HetsApi.sln +++ b/Server/HetsApi.sln @@ -36,11 +36,9 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {FF1DB058-3D10-4065-A42B-E9EB5BEB0982} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {E88FFF3D-CE15-43E9-B1BE-4111E5862E2B} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {292B510E-6283-4616-AD2A-D8A994FD4285} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {7DFA1859-E5B0-4460-A5A5-5E5288A4AC94} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BAABCEB5-DF1F-44BB-92B9-01FF124FABA6} diff --git a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs index 51394e541..e53c3e921 100644 --- a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs +++ b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs @@ -13,6 +13,7 @@ using Microsoft.EntityFrameworkCore; using HetsData.Model; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Hosting; namespace HetsApi.Authentication { @@ -200,7 +201,7 @@ protected override Task HandleAuthenticateAsync() { HttpContext context = Request.HttpContext; DbAppContext dbAppContext = (DbAppContext)context.RequestServices.GetService(typeof(DbAppContext)); - IHostingEnvironment hostingEnv = (IHostingEnvironment)context.RequestServices.GetService(typeof(IHostingEnvironment)); + IWebHostEnvironment hostingEnv = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment)); UserSettings userSettings = new UserSettings(); string userId = ""; diff --git a/Server/HetsApi/Authorization/PermissionHandler.cs b/Server/HetsApi/Authorization/PermissionHandler.cs index 77ab2ab02..7c9932140 100644 --- a/Server/HetsApi/Authorization/PermissionHandler.cs +++ b/Server/HetsApi/Authorization/PermissionHandler.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; namespace HetsApi.Authorization { @@ -32,9 +33,9 @@ public static IServiceCollection RegisterPermissionHandler(this IServiceCollecti public class PermissionHandler : AuthorizationHandler { private readonly HttpContext _httpContext; - private readonly IHostingEnvironment _hostingEnv; + private readonly IWebHostEnvironment _hostingEnv; - public PermissionHandler(IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnv) + public PermissionHandler(IHttpContextAccessor httpContextAccessor, IWebHostEnvironment hostingEnv) { _httpContext = httpContextAccessor.HttpContext; _hostingEnv = hostingEnv; @@ -48,39 +49,39 @@ public PermissionHandler(IHttpContextAccessor httpContextAccessor, IHostingEnvir /// protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { - // ************************************************** - // check if we have a Dev Environment Cookie - // ************************************************** - if (_hostingEnv.IsDevelopment()) - { - string temp = _httpContext.Request.Cookies["DEV-USER"]; + //// ************************************************** + //// check if we have a Dev Environment Cookie + //// ************************************************** + //if (_hostingEnv.IsDevelopment()) + //{ + // string temp = _httpContext.Request.Cookies["DEV-USER"]; - if (!string.IsNullOrEmpty(temp)) - { - // access granted - context.Succeed(requirement); + // if (!string.IsNullOrEmpty(temp)) + // { + // // access granted + // context.Succeed(requirement); - await Task.CompletedTask; - return; - } - } + // await Task.CompletedTask; + // return; + // } + //} - // ************************************************** - // check if we have a Business Dev Environment Cookie - // ************************************************** - if (_hostingEnv.IsDevelopment()) - { - string temp = _httpContext.Request.Cookies["BUS-USER"]; + //// ************************************************** + //// check if we have a Business Dev Environment Cookie + //// ************************************************** + //if (_hostingEnv.IsDevelopment()) + //{ + // string temp = _httpContext.Request.Cookies["BUS-USER"]; - if (!string.IsNullOrEmpty(temp)) - { - // access granted - context.Succeed(requirement); + // if (!string.IsNullOrEmpty(temp)) + // { + // // access granted + // context.Succeed(requirement); - await Task.CompletedTask; - return; - } - } + // await Task.CompletedTask; + // return; + // } + //} // ************************************************** // if not - check the users permissions diff --git a/Server/HetsApi/Controllers/AuthenticationController.cs b/Server/HetsApi/Controllers/AuthenticationController.cs index c60dfc5be..6ce100d9c 100644 --- a/Server/HetsApi/Controllers/AuthenticationController.cs +++ b/Server/HetsApi/Controllers/AuthenticationController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using HetsApi.Authentication; using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -17,7 +18,7 @@ namespace HetsApi.Controllers public class AuthenticationController : Controller { private readonly SiteMinderAuthOptions _options = new SiteMinderAuthOptions(); - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; private readonly HttpContext _httpContext; /// @@ -25,7 +26,7 @@ public class AuthenticationController : Controller /// /// /// - public AuthenticationController(IHostingEnvironment env, IHttpContextAccessor httpContextAccessor) + public AuthenticationController(IWebHostEnvironment env, IHttpContextAccessor httpContextAccessor) { _env = env; _httpContext = httpContextAccessor.HttpContext; diff --git a/Server/HetsApi/Controllers/BusinessController.cs b/Server/HetsApi/Controllers/BusinessController.cs index b36465878..680f8b2fa 100644 --- a/Server/HetsApi/Controllers/BusinessController.cs +++ b/Server/HetsApi/Controllers/BusinessController.cs @@ -25,9 +25,9 @@ public class BusinessController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly HttpContext _httpContext; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; - public BusinessController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnv) + public BusinessController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment hostingEnv) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Controllers/CurrentUserController.cs b/Server/HetsApi/Controllers/CurrentUserController.cs index 381d94fe4..5aa7ed792 100644 --- a/Server/HetsApi/Controllers/CurrentUserController.cs +++ b/Server/HetsApi/Controllers/CurrentUserController.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -27,10 +28,10 @@ public class CurrentUserController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly ILogger _logger; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; private readonly HttpContext _httpContext; - public CurrentUserController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, ILoggerFactory loggerFactory, IHostingEnvironment env) + public CurrentUserController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, ILoggerFactory loggerFactory, IWebHostEnvironment env) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Controllers/ErrorController.cs b/Server/HetsApi/Controllers/ErrorController.cs index 33a3940fb..d66b9f5d8 100644 --- a/Server/HetsApi/Controllers/ErrorController.cs +++ b/Server/HetsApi/Controllers/ErrorController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http.Features; using HetsApi.Model; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -16,13 +17,13 @@ namespace HetsApi.Controllers [ApiExplorerSettings(IgnoreApi = true)] public class ErrorController : Controller { - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; /// /// Error Controller Constructor /// /// - public ErrorController(IHostingEnvironment env) + public ErrorController(IWebHostEnvironment env) { _env = env; } diff --git a/Server/HetsApi/Controllers/HomeController.cs b/Server/HetsApi/Controllers/HomeController.cs index 602c9c1a4..66878e057 100644 --- a/Server/HetsApi/Controllers/HomeController.cs +++ b/Server/HetsApi/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Hosting; using HetsApi.Model; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -11,13 +12,13 @@ namespace HetsApi.Controllers [ApiExplorerSettings(IgnoreApi = true)] public class HomeController : Controller { - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; /// /// Authentication Controller Constructor /// /// - public HomeController(IHostingEnvironment env) + public HomeController(IWebHostEnvironment env) { _env = env; } diff --git a/Server/HetsApi/Controllers/VersionController.cs b/Server/HetsApi/Controllers/VersionController.cs index 9109c3b1b..70064be18 100644 --- a/Server/HetsApi/Controllers/VersionController.cs +++ b/Server/HetsApi/Controllers/VersionController.cs @@ -8,6 +8,7 @@ using HetsApi.Model; using HetsData.Model; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -22,9 +23,9 @@ public class VersionController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; - public VersionController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IHostingEnvironment env) + public VersionController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment env) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Helpers/UserAccountHelper.cs b/Server/HetsApi/Helpers/UserAccountHelper.cs index 691e2bc06..3accd34eb 100644 --- a/Server/HetsApi/Helpers/UserAccountHelper.cs +++ b/Server/HetsApi/Helpers/UserAccountHelper.cs @@ -8,6 +8,7 @@ using HetsData.Model; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Hosting; namespace HetsApi.Helpers { @@ -49,7 +50,7 @@ public static bool IsBusiness(HttpContext httpContext) /// /// /// - public static string GetBusinessGuid(HttpContext httpContext, IHostingEnvironment hostingEnv) + public static string GetBusinessGuid(HttpContext httpContext, IWebHostEnvironment hostingEnv) { string guid = ""; diff --git a/Server/HetsApi/HetsApi.csproj b/Server/HetsApi/HetsApi.csproj index c5446837a..a79bb01c4 100644 --- a/Server/HetsApi/HetsApi.csproj +++ b/Server/HetsApi/HetsApi.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 The Api server for the Hired Equipment Tracking System Copyright© 2017, Province of British Columbia. Hets Api Server @@ -36,45 +36,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + diff --git a/Server/HetsApi/Program.cs b/Server/HetsApi/Program.cs index 48195b78e..12c6a641b 100644 --- a/Server/HetsApi/Program.cs +++ b/Server/HetsApi/Program.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; namespace HetsApi { @@ -8,23 +10,24 @@ namespace HetsApi /// public static class Program { - /// - /// Main - /// - /// public static void Main(string[] args) { - BuildWebHost(args).Run(); + CreateHostBuilder(args).Build().Run(); } - /// - /// Build Web Host - /// - /// - /// - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup() - .Build(); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + //.UseSerilog((hostingContext, loggerConfiguration) => { + // loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration); + //} + //) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddEnvironmentVariables(); + }); } } diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 0b43a5aa7..90a61db93 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -13,6 +13,12 @@ using HetsApi.Authorization; using HetsApi.Authentication; using HetsData.Model; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OpenApi.Models; +using Microsoft.Extensions.Hosting; +using Swashbuckle.AspNetCore.SwaggerUI; namespace HetsApi { @@ -21,21 +27,14 @@ namespace HetsApi /// public class Startup { - private readonly IHostingEnvironment _hostingEnv; + private readonly IWebHostEnvironment _hostingEnv; - public IConfigurationRoot Configuration { get; } + public IConfiguration Configuration { get; } - public Startup(IHostingEnvironment env) + public Startup(IConfiguration configuration, IWebHostEnvironment env) { _hostingEnv = env; - - IConfigurationBuilder builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); - - Configuration = builder.Build(); + Configuration = configuration; } public void ConfigureServices(IServiceCollection services) @@ -48,6 +47,24 @@ public void ConfigureServices(IServiceCollection services) // add database context services.AddDbContext(options => options.UseNpgsql(connectionString)); + services + .AddControllers(options => + { + var policy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); + options.Filters.Add(new AuthorizeFilter(policy)); + }) + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; + options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; + options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; + options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); + // setup SiteMinder authentication (core 2.0+) services.AddAuthentication(options => { @@ -55,7 +72,6 @@ public void ConfigureServices(IServiceCollection services) options.DefaultChallengeScheme = SiteMinderAuthOptions.AuthenticationSchemeName; }).AddSiteMinderAuth(options => { - }); // setup authorization @@ -68,18 +84,6 @@ public void ConfigureServices(IServiceCollection services) options.MultipartBodyLengthLimit = 1073741824; // 1 GB }); - services.AddMvc(options => options.AddDefaultAuthorizationPolicyFilter()) - .AddJsonOptions( - opts => { - opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - opts.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; - opts.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; - opts.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; - - // ReferenceLoopHandling is set to Ignore to prevent JSON parser issues with the user / roles model. - opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; - }); - // enable Hangfire PostgreSqlStorageOptions postgreSqlStorageOptions = new PostgreSqlStorageOptions { SchemaName = "public" @@ -99,14 +103,12 @@ public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new Info + options.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "HETS REST API", Description = "Hired Equipment Tracking System" }); - - options.DescribeAllEnumsAsStrings(); }); } } @@ -117,28 +119,55 @@ public void ConfigureServices(IServiceCollection services) /// /// /// - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger logger) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - - // web site error handler (Testing: app.UseDeveloperExceptionPage();) - app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder => + if (env.IsDevelopment()) + app.UseDeveloperExceptionPage(); + + //app.UseMiddleware(); + + //TryMigrateDatabase(app, logger); + + //var healthCheckOptions = new HealthCheckOptions + //{ + // ResponseWriter = async (c, r) => + // { + // c.Response.ContentType = MediaTypeNames.Application.Json; + // var result = JsonSerializer.Serialize( + // new + // { + // checks = r.Entries.Select(e => + // new { + // description = e.Key, + // status = e.Value.Status.ToString(), + // tags = e.Value.Tags, + // responseTime = e.Value.Duration.TotalMilliseconds + // }), + // totalResponseTime = r.TotalDuration.TotalMilliseconds + // }); + // await c.Response.WriteAsync(result); + // } + //}; + + //app.UseHealthChecks("/healthz", healthCheckOptions); + + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + app.UseAuthorization(); + app.UseEndpoints(endpoints => { - builder.UseExceptionHandler(Configuration.GetSection("Constants:ErrorUrl").Value); + endpoints.MapControllers(); }); - // authenticate users - app.UseAuthentication(); - - // enable Hangfire - BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions + app.UseSwagger(); + app.UseSwaggerUI(options => { - WorkerCount = 1 - }; - - app.UseHangfireServer(jsOptions); + options.SwaggerEndpoint(Configuration.GetSection("Constants:SwaggerApiUrl").Value, "HETS REST API v1"); + options.DocExpansion(DocExpansion.None); + }); + // enable Hangfire Dashboard // disable the back to site link DashboardOptions dashboardOptions = new DashboardOptions { @@ -149,24 +178,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF // enable the hangfire dashboard app.UseHangfireDashboard(Configuration.GetSection("Constants:HangfireUrl").Value, dashboardOptions); - // setup mvc routes - app.UseMvc(routes => + BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}"); - }); + WorkerCount = 1 + }; - if (_hostingEnv.IsDevelopment()) - { - string swaggerApi = Configuration.GetSection("Constants:SwaggerApiUrl").Value; - app.UseSwagger(); - app.UseSwaggerUI(options => - { - options.SwaggerEndpoint(swaggerApi, "HETS REST API v1"); - options.DocExpansion(DocExpansion.None); - }); - } + app.UseHangfireServer(jsOptions); } /// diff --git a/Server/HetsApi/web.config b/Server/HetsApi/web.config deleted file mode 100644 index 92f64ac04..000000000 --- a/Server/HetsApi/web.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Server/HetsCommon/HetsCommon.csproj b/Server/HetsCommon/HetsCommon.csproj index e3626d0d1..3e767fea8 100644 --- a/Server/HetsCommon/HetsCommon.csproj +++ b/Server/HetsCommon/HetsCommon.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 Common code for the HETS application Copyright© 2017, Province of British Columbia Hets Common @@ -11,9 +11,9 @@ - - - + + + diff --git a/Server/HetsData/Helpers/OwnerHelper.cs b/Server/HetsData/Helpers/OwnerHelper.cs index c80225282..159c301a5 100644 --- a/Server/HetsData/Helpers/OwnerHelper.cs +++ b/Server/HetsData/Helpers/OwnerHelper.cs @@ -118,9 +118,9 @@ public static HetOwner GetRecord(int id, DbAppContext context, IConfiguration co .Include(x => x.HetEquipment) .ThenInclude(y => y.DistrictEquipmentType) .ThenInclude(z => z.EquipmentType) - .Include(x => x.HetEquipment) - .ThenInclude(y => y.Owner) - .ThenInclude(c => c.PrimaryContact) + //.Include(x => x.HetEquipment) + // .ThenInclude(y => y.Owner) + // .ThenInclude(c => c.PrimaryContact) .Include(x => x.HetEquipment) .ThenInclude(y => y.EquipmentStatusType) .Include(x => x.HetEquipment) diff --git a/Server/HetsData/HetsData.csproj b/Server/HetsData/HetsData.csproj index d9c02098e..b75e55f4b 100644 --- a/Server/HetsData/HetsData.csproj +++ b/Server/HetsData/HetsData.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 Common data code for the HETS application Copyright© 2017, Province of British Columbia Hets Data @@ -12,18 +12,15 @@ - - - + + + ..\..\..\..\..\Users\paulm\.nuget\packages\hangfire.core\1.6.20\lib\netstandard1.3\Hangfire.Core.dll - - ..\..\..\..\..\Users\paulm\.nuget\packages\microsoft.aspnetcore.mvc.core\1.0.4\lib\netstandard1.6\Microsoft.AspNetCore.Mvc.Core.dll - diff --git a/Server/HetsReport/HetsReport.csproj b/Server/HetsReport/HetsReport.csproj index 4142355b0..c1a21c053 100644 --- a/Server/HetsReport/HetsReport.csproj +++ b/Server/HetsReport/HetsReport.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 1.9.2.0 From 60dca891f0fbb76c428f1347c5f4e9dbd474035e Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Thu, 3 Jun 2021 15:51:06 -0700 Subject: [PATCH 011/352] converting to create react app. deleted original client folder and will rename client2 to client --- client2/.dockerignore | 2 + client2/.gitignore | 23 + client2/Dockerfile | 17 + client2/README.md | 100 + client2/nginx-start/start.sh | 13 + client2/nginx.conf.tmpl | 100 + client2/package-lock.json | 17316 ++++++++++++++++ client2/package.json | 61 + client2/public/favicon.ico | Bin 0 -> 3870 bytes client2/public/images/blueline.png | Bin 0 -> 158 bytes client2/public/images/gov/bceid_logo.png | Bin 0 -> 2637 bytes client2/public/images/gov/favicon.png | Bin 0 -> 11639 bytes client2/public/images/gov/gov3_bc_logo.png | Bin 0 -> 3881 bytes client2/public/images/gov/hets.jpg | Bin 0 -> 68151 bytes client2/public/images/greyline.png | Bin 0 -> 158 bytes client2/public/index.html | 43 + client2/public/manifest.json | 15 + client2/public/robots.txt | 3 + client2/src/App.test.js | 8 + client2/src/images/blueline.png | Bin 0 -> 158 bytes client2/src/images/gov/bceid_logo.png | Bin 0 -> 2637 bytes client2/src/images/gov/favicon.png | Bin 0 -> 11639 bytes client2/src/images/gov/gov3_bc_logo.png | Bin 0 -> 3881 bytes client2/src/images/gov/hets.jpg | Bin 0 -> 68151 bytes client2/src/images/greyline.png | Bin 0 -> 158 bytes client2/src/index.js | 20 + client2/src/js/App.jsx | 371 + client2/src/js/actionTypes.js | 228 + client2/src/js/actions.js | 39 + client2/src/js/api.js | 3286 +++ client2/src/js/components/Authorize.jsx | 29 + client2/src/js/components/BadgeLabel.jsx | 22 + client2/src/js/components/CheckboxControl.jsx | 37 + client2/src/js/components/ColDisplay.jsx | 30 + client2/src/js/components/Confirm.jsx | 42 + client2/src/js/components/Countdown.jsx | 58 + client2/src/js/components/DateControl.jsx | 106 + client2/src/js/components/DeleteButton.jsx | 27 + client2/src/js/components/DropdownControl.jsx | 200 + client2/src/js/components/EditButton.jsx | 29 + client2/src/js/components/Favourites.jsx | 225 + .../src/js/components/FileAttachDialog.jsx | 84 + client2/src/js/components/FilePicker.jsx | 37 + client2/src/js/components/FileUpload.jsx | 105 + client2/src/js/components/FilterDropdown.jsx | 187 + client2/src/js/components/Form.jsx | 27 + client2/src/js/components/FormDialog.jsx | 84 + .../src/js/components/FormInputControl.jsx | 76 + client2/src/js/components/History.jsx | 155 + client2/src/js/components/LinkControl.jsx | 68 + client2/src/js/components/Mailto.jsx | 36 + client2/src/js/components/ModalDialog.jsx | 39 + client2/src/js/components/MultiDropdown.jsx | 182 + client2/src/js/components/OverlayTrigger.jsx | 29 + client2/src/js/components/PageOrientation.jsx | 22 + client2/src/js/components/PrintButton.jsx | 45 + client2/src/js/components/ReturnButton.jsx | 31 + client2/src/js/components/RootCloseMenu.jsx | 24 + client2/src/js/components/SearchControl.jsx | 78 + client2/src/js/components/SortTable.jsx | 85 + client2/src/js/components/Spinner.jsx | 35 + client2/src/js/components/StatusDropdown.jsx | 77 + client2/src/js/components/TableControl.jsx | 35 + client2/src/js/components/TooltipButton.jsx | 49 + client2/src/js/components/Unimplemented.jsx | 21 + client2/src/js/components/Watermark.jsx | 24 + .../js/components/ui/AddButtonContainer.jsx | 20 + client2/src/js/components/ui/PageHeader.jsx | 29 + client2/src/js/components/ui/SearchBar.jsx | 22 + client2/src/js/components/ui/SubHeader.jsx | 66 + client2/src/js/constants.js | 147 + client2/src/js/history.js | 430 + client2/src/js/init.js | 115 + client2/src/js/reducers/all.js | 18 + client2/src/js/reducers/lookups.js | 277 + client2/src/js/reducers/models.js | 807 + client2/src/js/reducers/search.js | 50 + client2/src/js/reducers/ui.js | 149 + client2/src/js/reducers/user.js | 17 + client2/src/js/reducers/version.js | 15 + client2/src/js/selectors/history-selectors.js | 37 + client2/src/js/selectors/ui-selectors.js | 64 + client2/src/js/store.js | 35 + client2/src/js/utils/array.js | 35 + client2/src/js/utils/date.js | 169 + client2/src/js/utils/http.js | 301 + client2/src/js/utils/routes.js | 11 + client2/src/js/utils/string.js | 109 + client2/src/js/utils/string_test.js | 25 + client2/src/js/views/404.jsx | 26 + client2/src/js/views/AitReport.jsx | 552 + client2/src/js/views/BusinessOwner.jsx | 304 + client2/src/js/views/BusinessPortal.jsx | 221 + client2/src/js/views/DistrictAdmin.jsx | 295 + client2/src/js/views/Equipment.jsx | 401 + client2/src/js/views/EquipmentDetail.jsx | 543 + client2/src/js/views/EquipmentTable.jsx | 82 + client2/src/js/views/Footer.jsx | 43 + client2/src/js/views/HiringReport.jsx | 430 + client2/src/js/views/Home.jsx | 106 + client2/src/js/views/Main.jsx | 106 + client2/src/js/views/OvertimeRates.jsx | 131 + client2/src/js/views/Owners.jsx | 260 + client2/src/js/views/OwnersDetail.jsx | 988 + client2/src/js/views/Projects.jsx | 267 + client2/src/js/views/ProjectsDetail.jsx | 584 + .../src/js/views/RentalAgreementsDetail.jsx | 866 + client2/src/js/views/RentalRequests.jsx | 384 + client2/src/js/views/RentalRequestsDetail.jsx | 772 + client2/src/js/views/Roles.jsx | 171 + client2/src/js/views/RolesDetail.jsx | 266 + client2/src/js/views/Rollover.jsx | 188 + client2/src/js/views/SeniorityList.jsx | 133 + client2/src/js/views/StatusLetters.jsx | 174 + client2/src/js/views/TimeEntry.jsx | 488 + client2/src/js/views/TopNav.jsx | 391 + client2/src/js/views/Users.jsx | 273 + client2/src/js/views/UsersDetail.jsx | 450 + client2/src/js/views/Version.jsx | 256 + client2/src/js/views/WcbCglCoverage.jsx | 350 + .../js/views/dialogs/AttachmentAddDialog.jsx | 153 + .../js/views/dialogs/AttachmentEditDialog.jsx | 102 + client2/src/js/views/dialogs/CloneDialog.jsx | 184 + .../views/dialogs/ConditionAddEditDialog.jsx | 139 + .../src/js/views/dialogs/ConfirmDialog.jsx | 33 + .../views/dialogs/ConfirmForceHireDialog.jsx | 86 + .../js/views/dialogs/ContactsEditDialog.jsx | 273 + .../js/views/dialogs/DistrictEditDialog.jsx | 128 + .../DistrictEquipmentTypeAddEditDialog.jsx | 154 + .../js/views/dialogs/DocumentsListDialog.jsx | 217 + .../js/views/dialogs/EquipmentAddDialog.jsx | 419 + .../dialogs/EquipmentChangeStatusDialog.jsx | 98 + .../js/views/dialogs/EquipmentEditDialog.jsx | 510 + .../EquipmentRentalRatesEditDialog.jsx | 134 + .../views/dialogs/EquipmentTransferDialog.jsx | 493 + client2/src/js/views/dialogs/ErrorDialog.jsx | 123 + .../js/views/dialogs/HireOfferEditDialog.jsx | 465 + .../src/js/views/dialogs/NotesAddDialog.jsx | 106 + client2/src/js/views/dialogs/NotesDialog.jsx | 156 + .../views/dialogs/OvertimeRateEditDialog.jsx | 138 + .../views/dialogs/OwnerChangeStatusDialog.jsx | 160 + .../src/js/views/dialogs/OwnersAddDialog.jsx | 589 + .../src/js/views/dialogs/OwnersEditDialog.jsx | 267 + .../views/dialogs/OwnersPolicyEditDialog.jsx | 158 + .../js/views/dialogs/ProjectsAddDialog.jsx | 266 + .../js/views/dialogs/ProjectsEditDialog.jsx | 267 + .../RentalAgreementOvertimeNotesDialog.jsx | 109 + .../dialogs/RentalAgreementsEditDialog.jsx | 150 + .../dialogs/RentalConditionsEditDialog.jsx | 210 + .../views/dialogs/RentalRatesEditDialog.jsx | 258 + .../views/dialogs/RentalRequestsAddDialog.jsx | 336 + .../dialogs/RentalRequestsEditDialog.jsx | 175 + .../js/views/dialogs/SeniorityEditDialog.jsx | 230 + .../src/js/views/dialogs/TimeEntryDialog.jsx | 555 + .../js/views/dialogs/UserRoleAddDialog.jsx | 178 + .../src/js/views/dialogs/UsersEditDialog.jsx | 227 + client2/src/logo.svg | 1 + client2/src/reportWebVitals.js | 13 + client2/src/sass/components/all.scss | 21 + client2/src/sass/components/badge-label.scss | 5 + client2/src/sass/components/clone-dialog.scss | 18 + client2/src/sass/components/date-control.scss | 38 + .../src/sass/components/dropdown-control.scss | 72 + client2/src/sass/components/favourites.scss | 40 + client2/src/sass/components/file-upload.scss | 73 + .../src/sass/components/filter-dropdown.scss | 104 + client2/src/sass/components/form-dialog.scss | 18 + .../sass/components/form-input-control.scss | 0 client2/src/sass/components/history.scss | 18 + client2/src/sass/components/link-control.scss | 8 + .../src/sass/components/multi-dropdown.scss | 96 + client2/src/sass/components/print-button.scss | 7 + .../src/sass/components/return-button.scss | 8 + .../src/sass/components/search-control.scss | 11 + client2/src/sass/components/sort-table.scss | 30 + .../components/ui/add-button-container.scss | 4 + .../src/sass/components/ui/page-header.scss | 13 + .../src/sass/components/ui/search-bar.scss | 38 + client2/src/sass/components/ui/subheader.scss | 3 + client2/src/sass/gov3.scss | 2347 +++ client2/src/sass/header.scss | 213 + client2/src/sass/init.scss | 37 + client2/src/sass/main.scss | 137 + client2/src/sass/mixins.scss | 7 + client2/src/sass/print.scss | 155 + client2/src/sass/variables.scss | 13 + client2/src/sass/views/all.scss | 12 + client2/src/sass/views/business-portal.scss | 32 + client2/src/sass/views/dialogs/all.scss | 6 + .../src/sass/views/dialogs/contacts-edit.scss | 14 + .../sass/views/dialogs/documents-list.scss | 19 + .../views/dialogs/equipment-transfer.scss | 16 + .../src/sass/views/dialogs/error-dialog.scss | 28 + client2/src/sass/views/dialogs/notes.scss | 9 + .../sass/views/dialogs/rental-rates-edit.scss | 30 + client2/src/sass/views/district-admin.scss | 2 + client2/src/sass/views/equipment-list.scss | 69 + client2/src/sass/views/home.scss | 31 + client2/src/sass/views/owners.scss | 87 + client2/src/sass/views/projects.scss | 94 + client2/src/sass/views/rental-agreements.scss | 60 + client2/src/sass/views/rental-requests.scss | 86 + client2/src/sass/views/roles.scss | 42 + client2/src/sass/views/rollover.scss | 13 + client2/src/sass/views/users.scss | 48 + client2/src/setupProxy.js | 12 + client2/src/setupTests.js | 5 + 207 files changed, 50043 insertions(+) create mode 100644 client2/.dockerignore create mode 100644 client2/.gitignore create mode 100644 client2/Dockerfile create mode 100644 client2/README.md create mode 100644 client2/nginx-start/start.sh create mode 100644 client2/nginx.conf.tmpl create mode 100644 client2/package-lock.json create mode 100644 client2/package.json create mode 100644 client2/public/favicon.ico create mode 100644 client2/public/images/blueline.png create mode 100644 client2/public/images/gov/bceid_logo.png create mode 100644 client2/public/images/gov/favicon.png create mode 100644 client2/public/images/gov/gov3_bc_logo.png create mode 100644 client2/public/images/gov/hets.jpg create mode 100644 client2/public/images/greyline.png create mode 100644 client2/public/index.html create mode 100644 client2/public/manifest.json create mode 100644 client2/public/robots.txt create mode 100644 client2/src/App.test.js create mode 100644 client2/src/images/blueline.png create mode 100644 client2/src/images/gov/bceid_logo.png create mode 100644 client2/src/images/gov/favicon.png create mode 100644 client2/src/images/gov/gov3_bc_logo.png create mode 100644 client2/src/images/gov/hets.jpg create mode 100644 client2/src/images/greyline.png create mode 100644 client2/src/index.js create mode 100644 client2/src/js/App.jsx create mode 100644 client2/src/js/actionTypes.js create mode 100644 client2/src/js/actions.js create mode 100644 client2/src/js/api.js create mode 100644 client2/src/js/components/Authorize.jsx create mode 100644 client2/src/js/components/BadgeLabel.jsx create mode 100644 client2/src/js/components/CheckboxControl.jsx create mode 100644 client2/src/js/components/ColDisplay.jsx create mode 100644 client2/src/js/components/Confirm.jsx create mode 100644 client2/src/js/components/Countdown.jsx create mode 100644 client2/src/js/components/DateControl.jsx create mode 100644 client2/src/js/components/DeleteButton.jsx create mode 100644 client2/src/js/components/DropdownControl.jsx create mode 100644 client2/src/js/components/EditButton.jsx create mode 100644 client2/src/js/components/Favourites.jsx create mode 100644 client2/src/js/components/FileAttachDialog.jsx create mode 100644 client2/src/js/components/FilePicker.jsx create mode 100644 client2/src/js/components/FileUpload.jsx create mode 100644 client2/src/js/components/FilterDropdown.jsx create mode 100644 client2/src/js/components/Form.jsx create mode 100644 client2/src/js/components/FormDialog.jsx create mode 100644 client2/src/js/components/FormInputControl.jsx create mode 100644 client2/src/js/components/History.jsx create mode 100644 client2/src/js/components/LinkControl.jsx create mode 100644 client2/src/js/components/Mailto.jsx create mode 100644 client2/src/js/components/ModalDialog.jsx create mode 100644 client2/src/js/components/MultiDropdown.jsx create mode 100644 client2/src/js/components/OverlayTrigger.jsx create mode 100644 client2/src/js/components/PageOrientation.jsx create mode 100644 client2/src/js/components/PrintButton.jsx create mode 100644 client2/src/js/components/ReturnButton.jsx create mode 100644 client2/src/js/components/RootCloseMenu.jsx create mode 100644 client2/src/js/components/SearchControl.jsx create mode 100644 client2/src/js/components/SortTable.jsx create mode 100644 client2/src/js/components/Spinner.jsx create mode 100644 client2/src/js/components/StatusDropdown.jsx create mode 100644 client2/src/js/components/TableControl.jsx create mode 100644 client2/src/js/components/TooltipButton.jsx create mode 100644 client2/src/js/components/Unimplemented.jsx create mode 100644 client2/src/js/components/Watermark.jsx create mode 100644 client2/src/js/components/ui/AddButtonContainer.jsx create mode 100644 client2/src/js/components/ui/PageHeader.jsx create mode 100644 client2/src/js/components/ui/SearchBar.jsx create mode 100644 client2/src/js/components/ui/SubHeader.jsx create mode 100644 client2/src/js/constants.js create mode 100644 client2/src/js/history.js create mode 100644 client2/src/js/init.js create mode 100644 client2/src/js/reducers/all.js create mode 100644 client2/src/js/reducers/lookups.js create mode 100644 client2/src/js/reducers/models.js create mode 100644 client2/src/js/reducers/search.js create mode 100644 client2/src/js/reducers/ui.js create mode 100644 client2/src/js/reducers/user.js create mode 100644 client2/src/js/reducers/version.js create mode 100644 client2/src/js/selectors/history-selectors.js create mode 100644 client2/src/js/selectors/ui-selectors.js create mode 100644 client2/src/js/store.js create mode 100644 client2/src/js/utils/array.js create mode 100644 client2/src/js/utils/date.js create mode 100644 client2/src/js/utils/http.js create mode 100644 client2/src/js/utils/routes.js create mode 100644 client2/src/js/utils/string.js create mode 100644 client2/src/js/utils/string_test.js create mode 100644 client2/src/js/views/404.jsx create mode 100644 client2/src/js/views/AitReport.jsx create mode 100644 client2/src/js/views/BusinessOwner.jsx create mode 100644 client2/src/js/views/BusinessPortal.jsx create mode 100644 client2/src/js/views/DistrictAdmin.jsx create mode 100644 client2/src/js/views/Equipment.jsx create mode 100644 client2/src/js/views/EquipmentDetail.jsx create mode 100644 client2/src/js/views/EquipmentTable.jsx create mode 100644 client2/src/js/views/Footer.jsx create mode 100644 client2/src/js/views/HiringReport.jsx create mode 100644 client2/src/js/views/Home.jsx create mode 100644 client2/src/js/views/Main.jsx create mode 100644 client2/src/js/views/OvertimeRates.jsx create mode 100644 client2/src/js/views/Owners.jsx create mode 100644 client2/src/js/views/OwnersDetail.jsx create mode 100644 client2/src/js/views/Projects.jsx create mode 100644 client2/src/js/views/ProjectsDetail.jsx create mode 100644 client2/src/js/views/RentalAgreementsDetail.jsx create mode 100644 client2/src/js/views/RentalRequests.jsx create mode 100644 client2/src/js/views/RentalRequestsDetail.jsx create mode 100644 client2/src/js/views/Roles.jsx create mode 100644 client2/src/js/views/RolesDetail.jsx create mode 100644 client2/src/js/views/Rollover.jsx create mode 100644 client2/src/js/views/SeniorityList.jsx create mode 100644 client2/src/js/views/StatusLetters.jsx create mode 100644 client2/src/js/views/TimeEntry.jsx create mode 100644 client2/src/js/views/TopNav.jsx create mode 100644 client2/src/js/views/Users.jsx create mode 100644 client2/src/js/views/UsersDetail.jsx create mode 100644 client2/src/js/views/Version.jsx create mode 100644 client2/src/js/views/WcbCglCoverage.jsx create mode 100644 client2/src/js/views/dialogs/AttachmentAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/AttachmentEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/CloneDialog.jsx create mode 100644 client2/src/js/views/dialogs/ConditionAddEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/ConfirmDialog.jsx create mode 100644 client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx create mode 100644 client2/src/js/views/dialogs/ContactsEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/DistrictEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/DocumentsListDialog.jsx create mode 100644 client2/src/js/views/dialogs/EquipmentAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx create mode 100644 client2/src/js/views/dialogs/EquipmentEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/EquipmentTransferDialog.jsx create mode 100644 client2/src/js/views/dialogs/ErrorDialog.jsx create mode 100644 client2/src/js/views/dialogs/HireOfferEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/NotesAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/NotesDialog.jsx create mode 100644 client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx create mode 100644 client2/src/js/views/dialogs/OwnersAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/OwnersEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/ProjectsAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/ProjectsEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalRatesEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/SeniorityEditDialog.jsx create mode 100644 client2/src/js/views/dialogs/TimeEntryDialog.jsx create mode 100644 client2/src/js/views/dialogs/UserRoleAddDialog.jsx create mode 100644 client2/src/js/views/dialogs/UsersEditDialog.jsx create mode 100644 client2/src/logo.svg create mode 100644 client2/src/reportWebVitals.js create mode 100644 client2/src/sass/components/all.scss create mode 100644 client2/src/sass/components/badge-label.scss create mode 100644 client2/src/sass/components/clone-dialog.scss create mode 100644 client2/src/sass/components/date-control.scss create mode 100644 client2/src/sass/components/dropdown-control.scss create mode 100644 client2/src/sass/components/favourites.scss create mode 100644 client2/src/sass/components/file-upload.scss create mode 100644 client2/src/sass/components/filter-dropdown.scss create mode 100644 client2/src/sass/components/form-dialog.scss create mode 100644 client2/src/sass/components/form-input-control.scss create mode 100644 client2/src/sass/components/history.scss create mode 100644 client2/src/sass/components/link-control.scss create mode 100644 client2/src/sass/components/multi-dropdown.scss create mode 100644 client2/src/sass/components/print-button.scss create mode 100644 client2/src/sass/components/return-button.scss create mode 100644 client2/src/sass/components/search-control.scss create mode 100644 client2/src/sass/components/sort-table.scss create mode 100644 client2/src/sass/components/ui/add-button-container.scss create mode 100644 client2/src/sass/components/ui/page-header.scss create mode 100644 client2/src/sass/components/ui/search-bar.scss create mode 100644 client2/src/sass/components/ui/subheader.scss create mode 100644 client2/src/sass/gov3.scss create mode 100644 client2/src/sass/header.scss create mode 100644 client2/src/sass/init.scss create mode 100644 client2/src/sass/main.scss create mode 100644 client2/src/sass/mixins.scss create mode 100644 client2/src/sass/print.scss create mode 100644 client2/src/sass/variables.scss create mode 100644 client2/src/sass/views/all.scss create mode 100644 client2/src/sass/views/business-portal.scss create mode 100644 client2/src/sass/views/dialogs/all.scss create mode 100644 client2/src/sass/views/dialogs/contacts-edit.scss create mode 100644 client2/src/sass/views/dialogs/documents-list.scss create mode 100644 client2/src/sass/views/dialogs/equipment-transfer.scss create mode 100644 client2/src/sass/views/dialogs/error-dialog.scss create mode 100644 client2/src/sass/views/dialogs/notes.scss create mode 100644 client2/src/sass/views/dialogs/rental-rates-edit.scss create mode 100644 client2/src/sass/views/district-admin.scss create mode 100644 client2/src/sass/views/equipment-list.scss create mode 100644 client2/src/sass/views/home.scss create mode 100644 client2/src/sass/views/owners.scss create mode 100644 client2/src/sass/views/projects.scss create mode 100644 client2/src/sass/views/rental-agreements.scss create mode 100644 client2/src/sass/views/rental-requests.scss create mode 100644 client2/src/sass/views/roles.scss create mode 100644 client2/src/sass/views/rollover.scss create mode 100644 client2/src/sass/views/users.scss create mode 100644 client2/src/setupProxy.js create mode 100644 client2/src/setupTests.js diff --git a/client2/.dockerignore b/client2/.dockerignore new file mode 100644 index 000000000..354eebdbd --- /dev/null +++ b/client2/.dockerignore @@ -0,0 +1,2 @@ +.git +node_modules/ diff --git a/client2/.gitignore b/client2/.gitignore new file mode 100644 index 000000000..4d29575de --- /dev/null +++ b/client2/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/client2/Dockerfile b/client2/Dockerfile new file mode 100644 index 000000000..6f445285b --- /dev/null +++ b/client2/Dockerfile @@ -0,0 +1,17 @@ +FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/node:1 AS builder +LABEL maintainer="young-jin.chung@gov.bc.ca" + +COPY . /src + +RUN cd /src && npm ci && \ + ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT + +FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/nginx-116-rhel8:1 + +COPY --from=builder /src/dist/. /tmp/src +COPY --from=builder /src/nginx-start/. /tmp/src/nginx-start +COPY --from=builder /src/nginx.conf.tmpl /tmp/src/nginx.conf.tmpl + +RUN $STI_SCRIPTS_PATH/assemble + +CMD $STI_SCRIPTS_PATH/run \ No newline at end of file diff --git a/client2/README.md b/client2/README.md new file mode 100644 index 000000000..a9f8cc1f1 --- /dev/null +++ b/client2/README.md @@ -0,0 +1,100 @@ +# Hired Equipment Tracking System Web Application + +The Hired Equipment Tracking System (a.k.a. HETS) is a web application to track and hire equipment +in British Columbia. The client/ directory is the home of of the front-end source code. + +## Getting Started + +These instructions will get you web application and running on your local machine for development +and testing purposes. + +### Prerequisites + +The following software requirements are required: + +1. [Node](https://nodejs.org/en/download/) (at least version 8) +2. [git](https://git-scm.com/downloads) + +### Installing + +1. Git clone the [repository](https://github.com/bcgov/hets) onto your local machine. + + ``` + git clone git@github.com:bcgov/hets.git + ``` + +2. Install the Node module dependencies. You will need to be in the hets/client/ directory. + + ``` + npm install + ``` + + **Note**: The installation of [node-sass](https://www.npmjs.com/package/node-sass) might fail + depending on the target platform because of a missing C compiler. + +3. Run the local dev server + + ``` + npm start + ``` + +Now you will be able to access the web app when you go to +[http:://localhost:3000](http:://localhost:3000) + +## Development + +The web application requires the [C# API Server](https://github.com/bcgov/hets/tree/master/Server) +to be runing on localhost which can connect to a local PostgreSQL database. Check the +[Server project’s documentation](https://github.com/bcgov/hets/blob/master/Server/README.md) on how +to run the API server. Look for documentation in the +[DB Scripts](https://github.com/bcgov/hets/tree/master/Db%20Scripts) directory on how to init a +database. + +[Redux](https://redux.js.org/) is used to store most of the application’s state. The application’s +[store.js](https://github.com/bcgov/hets/tree/master/client/src/js/store.js) contains the response +data from any API request to be used by the React components as well as UI data. + +[React Router v3](https://github.com/ReactTraining/react-router/tree/v3/docs) is used to control the +browser’s URL history and routing. Routes are defined in +[app.jsx](https://github.com/bcgov/hets/tree/master/client/src/js/app.jsx) file. If a user is a +business owner they can only access the routes at the path `/business`. All other users can access +the rest of the application’s routes. + +API requests follow an [action creator pattern](https://redux.js.org/basics/actions#action-creators) +and they are all defined in a [api](./src/js/api.js) file. + +[SASS](https://sass-lang.com/) is a CSS preprocessor. The SCSS flavour of SASS is used for all the +files in the project. + +The web application uses [Webpack](https://webpack.js.org/)’s +[Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) which will update +the UI whenever a [React Component](https://reactjs.org/docs/react-component.html) is saved on disk. + +[Create React App](https://www.npmjs.com/package/create-react-app) is the tool used for the front-end build system. Inside the + + + + +## Coding style + +Coding style for JS is enforced by [ESLint](https://eslint.org/). ESLint is run whenever the +JavaScript is built. Warnings turn into errors when the project is built. Any ESLint errors will +fail to build the JS. + +## Deployment + + + + +## Built With + +- [React](https://reactjs.org/) - JS library for building UIs +- [React Bootstrap](https://react-bootstrap.github.io/) - UI components and styles + +## License + +This project is licensed under the [Apache v2 License](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/client2/nginx-start/start.sh b/client2/nginx-start/start.sh new file mode 100644 index 000000000..0afa627a3 --- /dev/null +++ b/client2/nginx-start/start.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +#echo "---> Setting window.RUNTIME_REACT_APP values ..." +#JS_PATH=~/js/env.config.js + +#echo "window.RUNTIME_REACT_APP_SSO_HOST='${REACT_APP_SSO_HOST}';" > $JS_PATH +#echo "window.RUNTIME_REACT_APP_SSO_REALM='${REACT_APP_SSO_REALM}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_SSO_CLIENT='${REACT_APP_SSO_CLIENT}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_API_HOST='${REACT_APP_API_HOST}';" >> $JS_PATH +#echo "window.RUNTIME_REACT_APP_DWPBI_URL='${REACT_APP_DWPBI_URL}';" >> $JS_PATH + +echo "---> Creating nginx.conf ..." +envsubst '${HETS_DEPLOY_SUFFIX}' < /tmp/src/nginx.conf.tmpl > /etc/nginx/nginx.conf \ No newline at end of file diff --git a/client2/nginx.conf.tmpl b/client2/nginx.conf.tmpl new file mode 100644 index 000000000..f6849c97d --- /dev/null +++ b/client2/nginx.conf.tmpl @@ -0,0 +1,100 @@ +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + + +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + gzip on; + gzip_disable "msie6"; + + gzip_comp_level 6; + gzip_min_length 1100; + gzip_buffers 16 8k; + gzip_proxied any; + gzip_types + text/plain + text/css + text/js + text/xml + text/csv + text/javascript + application/javascript + application/json + application/xml + application/vnd.google-earth.kml+xml + "application/gml+xml; version=3.2" + application/rss+xml + image/svg+xml; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /opt/app-root/etc/nginx.d/*.conf; + + server { + listen 8080 default_server; + listen [::]:8080 default_server; + server_name _; + + underscores_in_headers on; + add_header Last-Modified $date_gmt; + add_header Cache-Control "private, no-store, no-cache, must-revalidate"; + + client_max_body_size 5M; + + location /api/ { + proxy_connect_timeout 1800; + proxy_send_timeout 1800; + proxy_read_timeout 1800; + send_timeout 1800; + + proxy_set_header HOST $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + + # proxy_hide_header WWW-Authenticate; + + proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; + } + + location /swagger/ { + proxy_set_header HOST $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080/swagger/; + } + + location / { + root /opt/app-root/src; + index index.html index.htm; + + try_files $uri /index.html =404; + } + } +} \ No newline at end of file diff --git a/client2/package-lock.json b/client2/package-lock.json new file mode 100644 index 000000000..c0d232a29 --- /dev/null +++ b/client2/package-lock.json @@ -0,0 +1,17316 @@ +{ + "name": "client2", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz", + "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==" + }, + "@babel/core": { + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", + "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.1", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.1", + "@babel/parser": "^7.12.3", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/generator": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", + "requires": { + "@babel/types": "^7.14.2", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz", + "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==", + "requires": { + "@babel/compat-data": "^7.14.4", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz", + "integrity": "sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.14.4", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz", + "integrity": "sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", + "requires": { + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-function-name": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.14.2" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz", + "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==", + "requires": { + "@babel/traverse": "^7.13.15", + "@babel/types": "^7.13.16" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz", + "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==", + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz", + "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" + }, + "@babel/helper-wrap-function": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helpers": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz", + "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==" + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz", + "integrity": "sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz", + "integrity": "sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.3", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-class-static-block": "^7.12.13" + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz", + "integrity": "sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-decorators": "^7.12.1" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz", + "integrity": "sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz", + "integrity": "sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz", + "integrity": "sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz", + "integrity": "sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz", + "integrity": "sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz", + "integrity": "sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz", + "integrity": "sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA==", + "requires": { + "@babel/compat-data": "^7.14.4", + "@babel/helper-compilation-targets": "^7.14.4", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.2" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz", + "integrity": "sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz", + "integrity": "sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-create-class-features-plugin": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz", + "integrity": "sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz", + "integrity": "sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz", + "integrity": "sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz", + "integrity": "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", + "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz", + "integrity": "sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz", + "integrity": "sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.14.4", + "@babel/helper-split-export-declaration": "^7.12.13", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz", + "integrity": "sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.1.tgz", + "integrity": "sha512-8hAtkmsQb36yMmEtk2JZ9JnVyDSnDOdlB+0nEGzIDLuK4yR3JcEjfuFPYkdEPSh8Id+rAMeBEn+X0iVEyho6Hg==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz", + "integrity": "sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw==", + "requires": { + "@babel/helper-module-transforms": "^7.14.2", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz", + "integrity": "sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ==", + "requires": { + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.13.12", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", + "requires": { + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz", + "integrity": "sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw==", + "requires": { + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz", + "integrity": "sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.13.13.tgz", + "integrity": "sha512-SNJU53VM/SjQL0bZhyU+f4kJQz7bQQajnrZRSaU21hruG/NWY41AEM9AWXeXX90pYr/C2yAmTgI6yW3LlLrAUQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.2.tgz", + "integrity": "sha512-zCubvP+jjahpnFJvPaHPiGVfuVUjXHhFvJKQdNnsmSsiU9kR/rCZ41jHc++tERD2zV+p7Hr6is+t5b6iWTCqSw==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.3.tgz", + "integrity": "sha512-uuxuoUNVhdgYzERiHHFkE4dWoJx+UFVyuAl0aqN8P2/AKFHwqgUC5w2+4/PjpKXJsFgBlYAFXlUmDQ3k3DUkXw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/types": "^7.14.2" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz", + "integrity": "sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ==", + "requires": { + "@babel/plugin-transform-react-jsx": "^7.12.17" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz", + "integrity": "sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.2.tgz", + "integrity": "sha512-OMorspVyjxghAjzgeAWc6O7W7vHbJhV69NeTGdl9Mxgz6PaweAuo7ffB9T5A1OQ9dGcw0As4SYMUhyNC4u7mVg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", + "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", + "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz", + "integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==", + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.4.tgz", + "integrity": "sha512-WYdcGNEO7mCCZ2XzRlxwGj3PgeAr50ifkofOUC/+IN/GzKLB+biDPVBUAQN2C/dVZTvEXCp80kfQ1FFZPrwykQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.4", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-typescript": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/preset-env": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.4.tgz", + "integrity": "sha512-GwMMsuAnDtULyOtuxHhzzuSRxFeP0aR/LNzrHRzP8y6AgDNgqnrfCCBm/1cRdTU75tRs28Eh76poHLcg9VF0LA==", + "requires": { + "@babel/compat-data": "^7.14.4", + "@babel/helper-compilation-targets": "^7.14.4", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.14.2", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-class-static-block": "^7.14.3", + "@babel/plugin-proposal-dynamic-import": "^7.14.2", + "@babel/plugin-proposal-export-namespace-from": "^7.14.2", + "@babel/plugin-proposal-json-strings": "^7.14.2", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2", + "@babel/plugin-proposal-numeric-separator": "^7.14.2", + "@babel/plugin-proposal-object-rest-spread": "^7.14.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.2", + "@babel/plugin-proposal-optional-chaining": "^7.14.2", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-private-property-in-object": "^7.14.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.0", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.14.4", + "@babel/plugin-transform-classes": "^7.14.4", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.14.4", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.14.2", + "@babel/plugin-transform-modules-commonjs": "^7.14.0", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.14.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.14.2", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.13.15", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.14.4", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.13.13.tgz", + "integrity": "sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA==", + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-transform-react-display-name": "^7.12.13", + "@babel/plugin-transform-react-jsx": "^7.13.12", + "@babel/plugin-transform-react-jsx-development": "^7.12.17", + "@babel/plugin-transform-react-pure-annotations": "^7.12.1" + } + }, + "@babel/preset-typescript": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.12.1.tgz", + "integrity": "sha512-hNK/DhmoJPsksdHuI/RVrcEws7GN5eamhi28JkO52MqIxU8Z0QpmiSOQxZHWOHV7I3P4UjHV97ay4TcamMA6Kw==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.12.1" + } + }, + "@babel/runtime": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs2": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.14.0.tgz", + "integrity": "sha512-btR4E8JiGlmmDI5YgirlG9z3T91rBdxnVh2YuEStrHDcekffaaIeK+CE0S4IaYUyYhMa7rFDfF2GEO79XNbLEA==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz", + "integrity": "sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg==", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz", + "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@csstools/convert-colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", + "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" + }, + "@csstools/normalize.css": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", + "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" + }, + "@eslint/eslintrc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", + "integrity": "sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "requires": { + "type-fest": "^0.8.1" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + } + } + }, + "@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" + }, + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "requires": { + "@hapi/hoek": "^8.3.0" + } + }, + "@hypnosphi/create-react-context": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", + "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", + "requires": { + "gud": "^1.0.0", + "warning": "^4.0.3" + }, + "dependencies": { + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", + "integrity": "sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ==", + "requires": { + "ansi-html": "^0.0.7", + "error-stack-parser": "^2.0.6", + "html-entities": "^1.2.1", + "native-url": "^0.2.6", + "schema-utils": "^2.6.5", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "@rollup/plugin-node-resolve": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", + "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", + "requires": { + "@rollup/pluginutils": "^3.0.8", + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.14.2" + } + }, + "@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + } + } + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@surma/rollup-plugin-off-main-thread": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", + "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", + "requires": { + "ejs": "^2.6.1", + "magic-string": "^0.25.0" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + } + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "requires": { + "@babel/types": "^7.12.6" + } + }, + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "requires": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + } + }, + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + } + }, + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "@testing-library/dom": { + "version": "7.31.2", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", + "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^4.2.2", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.6", + "lz-string": "^1.4.4", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.12.0.tgz", + "integrity": "sha512-N9Y82b2Z3j6wzIoAqajlKVF1Zt7sOH0pPee0sUHXHc5cv2Fdn23r+vpWm0MBBoGJtPOly5+Bdx1lnc3CD+A+ow==", + "requires": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^4.2.2", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "lodash": "^4.17.15", + "redent": "^3.0.0" + } + }, + "@testing-library/react": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.7.tgz", + "integrity": "sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==", + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^7.28.1" + } + }, + "@testing-library/user-event": { + "version": "12.8.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", + "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", + "requires": { + "@babel/runtime": "^7.12.5" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@types/aria-query": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", + "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==" + }, + "@types/babel__core": { + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", + "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", + "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/eslint": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz", + "integrity": "sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", + "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==" + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "requires": { + "@types/node": "*" + } + }, + "@types/html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" + }, + "@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, + "@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" + }, + "@types/node": { + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.0.tgz", + "integrity": "sha512-+aHJvoCsVhO2ZCuT4o5JtcPrCPyDE3+1nvbDprYes+pPkEsbjH7AGUCNtjMOXS0fqH14t+B7yLzaqSz92FPWyw==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/prettier": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + }, + "@types/tapable": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", + "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==" + }, + "@types/testing-library__jest-dom": { + "version": "5.9.5", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.5.tgz", + "integrity": "sha512-ggn3ws+yRbOHog9GxnXiEZ/35Mow6YtPZpd7Z5mKDeZS/o7zx3yAle0ov/wjhVB5QT4N2Dt+GNoGCdqkBGCajQ==", + "requires": { + "@types/jest": "*" + } + }, + "@types/uglify-js": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz", + "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==", + "requires": { + "source-map": "^0.6.1" + } + }, + "@types/webpack": { + "version": "4.41.29", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.29.tgz", + "integrity": "sha512-6pLaORaVNZxiB3FSHbyBiWM7QdazAWda1zvAq4SbZObZqHSDbWLi62iFdblVea6SK9eyBIVp5yHhKt/yNQdR7Q==", + "requires": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + } + }, + "@types/webpack-sources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", + "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "@types/yargs": { + "version": "15.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", + "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz", + "integrity": "sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==", + "requires": { + "@typescript-eslint/experimental-utils": "4.26.0", + "@typescript-eslint/scope-manager": "4.26.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.21", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.0.tgz", + "integrity": "sha512-TH2FO2rdDm7AWfAVRB5RSlbUhWxGVuxPNzGT7W65zVfl8H/WeXTk1e69IrcEVsBslrQSTDKQSaJD89hwKrhdkw==", + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.26.0", + "@typescript-eslint/types": "4.26.0", + "@typescript-eslint/typescript-estree": "4.26.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz", + "integrity": "sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg==", + "requires": { + "@typescript-eslint/scope-manager": "4.26.0", + "@typescript-eslint/types": "4.26.0", + "@typescript-eslint/typescript-estree": "4.26.0", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz", + "integrity": "sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg==", + "requires": { + "@typescript-eslint/types": "4.26.0", + "@typescript-eslint/visitor-keys": "4.26.0" + } + }, + "@typescript-eslint/types": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.0.tgz", + "integrity": "sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A==" + }, + "@typescript-eslint/typescript-estree": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz", + "integrity": "sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg==", + "requires": { + "@typescript-eslint/types": "4.26.0", + "@typescript-eslint/visitor-keys": "4.26.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz", + "integrity": "sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg==", + "requires": { + "@typescript-eslint/types": "4.26.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, + "address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" + }, + "adjust-sourcemap-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", + "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + } + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "axe-core": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.1.tgz", + "integrity": "sha512-evY7DN8qSIbsW2H/TWQ1bX3sXN1d4MNb5Vb4n7BzPuCwRHdkZ1H2eNLuSh73EoQqkGKUtju2G2HCcjCfhvZIAA==" + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "babel-extract-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", + "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", + "requires": { + "babylon": "^6.18.0" + } + }, + "babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, + "babel-plugin-named-asset-import": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz", + "integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==" + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz", + "integrity": "sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.9.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + } + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "requires": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "babel-preset-react-app": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.0.tgz", + "integrity": "sha512-itL2z8v16khpuKutx5IH8UdCdSTuzrOhRFTEdIhveZ2i1iBKDrVE0ATa4sFVy+02GLucZNVBWtoarXBy0Msdpg==", + "requires": { + "@babel/core": "7.12.3", + "@babel/plugin-proposal-class-properties": "7.12.1", + "@babel/plugin-proposal-decorators": "7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "7.12.1", + "@babel/plugin-proposal-numeric-separator": "7.12.1", + "@babel/plugin-proposal-optional-chaining": "7.12.1", + "@babel/plugin-transform-flow-strip-types": "7.12.1", + "@babel/plugin-transform-react-display-name": "7.12.1", + "@babel/plugin-transform-runtime": "7.12.1", + "@babel/preset-env": "7.12.1", + "@babel/preset-react": "7.12.1", + "@babel/preset-typescript": "7.12.1", + "@babel/runtime": "7.12.1", + "babel-plugin-macros": "2.8.0", + "babel-plugin-transform-react-remove-prop-types": "0.4.24" + }, + "dependencies": { + "@babel/plugin-proposal-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz", + "integrity": "sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz", + "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", + "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", + "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", + "requires": { + "@babel/compat-data": "^7.12.1", + "@babel/helper-compilation-targets": "^7.12.1", + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-option": "^7.12.1", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.1", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.1", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.1", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.1", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.12.1", + "core-js-compat": "^3.6.2", + "semver": "^5.5.0" + } + }, + "@babel/preset-react": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.1.tgz", + "integrity": "sha512-euCExymHCi0qB9u5fKw7rvlw7AZSjw/NaB9h7EkdTt5+yHRrXdiRTh7fkG3uBPpJg82CqLfp1LHLqWGSCrab+g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-transform-react-display-name": "^7.12.1", + "@babel/plugin-transform-react-jsx": "^7.12.1", + "@babel/plugin-transform-react-jsx-development": "^7.12.1", + "@babel/plugin-transform-react-jsx-self": "^7.12.1", + "@babel/plugin-transform-react-jsx-source": "^7.12.1", + "@babel/plugin-transform-react-pure-annotations": "^7.12.1" + } + }, + "@babel/runtime": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", + "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "requires": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "optional": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "bootstrap": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", + "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001233", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz", + "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==" + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "requires": { + "rsvp": "^4.8.4" + } + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", + "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" + }, + "check-types": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", + "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==" + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "requires": { + "source-map": "~0.6.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", + "requires": { + "arity-n": "^1.0.4" + } + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==" + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "core-js-compat": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz", + "integrity": "sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==", + "requires": { + "browserslist": "^4.16.6", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, + "core-js-pure": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.13.1.tgz", + "integrity": "sha512-wVlh0IAi2t1iOEh16y4u1TRk6ubd4KvLE8dlMi+3QUI6SfKphQUh7tAwihGGSQ8affxEXpVIPpOdf9kjR4v4Pw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-react-class": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", + "integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==", + "requires": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + }, + "css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "requires": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "css-blank-pseudo": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", + "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", + "requires": { + "postcss": "^7.0.5" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-has-pseudo": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", + "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^5.0.0-rc.4" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "css-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", + "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", + "requires": { + "camelcase": "^6.0.0", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^2.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.3", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.1", + "semver": "^7.3.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "css-prefers-color-scheme": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", + "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", + "requires": { + "postcss": "^7.0.5" + } + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=" + }, + "cssdb": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", + "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + } + } + }, + "cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "damerau-levenshtein": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", + "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-freeze-strict": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-freeze-strict/-/deep-freeze-strict-1.1.1.tgz", + "integrity": "sha1-d9BYPKJKab5LvZrC+uQV1VUj5bA=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + }, + "dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-accessibility-api": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz", + "integrity": "sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw==" + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + } + } + }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" + }, + "electron-to-chromium": { + "version": "1.3.746", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.746.tgz", + "integrity": "sha512-3ffyGODL38apwSsIgXaWnAKNXChsjXhAmBTjbqCbrv1fBbVltuNLWh0zdrQbwK/oxPQ/Gss/kYfFAPPGu9mszQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "requires": { + "stackframe": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.27.0.tgz", + "integrity": "sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA==", + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "eslint-config-react-app": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", + "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", + "requires": { + "confusing-browser-globals": "^1.0.10" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-module-utils": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "requires": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.2.tgz", + "integrity": "sha512-7Oq/N0+3nijBnYWQYzz/Mp/7ZCpwxYvClRyW/PLAmimY9uLCBvoXsNsERcJdkKceyOjgRbFhhxs058KTrne9Mg==", + "requires": { + "lodash": "^4.17.15", + "string-natural-compare": "^3.0.1" + } + }, + "eslint-plugin-import": { + "version": "2.23.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", + "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.1", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.4.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.3", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "eslint-plugin-jest": { + "version": "24.3.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz", + "integrity": "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==", + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", + "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", + "requires": { + "@babel/runtime": "^7.11.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.0.2", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^3.1.0", + "language-tags": "^1.0.5" + }, + "dependencies": { + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + } + } + }, + "eslint-plugin-react": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz", + "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==", + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==" + }, + "eslint-plugin-testing-library": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz", + "integrity": "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==", + "requires": { + "@typescript-eslint/experimental-utils": "^3.10.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz", + "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==", + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/typescript-estree": "3.10.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/types": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz", + "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==" + }, + "@typescript-eslint/typescript-estree": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz", + "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==", + "requires": { + "@typescript-eslint/types": "3.10.1", + "@typescript-eslint/visitor-keys": "3.10.1", + "debug": "^4.1.1", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz", + "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + }, + "eslint-webpack-plugin": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.4.tgz", + "integrity": "sha512-7rYh0m76KyKSDE+B+2PUQrlNS4HJ51t3WKpkJg6vo2jFMbEPTG99cBV0Dm7LXSHucN4WGCG65wQcRiTFrj7iWw==", + "requires": { + "@types/eslint": "^7.2.6", + "arrify": "^2.0.1", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "eventsource": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "requires": { + "bser": "2.1.1" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-loader": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz", + "integrity": "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "filesize": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", + "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" + }, + "flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "fork-ts-checker-webpack-plugin": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", + "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", + "requires": { + "@babel/code-frame": "^7.5.5", + "chalk": "^2.4.1", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "requires": { + "globule": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "optional": true + }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, + "history": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", + "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=", + "requires": { + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "query-string": "^4.2.2", + "warning": "^3.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "requires": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + } + }, + "html-webpack-plugin": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", + "integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==", + "requires": { + "@types/html-minifier-terser": "^5.0.0", + "@types/tapable": "^1.0.5", + "@types/webpack": "^4.41.8", + "html-minifier-terser": "^5.0.1", + "loader-utils": "^1.2.3", + "lodash": "^4.17.15", + "pretty-error": "^2.1.1", + "tapable": "^1.1.3", + "util.promisify": "1.0.0" + }, + "dependencies": { + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + } + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-proxy-middleware": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.0.tgz", + "integrity": "sha512-S+RN5njuyvYV760aiVKnyuTXqUMcSIvYOsHA891DOVQyrdZOwaXtBHpt9FUVPEDAsOvsPArZp6VXQLs44yvkow==", + "requires": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "requires": { + "postcss": "^7.0.14" + } + }, + "identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", + "requires": { + "harmony-reflect": "^1.4.6" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + }, + "immer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/immer/-/immer-2.1.5.tgz", + "integrity": "sha512-xyjQyTBYIeiz6jd02Hg12jV+9QISwF1crLcwTlzHpWH4e0ryNWj1kacpTwimK3bJV5NKKXw458G2vpqoB/inFA==" + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + } + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.6.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz", + "integrity": "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA==", + "requires": { + "@jest/core": "^26.6.0", + "import-local": "^3.0.2", + "jest-cli": "^26.6.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-circus": { + "version": "26.6.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.6.0.tgz", + "integrity": "sha512-L2/Y9szN6FJPWFK8kzWXwfp+FOR7xq0cUL4lIsdbIdwz3Vh6P1nrpcqOleSzr28zOtSHQNV9Z7Tl+KkuK7t5Ng==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.0", + "@jest/test-result": "^26.6.0", + "@jest/types": "^26.6.0", + "@types/babel__traverse": "^7.0.4", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^26.6.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.0", + "jest-matcher-utils": "^26.6.0", + "jest-message-util": "^26.6.0", + "jest-runner": "^26.6.0", + "jest-runtime": "^26.6.0", + "jest-snapshot": "^26.6.0", + "jest-util": "^26.6.0", + "pretty-format": "^26.6.0", + "stack-utils": "^2.0.2", + "throat": "^5.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + } + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + }, + "jest-resolve": { + "version": "26.6.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz", + "integrity": "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ==", + "requires": { + "@jest/types": "^26.6.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + } + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-watch-typeahead": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz", + "integrity": "sha512-ITVnHhj3Jd/QkqQcTqZfRgjfyRhDFM/auzgVo2RKvSwi18YMvh0WvXDJFoFED6c7jd/5jxtu4kSOb9PTu2cPVg==", + "requires": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^26.0.0", + "jest-watcher": "^26.3.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", + "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.5", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz", + "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==" + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "requires": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + } + }, + "keycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==" + }, + "language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==" + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "requires": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "loglevel": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "^2.0.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "^4.0.1" + } + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "requires": { + "mime-db": "1.48.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, + "mini-css-extract-plugin": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", + "integrity": "sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA==", + "requires": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "native-url": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz", + "integrity": "sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA==", + "requires": { + "querystring": "^0.2.0" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, + "node-notifier": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==" + }, + "node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, + "object.fromentries": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + } + } + }, + "optimize-css-assets-webpack-plugin": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz", + "integrity": "sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A==", + "requires": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, + "pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "requires": { + "ts-pnp": "^1.1.6" + } + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-attribute-case-insensitive": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", + "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^6.0.2" + } + }, + "postcss-browser-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", + "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", + "requires": { + "postcss": "^7" + } + }, + "postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "requires": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-color-functional-notation": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", + "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-color-gray": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", + "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-color-hex-alpha": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", + "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", + "requires": { + "postcss": "^7.0.14", + "postcss-values-parser": "^2.0.1" + } + }, + "postcss-color-mod-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", + "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-color-rebeccapurple": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", + "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-custom-media": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", + "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", + "requires": { + "postcss": "^7.0.14" + } + }, + "postcss-custom-properties": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", + "requires": { + "postcss": "^7.0.17", + "postcss-values-parser": "^2.0.1" + } + }, + "postcss-custom-selectors": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", + "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-dir-pseudo-class": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", + "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-double-position-gradients": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", + "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", + "requires": { + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-env-function": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", + "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-flexbugs-fixes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz", + "integrity": "sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==", + "requires": { + "postcss": "^7.0.26" + } + }, + "postcss-focus-visible": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", + "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-focus-within": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", + "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-font-variant": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", + "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-gap-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", + "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-image-set-function": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", + "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-initial": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", + "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-lab-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", + "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", + "requires": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + } + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-logical": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", + "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-media-minmax": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", + "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "requires": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "postcss-nesting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", + "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-normalize": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", + "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", + "requires": { + "@csstools/normalize.css": "^10.1.0", + "browserslist": "^4.6.2", + "postcss": "^7.0.17", + "postcss-browser-comments": "^3.0.0", + "sanitize.css": "^10.0.0" + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-overflow-shorthand": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", + "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-page-break": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", + "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-place": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", + "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", + "requires": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + } + }, + "postcss-preset-env": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", + "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", + "requires": { + "autoprefixer": "^9.6.1", + "browserslist": "^4.6.4", + "caniuse-lite": "^1.0.30000981", + "css-blank-pseudo": "^0.1.4", + "css-has-pseudo": "^0.10.0", + "css-prefers-color-scheme": "^3.1.1", + "cssdb": "^4.4.0", + "postcss": "^7.0.17", + "postcss-attribute-case-insensitive": "^4.0.1", + "postcss-color-functional-notation": "^2.0.1", + "postcss-color-gray": "^5.0.0", + "postcss-color-hex-alpha": "^5.0.3", + "postcss-color-mod-function": "^3.0.3", + "postcss-color-rebeccapurple": "^4.0.1", + "postcss-custom-media": "^7.0.8", + "postcss-custom-properties": "^8.0.11", + "postcss-custom-selectors": "^5.1.2", + "postcss-dir-pseudo-class": "^5.0.0", + "postcss-double-position-gradients": "^1.0.0", + "postcss-env-function": "^2.0.2", + "postcss-focus-visible": "^4.0.0", + "postcss-focus-within": "^3.0.0", + "postcss-font-variant": "^4.0.0", + "postcss-gap-properties": "^2.0.0", + "postcss-image-set-function": "^3.0.1", + "postcss-initial": "^3.0.0", + "postcss-lab-function": "^2.0.1", + "postcss-logical": "^3.0.0", + "postcss-media-minmax": "^4.0.0", + "postcss-nesting": "^7.0.0", + "postcss-overflow-shorthand": "^2.0.0", + "postcss-page-break": "^2.0.0", + "postcss-place": "^4.0.1", + "postcss-pseudo-class-any-link": "^6.0.0", + "postcss-replace-overflow-wrap": "^3.0.0", + "postcss-selector-matches": "^4.0.0", + "postcss-selector-not": "^4.0.0" + } + }, + "postcss-pseudo-class-any-link": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", + "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", + "requires": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-replace-overflow-wrap": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", + "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", + "requires": { + "postcss": "^7.0.2" + } + }, + "postcss-safe-parser": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-5.0.2.tgz", + "integrity": "sha512-jDUfCPJbKOABhwpUKcqCVbbXiloe/QXMcbJ6Iipf3sDIihEzTqRCeMBfRaOHxhBuTYqtASrI1KJWxzztZU4qUQ==", + "requires": { + "postcss": "^8.1.0" + }, + "dependencies": { + "postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "postcss-selector-matches": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", + "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", + "requires": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + } + }, + "postcss-selector-not": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", + "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", + "requires": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + }, + "postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + }, + "pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "requires": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "requires": { + "asap": "~2.0.6" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + } + } + }, + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-app-polyfill": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz", + "integrity": "sha512-0sF4ny9v/B7s6aoehwze9vJNWcmCemAUYBVasscVr92+UYiEqDXOxfKjXN685mDaMRNF3WdhHQs76oTODMocFA==", + "requires": { + "core-js": "^3.6.5", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "whatwg-fetch": "^3.4.1" + }, + "dependencies": { + "core-js": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.13.1.tgz", + "integrity": "sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ==" + } + } + }, + "react-bootstrap": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.4.tgz", + "integrity": "sha512-xj+JfaPOvnvr3ow0aHC7Y3HaBKZNR1mm361hVxVzVX3fcdJNIrfiodbQ0m9nLBpNxiKG6FTU2lq/SbTDYT2vew==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0", + "classnames": "^2.2.5", + "dom-helpers": "^3.2.0", + "invariant": "^2.2.4", + "keycode": "^2.2.0", + "prop-types": "^15.6.1", + "prop-types-extra": "^1.0.1", + "react-overlays": "^0.8.0", + "react-prop-types": "^0.4.0", + "react-transition-group": "^2.0.0", + "uncontrollable": "^5.0.0", + "warning": "^3.0.0" + }, + "dependencies": { + "react-overlays": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", + "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", + "requires": { + "classnames": "^2.2.5", + "dom-helpers": "^3.2.1", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-transition-group": "^2.2.0", + "warning": "^3.0.0" + } + } + } + }, + "react-context-toolbox": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz", + "integrity": "sha512-tY4j0imkYC3n5ZlYSgFkaw7fmlCp3IoQQ6DxpqeNHzcD0hf+6V+/HeJxviLUZ1Rv1Yn3N3xyO2EhkkZwHn0m1A==" + }, + "react-datetime": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-3.0.4.tgz", + "integrity": "sha512-v6MVwCve+DRaLN2f22LTO5TlrPpkUXumPkp1zfrbhaFtSYGl2grZ2JtwJfLxRj/T4ACyePAV4srCR6cMSiQ/Iw==", + "requires": { + "prop-types": "^15.5.7" + } + }, + "react-dev-utils": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", + "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", + "requires": { + "@babel/code-frame": "7.10.4", + "address": "1.1.2", + "browserslist": "4.14.2", + "chalk": "2.4.2", + "cross-spawn": "7.0.3", + "detect-port-alt": "1.1.6", + "escape-string-regexp": "2.0.0", + "filesize": "6.1.0", + "find-up": "4.1.0", + "fork-ts-checker-webpack-plugin": "4.1.6", + "global-modules": "2.0.0", + "globby": "11.0.1", + "gzip-size": "5.1.1", + "immer": "8.0.1", + "is-root": "2.1.0", + "loader-utils": "2.0.0", + "open": "^7.0.2", + "pkg-up": "3.1.0", + "prompts": "2.4.0", + "react-error-overlay": "^6.0.9", + "recursive-readdir": "2.2.2", + "shell-quote": "1.7.2", + "strip-ansi": "6.0.0", + "text-table": "0.2.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "browserslist": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", + "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", + "requires": { + "caniuse-lite": "^1.0.30001125", + "electron-to-chromium": "^1.3.564", + "escalade": "^3.0.2", + "node-releases": "^1.1.61" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "immer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", + "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-error-overlay": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", + "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" + }, + "react-hot-loader": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.0.tgz", + "integrity": "sha512-JrLlvUPqh6wIkrK2hZDfOyq/Uh/WeVEr8nc7hkn2/3Ul0sx1Kr5y4kOGNacNRoj7RhwLNcQ3Udf1KJXrqc0ZtA==", + "requires": { + "fast-levenshtein": "^2.0.6", + "global": "^4.3.0", + "hoist-non-react-statics": "^3.3.0", + "loader-utils": "^1.1.0", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-overlays": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz", + "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==", + "requires": { + "classnames": "^2.2.6", + "dom-helpers": "^3.4.0", + "prop-types": "^15.6.2", + "prop-types-extra": "^1.1.0", + "react-context-toolbox": "^2.0.2", + "react-popper": "^1.3.2", + "uncontrollable": "^6.0.0", + "warning": "^4.0.2" + }, + "dependencies": { + "uncontrollable": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.2.3.tgz", + "integrity": "sha512-VgOAoBU2ptCL2bfTG2Mra0I8i1u6Aq84AFonD5tmCAYSfs3hWvr2Rlw0q2ntoxXTHjcQOmZOh3FKaN+UZVyREQ==", + "requires": { + "@babel/runtime": "^7.4.5", + "invariant": "^2.2.4" + } + }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-popper": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", + "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", + "requires": { + "@babel/runtime": "^7.1.2", + "@hypnosphi/create-react-context": "^0.3.1", + "deep-equal": "^1.1.1", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + }, + "dependencies": { + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-prop-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", + "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", + "requires": { + "warning": "^3.0.0" + } + }, + "react-redux": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.1.tgz", + "integrity": "sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.2" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "react-refresh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", + "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" + }, + "react-router": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.2.6.tgz", + "integrity": "sha512-nlxtQE8B22hb/JxdaslI1tfZacxFU8x8BJryXOnR2RxB4vc01zuHYAHAIgmBkdk1kzXaA25hZxK6KAH/+CXArw==", + "requires": { + "create-react-class": "^15.5.1", + "history": "^3.0.0", + "hoist-non-react-statics": "^3.3.2", + "invariant": "^2.2.1", + "loose-envify": "^1.2.0", + "prop-types": "^15.7.2", + "react-is": "^16.13.0", + "warning": "^3.0.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "react-router-bootstrap": { + "version": "0.23.3", + "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.23.3.tgz", + "integrity": "sha1-lww1xTwExh+2sRDU/2Uafopzsro=", + "requires": { + "prop-types": "^15.5.8" + } + }, + "react-scripts": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", + "integrity": "sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==", + "requires": { + "@babel/core": "7.12.3", + "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", + "@svgr/webpack": "5.5.0", + "@typescript-eslint/eslint-plugin": "^4.5.0", + "@typescript-eslint/parser": "^4.5.0", + "babel-eslint": "^10.1.0", + "babel-jest": "^26.6.0", + "babel-loader": "8.1.0", + "babel-plugin-named-asset-import": "^0.3.7", + "babel-preset-react-app": "^10.0.0", + "bfj": "^7.0.2", + "camelcase": "^6.1.0", + "case-sensitive-paths-webpack-plugin": "2.3.0", + "css-loader": "4.3.0", + "dotenv": "8.2.0", + "dotenv-expand": "5.1.0", + "eslint": "^7.11.0", + "eslint-config-react-app": "^6.0.0", + "eslint-plugin-flowtype": "^5.2.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jest": "^24.1.0", + "eslint-plugin-jsx-a11y": "^6.3.1", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4.2.0", + "eslint-plugin-testing-library": "^3.9.2", + "eslint-webpack-plugin": "^2.5.2", + "file-loader": "6.1.1", + "fs-extra": "^9.0.1", + "fsevents": "^2.1.3", + "html-webpack-plugin": "4.5.0", + "identity-obj-proxy": "3.0.0", + "jest": "26.6.0", + "jest-circus": "26.6.0", + "jest-resolve": "26.6.0", + "jest-watch-typeahead": "0.6.1", + "mini-css-extract-plugin": "0.11.3", + "optimize-css-assets-webpack-plugin": "5.0.4", + "pnp-webpack-plugin": "1.6.4", + "postcss-flexbugs-fixes": "4.2.1", + "postcss-loader": "3.0.0", + "postcss-normalize": "8.0.1", + "postcss-preset-env": "6.7.0", + "postcss-safe-parser": "5.0.2", + "prompts": "2.4.0", + "react-app-polyfill": "^2.0.0", + "react-dev-utils": "^11.0.3", + "react-refresh": "^0.8.3", + "resolve": "1.18.1", + "resolve-url-loader": "^3.1.2", + "sass-loader": "^10.0.5", + "semver": "7.3.2", + "style-loader": "1.3.0", + "terser-webpack-plugin": "4.2.3", + "ts-pnp": "1.2.0", + "url-loader": "4.1.1", + "webpack": "4.44.2", + "webpack-dev-server": "3.11.1", + "webpack-manifest-plugin": "2.2.0", + "workbox-webpack-plugin": "5.1.4" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + } + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "requires": { + "minimatch": "3.0.4" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "redux": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz", + "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-freeze": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/redux-freeze/-/redux-freeze-0.1.7.tgz", + "integrity": "sha512-L+S9pvWW4u7BRqM2nmeOR/ZTU5k/3pWd+0Vq/oH4vliObKzMLBvENkzmicL/eb44gO3C/OX0fov6NHIlDGw8Zg==", + "requires": { + "deep-freeze-strict": "1.1.1" + } + }, + "redux-promise-middleware": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/redux-promise-middleware/-/redux-promise-middleware-6.1.2.tgz", + "integrity": "sha512-ZqZu/nnSzGgwTtNbGoGVontpk7LjTOv0kigtt3CcgXI9gpq+8WlfXTXRZD0WTD5yaohRq0q2nYmJXSTjwXs83Q==" + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" + }, + "regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", + "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", + "requires": { + "css-select": "^2.0.2", + "dom-converter": "^0.2", + "htmlparser2": "^3.10.1", + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" + } + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "resolve-url-loader": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz", + "integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==", + "requires": { + "adjust-sourcemap-loader": "3.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.21", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", + "requires": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + } + } + }, + "rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", + "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", + "requires": { + "@types/estree": "*", + "@types/node": "*", + "acorn": "^7.1.0" + } + }, + "rollup-plugin-babel": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz", + "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-terser": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz", + "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==", + "requires": { + "@babel/code-frame": "^7.5.5", + "jest-worker": "^24.9.0", + "rollup-pluginutils": "^2.8.2", + "serialize-javascript": "^4.0.0", + "terser": "^4.6.2" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "requires": { + "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" + } + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sanitize.css": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", + "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + } + }, + "sass-loader": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.2.0.tgz", + "integrity": "sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw==", + "requires": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "selfsigned": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", + "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", + "requires": { + "node-forge": "^0.10.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "optional": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^3.4.0", + "websocket-driver": "^0.7.4" + } + }, + "sockjs-client": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", + "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", + "requires": { + "debug": "^3.2.6", + "eventsource": "^1.0.7", + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" + }, + "source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "requires": { + "minipass": "^3.1.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } + }, + "stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", + "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", + "requires": { + "babel-extract-comments": "^1.0.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "style-loader": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", + "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.7.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", + "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" + }, + "tempy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", + "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "requires": { + "temp-dir": "^1.0.0", + "type-fest": "^0.3.1", + "unique-string": "^1.0.0" + }, + "dependencies": { + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", + "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", + "requires": { + "cacache": "^15.0.5", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.5.0", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.3.4", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "terser": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", + "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "requires": { + "glob": "^7.1.2" + } + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "ts-pnp": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", + "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "uncontrollable": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz", + "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==", + "requires": { + "invariant": "^2.2.4" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + } + } + }, + "url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "requires": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "url-parse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + }, + "v8-to-istanbul": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" + } + }, + "watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "optional": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "web-vitals": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz", + "integrity": "sha512-PFMKIY+bRSXlMxVAQ+m2aw9c/ioUYfDgrYot0YUa+/xa0sakubWhSDyxAKwzymvXVdF4CZI71g06W+mqhzu6ig==" + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "webpack": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.3.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + } + } + }, + "webpack-dev-server": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", + "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + } + } + }, + "webpack-manifest-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "requires": { + "fs-extra": "^7.0.0", + "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", + "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "workbox-background-sync": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz", + "integrity": "sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-broadcast-update": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz", + "integrity": "sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-build": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-5.1.4.tgz", + "integrity": "sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow==", + "requires": { + "@babel/core": "^7.8.4", + "@babel/preset-env": "^7.8.4", + "@babel/runtime": "^7.8.4", + "@hapi/joi": "^15.1.0", + "@rollup/plugin-node-resolve": "^7.1.1", + "@rollup/plugin-replace": "^2.3.1", + "@surma/rollup-plugin-off-main-thread": "^1.1.1", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.6", + "lodash.template": "^4.5.0", + "pretty-bytes": "^5.3.0", + "rollup": "^1.31.1", + "rollup-plugin-babel": "^4.3.3", + "rollup-plugin-terser": "^5.3.1", + "source-map": "^0.7.3", + "source-map-url": "^0.4.0", + "stringify-object": "^3.3.0", + "strip-comments": "^1.0.2", + "tempy": "^0.3.0", + "upath": "^1.2.0", + "workbox-background-sync": "^5.1.4", + "workbox-broadcast-update": "^5.1.4", + "workbox-cacheable-response": "^5.1.4", + "workbox-core": "^5.1.4", + "workbox-expiration": "^5.1.4", + "workbox-google-analytics": "^5.1.4", + "workbox-navigation-preload": "^5.1.4", + "workbox-precaching": "^5.1.4", + "workbox-range-requests": "^5.1.4", + "workbox-routing": "^5.1.4", + "workbox-strategies": "^5.1.4", + "workbox-streams": "^5.1.4", + "workbox-sw": "^5.1.4", + "workbox-window": "^5.1.4" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "workbox-cacheable-response": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz", + "integrity": "sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-core": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.4.tgz", + "integrity": "sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg==" + }, + "workbox-expiration": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.1.4.tgz", + "integrity": "sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-google-analytics": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz", + "integrity": "sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA==", + "requires": { + "workbox-background-sync": "^5.1.4", + "workbox-core": "^5.1.4", + "workbox-routing": "^5.1.4", + "workbox-strategies": "^5.1.4" + } + }, + "workbox-navigation-preload": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz", + "integrity": "sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-precaching": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.1.4.tgz", + "integrity": "sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-range-requests": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz", + "integrity": "sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-routing": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.4.tgz", + "integrity": "sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "workbox-strategies": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.4.tgz", + "integrity": "sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA==", + "requires": { + "workbox-core": "^5.1.4", + "workbox-routing": "^5.1.4" + } + }, + "workbox-streams": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.1.4.tgz", + "integrity": "sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw==", + "requires": { + "workbox-core": "^5.1.4", + "workbox-routing": "^5.1.4" + } + }, + "workbox-sw": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.1.4.tgz", + "integrity": "sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA==" + }, + "workbox-webpack-plugin": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.4.tgz", + "integrity": "sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ==", + "requires": { + "@babel/runtime": "^7.5.5", + "fast-json-stable-stringify": "^2.0.0", + "source-map-url": "^0.4.0", + "upath": "^1.1.2", + "webpack-sources": "^1.3.0", + "workbox-build": "^5.1.4" + } + }, + "workbox-window": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.1.4.tgz", + "integrity": "sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw==", + "requires": { + "workbox-core": "^5.1.4" + } + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "requires": { + "errno": "~0.1.7" + } + }, + "worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "requires": { + "microevent.ts": "~0.1.1" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + } + } +} diff --git a/client2/package.json b/client2/package.json new file mode 100644 index 000000000..a9a73b827 --- /dev/null +++ b/client2/package.json @@ -0,0 +1,61 @@ +{ + "name": "client2", + "version": "0.1.0", + "private": true, + "dependencies": { + "@testing-library/jest-dom": "^5.12.0", + "@testing-library/react": "^11.2.7", + "@testing-library/user-event": "^12.8.3", + "bluebird": "^3.5.2", + "bootstrap": "^3.4.1", + "classnames": "^2.2.6", + "http-proxy-middleware": "^2.0.0", + "immer": "^2.1.3", + "lodash": "^4.17.21", + "moment": "^2.22.2", + "node-sass": "^4.14.1", + "react": "^17.0.2", + "react-bootstrap": "^0.32.4", + "react-datetime": "^3.0.4", + "react-dom": "^16.8.4", + "react-hot-loader": "^4.8.0", + "react-overlays": "^1.2.0", + "react-redux": "^6.0.1", + "react-router": "^3.2.1", + "react-router-bootstrap": "^0.23.3", + "react-scripts": "4.0.3", + "redux": "^4.0.1", + "redux-freeze": "^0.1.7", + "redux-promise-middleware": "^6.0.1", + "redux-thunk": "^2.3.0", + "reselect": "^4.0.0", + "web-vitals": "^1.1.2" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "eslintIgnore": [ + "gov3.scss" + ], + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/client2/public/favicon.ico b/client2/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 zcma);c{J4h9>;%nil|2-o+rCuEF-(I%-F}ijC~o(k~HKAkr0)!FCj~d>`RtpD?8b; zXOC1OD!V*IsqUwzbMF1)-gEDD=A573Z-&G7^LoAC9|WO7Xc0Cx1g^Zu0u_SjAPB3vGa^W|sj)80f#V0@M_CAZTIO(t--xg= z!sii`1giyH7EKL_+Wi0ab<)&E_0KD!3Rp2^HNB*K2@PHCs4PWSA32*-^7d{9nH2_E zmC{C*N*)(vEF1_aMamw2A{ZH5aIDqiabnFdJ|y0%aS|64E$`s2ccV~3lR!u<){eS` z#^Mx6o(iP1Ix%4dv`t@!&Za-K@mTm#vadc{0aWDV*_%EiGK7qMC_(`exc>-$Gb9~W!w_^{*pYRm~G zBN{nA;cm^w$VWg1O^^<6vY`1XCD|s_zv*g*5&V#wv&s#h$xlUilPe4U@I&UXZbL z0)%9Uj&@yd03n;!7do+bfixH^FeZ-Ema}s;DQX2gY+7g0s(9;`8GyvPY1*vxiF&|w z>!vA~GA<~JUqH}d;DfBSi^IT*#lrzXl$fNpq0_T1tA+`A$1?(gLb?e#0>UELvljtQ zK+*74m0jn&)5yk8mLBv;=@}c{t0ztT<v;Avck$S6D`Z)^c0(jiwKhQsn|LDRY&w(Fmi91I7H6S;b0XM{e zXp0~(T@k_r-!jkLwd1_Vre^v$G4|kh4}=Gi?$AaJ)3I+^m|Zyj#*?Kp@w(lQdJZf4 z#|IJW5z+S^e9@(6hW6N~{pj8|NO*>1)E=%?nNUAkmv~OY&ZV;m-%?pQ_11)hAr0oAwILrlsGawpxx4D43J&K=n+p3WLnlDsQ$b(9+4 z?mO^hmV^F8MV{4Lx>(Q=aHhQ1){0d*(e&s%G=i5rq3;t{JC zmgbn5Nkl)t@fPH$v;af26lyhH!k+#}_&aBK4baYPbZy$5aFx4}ka&qxl z$=Rh$W;U)>-=S-0=?7FH9dUAd2(q#4TCAHky!$^~;Dz^j|8_wuKc*YzfdAht@Q&ror?91Dm!N03=4=O!a)I*0q~p0g$Fm$pmr$ zb;wD;STDIi$@M%y1>p&_>%?UP($15gou_ue1u0!4(%81;qcIW8NyxFEvXpiJ|H4wz z*mFT(qVx1FKufG11hByuX%lPk4t#WZ{>8ka2efjY`~;AL6vWyQKpJun2nRiZYDij$ zP>4jQXPaP$UC$yIVgGa)jDV;F0l^n(V=HMRB5)20V7&r$jmk{UUIe zVjKroK}JAbD>B`2cwNQ&GDLx8{pg`7hbA~grk|W6LgiZ`8y`{Iq0i>t!3p2}MS6S+ zO_ruKyAElt)rdS>CtF7j{&6rP-#c=7evGMt7B6`7HG|-(WL`bDUAjyn+k$mx$CH;q2Dz4x;cPP$hW=`pFfLO)!jaCL@V2+F)So3}vg|%O*^T1j>C2lx zsURO-zIJC$^$g2byVbRIo^w>UxK}74^TqUiRR#7s_X$e)$6iYG1(PcW7un-va-S&u zHk9-6Zn&>T==A)lM^D~bk{&rFzCi35>UR!ZjQkdSiNX*-;l4z9j*7|q`TBl~Au`5& z+c)*8?#-tgUR$Zd%Q3bs96w6k7q@#tUn`5rj+r@_sAVVLqco|6O{ILX&U-&-cbVa3 zY?ngHR@%l{;`ri%H*0EhBWrGjv!LE4db?HEWb5mu*t@{kv|XwK8?npOshmzf=vZA@ zVSN9sL~!sn?r(AK)Q7Jk2(|M67Uy3I{eRy z_l&Y@A>;vjkWN5I2xvFFTLX0i+`{qz7C_@bo`ZUzDugfq4+>a3?1v%)O+YTd6@Ul7 zAfLfm=nhZ`)P~&v90$&UcF+yXm9sq!qCx3^9gzIcO|Y(js^Fj)Rvq>nQAHI92ap=P z10A4@prk+AGWCb`2)dQYFuR$|H6iDE8p}9a?#nV2}LBCoCf(Xi2@szia7#gY>b|l!-U`c}@ zLdhvQjc!BdLJvYvzzzngnw51yRYCqh4}$oRCy-z|v3Hc*d|?^Wj=l~18*E~*cR_kU z{XsxM1i{V*4GujHQ3DBpl2w4FgFR48Nma@HPgnyKoIEY-MqmMeY=I<%oG~l!f<+FN z1ZY^;10j4M4#HYXP zw5eJpA_y(>uLQ~OucgxDLuf}fVs272FaMxhn4xnDGIyLXnw>Xsd^J8XhcWIwIoQ9} z%FoSJTAGW(SRGwJwb=@pY7r$uQRK3Zd~XbxU)ts!4XsJrCycrWSI?e!IqwqIR8+Jh zlRjZ`UO1I!BtJR_2~7AbkbSm%XQqxEPkz6BTGWx8e}nQ=w7bZ|eVP4?*Tb!$(R)iC z9)&%bS*u(lXqzitAN)Oo=&Ytn>%Hzjc<5liuPi>zC_nw;Z0AE3Y$Jao_Q90R-gl~5 z_xAb2J%eArrC1CN4G$}-zVvCqF1;H;abAu6G*+PDHSYFx@Tdbfox*uEd3}BUyYY-l zTfEsOqsi#f9^FoLO;ChK<554qkri&Av~SIM*{fEYRE?vH7pTAOmu2pz3X?Wn*!ROX ztd54huAk&mFBemMooL33RV-*1f0Q3_(7hl$<#*|WF9P!;r;4_+X~k~uKEqdzZ$5Al zV63XN@)j$FN#cCD;ek1R#l zv%pGrhB~KWgoCj%GT?%{@@o(AJGt*PG#l3i>lhmb_twKH^EYvacVY-6bsCl5*^~L0 zonm@lk2UvvTKr2RS%}T>^~EYqdL1q4nD%0n&Xqr^cK^`J5W;lRRB^R-O8b&HENO||mo0xaD+S=I8RTlIfVgqN@SXDr2&-)we--K7w= zJVU8?Z+7k9dy;s;^gDkQa`0nz6N{T?(A&Iz)2!DEecLyRa&FI!id#5Z7B*O2=PsR0 zEvc|8{NS^)!d)MDX(97Xw}m&kEO@5jqRaDZ!+%`wYOI<23q|&js`&o4xvjP7D_xv@ z5hEwpsp{HezI9!~6O{~)lLR@oF7?J7i>1|5a~UuoN=q&6N}EJPV_GD`&M*v8Y`^2j zKII*d_@Fi$+i*YEW+Hbzn{iQk~yP z>7N{S4)r*!NwQ`(qcN#8SRQsNK6>{)X12nbF`*7#ecO7I)Q$uZsV+xS4E7aUn+U(K baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/client2/public/images/blueline.png b/client2/public/images/blueline.png new file mode 100644 index 0000000000000000000000000000000000000000..cb01efb3ec6ddf7781be3f82c83ee0d5dc0f6b81 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61SFYwH*Nw_oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J`1m?9Cx9{-)^9gY-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSo9FbnKx9mKhQOj4NvxlIAdaUU=Gk5~R`7)z4*}Q$iB}nqelJ literal 0 HcmV?d00001 diff --git a/client2/public/images/gov/bceid_logo.png b/client2/public/images/gov/bceid_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea1cd2fe326fba142851d10db433b558e077aa5 GIT binary patch literal 2637 zcmV-T3bOTyP)d0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU*?@2^KRCwC#S_^PgeskK^5fxfV%Gf=U$juZq0 zNnQ!*qyZ7Gz|IhoJ`x~Zd(uZ{N zQO*#WOA%u7Uh;qJgEd{ zD2uz0aS4POU<7f!gb|T@8A(P9qn5FYv6Zot(b>=OM=)kHE@n()lwu4M^9V6~81ogz z9>%{JTX5`1spK&_xVoA;TWiVi1^N(NfDC9kjL!LOAdJ62ATmw@f{QYyGUhQZP|yF1QSJ8fw)*wdu?)!|-;yIsq*Z!{31yEnWp@Q8^}5h4UK5UABA1FdkyeRT^{|qL4HhSdkvy9JUKEpBQan#wOXmDxrkKe1TFUQMZHL2KYH37Rvjmq|Xz zxE04s88(*CmbBy+>~b~l;%~&+xXqfp=FsbP&6V@`#d#m z`KB8$j(V75n@!mbk86{6-^5s?uF3JwvJqUn$H63F*ssprQnN21rV#@1q5&jS%MmL+ zdYmT3YpLzfX7c$%PS2fy$y(^S2F(K3ls+1>eunR-ZvDjTwbzTBMV_U zk$9yas`HyMUr&PbIzlQZ}?}4t4ua*cjCoB1dMy^Ph~I zLUrE6)%y-934+mSC%VRd8g-sUb9KYSi{RV}!eZ1e27>$zHl`5L=*jAQ>jx&ZK%q`Z zPDj0ES^6@@?GE!_qV5s;v1xW4@Q2FCA1*)9f~&XjYodDY0@mjbWN#`G9 z%wW9a@a$=}G2R(mq21ptwC?aDZL_B&#mD)77`NCIa1yLhXTh8h7&T^Rg7PZQ;dd4f zh0c~PKf=2E;-yz9i~bziV1>|BOBjurRGK0#&sN#aj}6v}V!Ixp*zQM}!9`kV0mQK} zst&tFjhllEtwz`hEH1zC2V~l63=VGVexVn1Izup!@_fv?vPicGPBf z+G1FdLt>E?C6DZ;4u;ipl;5_)TPgnLij2^D)@!#h&b8H!o1t)XP=;8+>kSC`39CL! zaWd-9JG&$Rs8~!{Bl%9Ir^@6eU=*YHv z$p{3jgyb@9sA!F?fvfL5wu-f}+btM>6%8>OZSx?p!K&jdEm&r=swp_$VPo2i!CFx! z^DC6ErUdsKRewuO`7LC=eI`UH&LksMm$J2uA4)=#_K()sm*C|FO>jcnZSl-{;sW_~Yt0 zKn@MlevrH;8XhfGicz90+@gJ1xnqu#@%<~)+ZcureF5tflCR@`{vZSwQpKU9u>ZAX zrFzh7(2g1iNt5}n68n6?q9}8`)b@WYSE8#mmHMzgsPvCAo@yn^g@ zsSfgHN1RH|e1Hlk&9~qGTgq&;i({>(@=yg(1o1T1=9Ed8Qwapqu4=JDTo=Qz_M;@I zdy9i~c3!5;4!LI?x=nowE*BF@Iy5(PZEm%loOgfqm&%}}AEE9IxG6BM0rlX1duG+q z{2C?d)?@!6>C`a^kDATaR_PSu{b01|;MPL00*qm8$H?OjZ8yPvNGB2fUw{DszM#8l+K$(900000NkvXXu0mjfpz{(m literal 0 HcmV?d00001 diff --git a/client2/public/images/gov/favicon.png b/client2/public/images/gov/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bc4b5a97e8eff63c1c5e86239902157cc0d2acdd GIT binary patch literal 11639 zcmeHtXH-+&wl<;n-cbwz6i^5yl!O*~k=~IafrJn`geHhmrHC{UP^9+X*c-3=Plno-?`rz@;-QYG|?C%GcPl3Ets8~ix2|oW{VQ? zb8*L^@$h8i{oE0DPAD&+Eeefsl?83Jc7T8wq%6o(Tw7S%T?yrYQTO*m8T#uO+4(!! zL6IPNIdU047>>XN<%IzHxj4IGVScipU%W8f{Y5tz1pEc@a*_p^Y3l)%+&oc0h!8|b zSWv|e<0A@^BL~WOBJE)Y%BsIp;99aE2QM#o7#Qs9>nr3dCgkRc28%$UP_VElSX5LH zhY-ZxarHv@3A$prFDQQFP)1?xJTdNG7&lko1t-GR&D%>B1j3C2e<#O{+Nt>AI)8U? z(f&n`^+JL*a197|cF)V^J4fzv6aA+JkXH z{qp=*8#N7Wy+3R&WJF_J+<#eIp#O?Q+WmoZ_x5!Dg+bbZQO+nATp(B+v&i4@UKsm7 z7wB*ExfuCxf#BTz!T&e(KlJ()%P(DF%5HYv7fv;lWkDD5!jNuu7$of1t+cH z5JcKaK?NZQdl5mXm^egG0)m7<5fF%&gsAObs5D%$UI&C^8|q=j+y z_WN_d2;+h>^g>*SCL#`j3PT{GqGBRaVv=Gae}YU*LxUvP>D3rYPNK-$4nafAq5 zu3=mdXcXAp75!`AVpU+cx!`m~T$Bcm_*Xw}DljEa6vE5R)5y)uSr&8=D)55wS49D3 zeyi8mss95f^INv6<80kL@BGETA=H)|y~_dB?nb@0;lb^Vv_{|WFn1}%&o$`$MOuR{MT!4{x6oGe7HpeQTrM|7;;6;L;0+v%Td#*`t%Q!26?zrY9#6htos1m1i_ND$14v zPG?Vd*9ek3wua=}x10mtV!i}-4+YDM4W}Rc46r(;PWrlhx_$cTU~5_R%mwUJIf_@-OE zH-CKZrybw($}be(GHv$*<&)&wGVje?JwvF@eMmpwe&~>W{N?Gj9cMzxmSb6mUDe@(n!;+Y}PJTW`6-ML)>l`4JJu@$R_2+cp}S z;cz$3>XgU0*qU@j=qbT3|ucMc=|xJ@P2c2SlIC+%$=RU+nbFoI~}|d30=G0pUq~s z_rzY^m@{?BPg#ED{TjV2Ury(Ip9HA3_t|&iiCtlfT{!lb@n* zI9NY^tDHRd0dK!a*)#K6*WCPM3rxMaQ+eZvoi5yLwLWdF{7{Zq@-n6D(f(|-i2ZZS zlDU1l#MCM~>5du}lERlfhZ;kPq}r&!HtN$h!Q zV@J;oz>~}W;$|CHh@y5zB^+ye^Cd1?E_y8;amxY!^ zP3^fGfV_wi)4VEW?J4-E;^oho+}lpWC4&uxt#}hw!$wnh(l4)aFnlaG?LsUi7v(J( zvej0$nx;t>1QhL=y%q1cD$X|WB<;(TLvVd|e$)J1GXJgXx%xKa#csJ1ob1EsAM1&e zQibK(3U01CeE6NrD|GIL7!Cu;`v;d{LoLJS?++PkU(b=+O4sf?Y1z2&u~JU-)MlPg zEkxUib(xjyYKk(2aM=rT%hmyDjgeid$tS%!zCu z2MS<(xMpO}v|Qzt$ArrsL16nTrHa!6Wk}K3$vk!Q#+=>_v54BnL$q@f^(R=o+?qXo z2T{+ggdtvCLC53fAtgYb!E#QvD;Ef1LW1N_hx$)=9XwSK0PP(ZnH8fAO{(?H1~zL% zckw6Cx(_JJB!VOce{?YU7fKmhR}@M zI+((B;h6B^o}mO;P~q*|HX*W3nO#|4Fm$zV*U^OT>xbeJ`@St~#vU z>#+~vCEOjTF)O6#e#}|wEkf_abS6hJ17$giD?*|*Je~l69^G9~m)hM1s^S4Hx}SmH zR^;4<@W~bS(`aE}BlCw+hJx8jL12T80;t8P_EnE;X=0TIwwHYAp`2H*ikKEXssSW% zscUxA-?%U18$BL`u5dr%tKRB#PB2>S%q%~`K8|jNkjgw~AQ?!}8NA-w=^rbuSy}h) z)^3A`ML7T9P=bwxzSj1c#3w2nF%vbZhYJ(WXhcI)jFWhL3zVWWBXw&y z(QGLPH$9aET9KvkH=eW=8JV@@-2RF1cBl}L06?+wWC~n&`tW`{Pv@Ri@UQ&DIx3ky za+L0S-RaHvRRs-YiLJ+I!cUV9^>yB^dVX}*`ll+q#v6#xcLuF_V>!7--ghUKww(3;1Rp#Ubi(P+nwa4KAy*% zmb7(STCtGC#i$jod#(}apV`;ABn_{edF<2cSwngy~ROchfgjU?H8)88Z+Ma zaLN+ImwB{V##n$+B&DF&7BkWWsIUNl0>r}jgQ*d~72>cf_4Lf6cqE@(6jNQwHMAj) zmUSi*g$ypE5o$+YieGvU$DSz%wRy0SR}^g)%T%l5>B+vPkrX!r8<}L#)lsdI*pIP- z3}_57?Wdz)tJ!ui^LBwche&VBXF)n@c+PMxg-KcT`&SVYQSmdo-Ne*lH=VAdp(Dz& zz&kX~P&O z*EHd*{!Ti`>dbj!@jW5S`wjq2NoDp|Pa?Ncz2H`1nlpL`zBw`eBmh>#$0R=uIJGC{ zx%W}tj5goyZk<&y;L)v7WkiY$n|0@tfRE9>w+BA~LL_H3cO1z*wzN*)>N+h;lW|2; zaXhZb?#%Jb7@rE2yS>ked_8bk7+{OK+C{&6ixy$nHcm`Y;GuARmVNaZLp%vnN^rrN z_(G33{5=tIU#IUX5sL!dp8n2f=w&A0h$Ns-*eiG~=3%5C>Y3`PWH zm+l=}TSD7<7nvBF>rzdv;lk@g3h9}{+!5}a3v|K76;35dPrCEsb8_DUYN%~Qc$4sb zD4x2r^f6@;v&L7C9mZ9Ivtp?^t;q}S_T%xSQ^V~P)ErNy=fd*oZQFn~w~{~U?QA%Y zX9G0SPxOJLBK{flua-(jt+L=85Otm`=Fqg2Sjr#*pU97{SNK#^RpOsnmwNiohC^2ne8$=r>|S_7BrQvvw!)LGd!2b z=w*1_)t`~f5ud5Yz=Z7Gxs0oy6spOtt#|1Gpn4zb{S z>@I_(%`qa>WUAF=QEUDWc-mq^)LtxD&!XWDYJ9djeJ09Vil4>$bVtn>#BW?OhgXQ$ zR8-yY{xWRZ1<%diBJh4eSwu1J1v2}bi#Wk|iEU9%<$;h_1#873<3}H;XtHz)iEY&1 z6SxBPSTwu7X2)v-_UNYzdo?w$x2>wS08(FF2=&N{O5PVLQ`S~~mC0oNpX-_OFFJJ^3n`~8LfsDZ#|r((Qk`T@uC2mrXDNr=Q0&p#&E_4=OG!c2Mox+ z;VT=|DvU5mK@!=D(`nc9+-jJwK?m(El5gnj9+)LM8f3!n5(F!d!TSu4t0H2h%;^cM z%~`~T*w~G$D1NZr*#8<4AMaOweJ&YAQq$?Y$MuS!bYYq}wOfdzi%AE@XAqLazA;DM zMt$yOzKedpDYUW@ZKu*YJO$AzN~3ixCgXPJw;#%>8jXZgzOge>W6}PmSHa$}fv?ip z3d+!U^cg>v*dTy-cQpFxP!|pB<`u?RlZ~;@yv4Kkg6S=adiF|N6pe|Mi@21U8qHKA z3;{1JQ|-q)8)Uw$66Ce?(kIMaBg2e!EFnUYhmil{Ne4=C8WD^yaiqYyf=StkU7&_)vt=wca#yO zTe!PVpB-qUws>i74UVkuCmiv&)zt9d8fdI~H7jT(z^Clw-E=>qfz5g`bvyU6%C7zb zgVj!)&kv0E77Gz!OXnx13Vhf5MSXYFY*q1ptz+!ILmY^29{$e=cuj3B6gB=>{-OV zfvTK-U*Prb4ySVhg6mBu?TBsDErCD)_4u>y*2p>Y$*ydZI<}>&!{tM-1FLVsoIoS+ zFxS3vylskR#YBcj9ChVd37huq2KJFM>D;f`A~>!*nigL8e8V7BOvUnMZ^l*FBqCJg zVW)gHGaLRlrHLFMMon2?lQq2dc}xE~lhfVP_Q?HuErIXO4xIipePZN;qB&x~iB+dp zsB)At|4C4>Y8dFKIdlw{v7b#ytJ{|G;QY!nU z8#UyPN&~Ybl7f|5c#RxAz1v}=mjSia$2B{?_k0qo6ebcp;Fr8M?%I(_$}v??d<$dL z)zasn|5{ZsjcQ7I&$~}YcaH=fo}-#9ID2S-;#9WKjbmfU9X~P`%;%p&u{TWT$`E1n|jedUYFBs>T)qi=}z#F zhjI*cPS;fdBK5G2Xxhu#^H>mANjeMcPoVU^6ByT?|Gg~dejK4rCogp3n|#V3@8$MR zQKbhAYx=X)-hvN_i^2$RP$&j>h(wNGe<*8V9JG@gqPLb}O|Nbmq8&b48b9G@%K#C5 z){w+fr2dp^!Vo5+K61%a{)G=gxZOd zOMPG&*hr44dd{5IT`j8Z;sGu;#o@(dgzx#l<`Llxo_b_)!hS0E%j`qlLw%B?VYC6K-*{bJucsFrSSUO7zJ+BZ z21wyZ<2Qt4r2-7!aiF|*QbA_2Jzo`aHMc;WIwSwZj5SX!hz*Kyi!XiSSOc|z&cWcX z+98P6R%>Mso8kQs_NKFlMG_}V@OSBz-BE=9d_QgD5p8V|Y?~jW|KLDK zCooqmG5dv>tR{d>D6EW2Xne7Kau{$`YDBukgg8Y}zZWn+jEaL#Bxy=>x8b=>A2^Uy z$J@E)X&G5csjA9qa05@hHWY@wb6ds4?UR$Ld>Kw&A%Rd-buL_Qd04PdJ2sml_qfho zeZ*ELVc#j#`WmGb$q)>EzD<9V7l!7B7lSFj9g zQF1Vsb)aN3g6F%bE!_qK-Co#k$T^~&R*@dQ<=ccV7xWv(d)`$6dU0uQIN6S={s|9AvlBfY7Qc8|fxGDiCkV!1>Pj*)!~PS% z7RF`1#4|PQnJ`e)4Nd^dvzqRtQiR^EV+k5a6`=TJweSK@@mME6dZ2XdB_5H&VzGKM z$)Mhk%LUM!>&e>wrKG*COuHz-7^1!lGg3Ro6j;)^s;mSV`QHED0-$vj z%ca+?)lgFylIGF~)&4*MS3Xis*%~kF5{7XVX4V}uOKgYNXvXPQX>FRF913QM5`yyZTZE&8|(`6s^YOU-u}(g7^c?mw>0aeMC!m3w7pk z+%MFVHRxXI^v5;`RTv^Q{0+|Uz#rNx1>oK5my|_9k~1C+D;O4WTU)B+lY+=v;)-5oEQZNUo9e`;{xgBkJ5Z>3n0&L2~md$ z>M(DK*iMUKi z%>`~I&{>rh!dGdhqJ;ovg-4h3%4Z{=;_?b?OAXS#$SfcnvgUjMb4Gnh#!$ zM4RgBueRQfY=8pweyZqR$Fu#Auu9WS(RcMbky_t1+h^IU>u+y169eOioJ@(g^7n|7 zZfAv>4MYGv;v>Q2DrxW9=LbgeXTvxHM_vlYbhxbPze1RE>^Cfg{@0o5g(&k2MP_8GedYA`e2$qPjeBQm|m?U_-494)3IUI#tOo{R)Cy1n?P z122~gtY5ZSR@UA~H?l^K)Sptz9b-<%P#imfROzzD-94n_d*q|kJSWrFM)H79Bn&^y zP%;Xb2nOY4+#`(?TCL!l@g$Ld9>pm~ffbg^R>DN*V=DV%Tnp^nwm*u zatP-Z_sjgXYy(O>|I7BwF>qj1hebq72uHxTfNMu04o)AqiW@iu$6dR=t)k`@#jkAw zUN}~sW#hnunXM+%gN zH$D+{bJ?|(0zEO~fuXi$Lw6Ty*^swJ8;8!C+(A4sC9zC+`LB|``Pp8wh#Ztr8L~`cR2W`Y}0%_KVsZ>6Mg=l1cEXG>qg%BEilKcrg z)U}D=EE~6H2g#3K5>8sb{rFq|;@o{zkcn)9ig@mm^um{9Ux)D^%V!cG7pywM1Pxlu zzCsXir71x)i5;j^yVPiP_5D%-r835dIvbyF-TQj4bw@GY0BqtYj1+na z;6sXWFH%u6RW#fW`f2$M)NK+XavDe3zTa32wgkMaN>t%+Xc}V{i$BA=EdMpr_Be%q z9o%t#4nHpr9!{?Lx_KYaSURH|>aJ*qdx2G6Ps>Q<{QUgr`_|d?FQ#Dh``R&(WAE?SAFBNxTS=YZ!&UONDg~E(c;cj=hl582Ylo3(7H#*`2h8g6~6GaWgj)KSIL4!O~tW|g9dDOtOV5)^@i!k#bp%@(tlD1iC*TPbe1cn z)XE%_L#0o0;^{gqZfX>-kEIpru8DOv$+#^ubfS-0;O7CI@7@8tJy9-g&lEC!lffZL zA2|Bz>o2|3Y8$0?gM5%2SDJPCIAJ3Hd9J>kqc8GFP0rTX)D@-4H1n-`9r^Ee*S=GL X8-R7U>Gn=9UX9jJ(NV5Yv$_7|bA(B{M@2j>Z&aYmC7#n=#DToZlbk_dd_(dG7nZKHu+keXr%8JIvJNg5W;!eSCa;f(92+ zXx{U5P-CoQlOolb>AAPfdWkpWet&>SJk8X6i9B^8K@iUJRz;O0rDW0?wM zH<_OvPnih^?|;mLFZlopt0 zQM4!6!%?al8Ze|1456+9RaVwh)rCS~NEH=*6&OMdg@P*oY@4244c**#My3Z3HSM4^I^NRXU4foxAF1X`v({L|8gNbF_7VPtPZJj|jBqQc?NBql3Ve!c z=p5J!CvL9|=iF7`gF2kK5)^mKfIU3*VQ^x$`1JM)due4I7nrPK83gotamz&#^4|g< zJ%GM|o~(1+S7N|$0*Pv}ON{_@5dd~jT`Fpm^Nm}tUD^B*n5(DW&YYN81m2l8_k7ys zEFHh(WnhWs)+z(b-Jiy00G6*IIr(%M`Wnl2mSfNT=?=Ub`(!m}b8lM9?>@{%@mRHxmu5ECuPj75;xRughU!Dj}dYM)6 z!P@T$&}QKiSCCuvzN2r_`Bu6aJ(K&+IIXmq`vwM#r9aAfqw92M<<*&6eiy=%%YgUR zsU_XOXv*01!uG~wO>19rQ9ZXocbmJ3^UnZgYgMgd-n?gD^UCACmgP3;c|_%yGaq-i zm1f7FfNs+4;>z|yOL%evFp>LdY#}P+wIJNi+R&7Ax~dFxbRU6L^Hu=UHYYac0Z z9OTw0?pCwsRGt(;d0rx?9Ya`q$5sO!cE>LTP$J62FZiI{(?xY`4`@*g$r;=-;my*+ zYa3ewqtgpt*V9LzRq*QJDbr(LqJvjy_ zT?~^w`^eYAtXHgtAHk{xT|_9snuQJp+JW_q#Zetipj2oY78guj6PY zc+Y#cYppZdIj)~1c8v{-)b8s4=RH!S+M3|Q8Sj$Hx#l)xyI&jNY2D#cd1(D zj}4X@)3$N1D*8+Y(=j=vrD~Am6$L{}%lds{X-u>W+VLZLYtCS_q0~jnQYQP&7nRG- z`f3Fxh6M4EYiV7Fp%rI0C(H6B2OBN~z`NhwL*HwY6Lm}UJQ;K4UH@i9W5dlHEL#(p z!ej_X;ER7xsT^{r z=W55P8R7ew=<}If>8K{z$-vFFT>jc20eNZ4+9N;HSb;KD_xxOm|FzPP-LIXkOCq|m z6j9A8@&rGvIYYzzPERc6wR|fx$dGD{N1Nx_*(#mgaRTT4+wae`IP}&O(>s3rxyc~Q zYNz4(vkXR~=fvh+IbX?)hsI5ST-)YrFgUNrC3W$B&~(Y5UTWW66SEB1x_mt4G8>~; zaX{eDAcu>~sWW$AMuwxm{1Q9qdsO&U>lZt>?k*gzAPsrER8}eWUhmWRDM`?&6vp01 z@9Dj+t$5769Y;a-A=8JXuTPH7+wLjY@sT6}k4`ylmYJPWctyzBD)v4Csv?`&KT0SL z6Q_+IPsSS`&208nU4)go9|*K^2c5(cjm(iv1k63ujrGIQaRM70 zVd(&4hBBnR*ZMN+w#xN*y|yB?gI$xf$5Ge4_gjtMDpzwhNhvmxFO5~sc-9}7pC~dL zX(s#5m*`!dA$x9PMpI%bKeop02}fSj=*-UiM0ic`kfmXwVyixZF02sAOd_}6L)Fn_ zh_@q~n)1TmKa;2{EPSD;ZRIH7Fk{6eL*5?t>Qk%fukB-h9h&W_U_IGiv$o?BapP2& zdWhJwp5n~j1EyL>gg*W$y|c9+YZ_OaI4&V1Kq7kURi~PX2eRoNr)KSmV8IhF?+p=8 zp!lC^y)8&I(J$YT+IO<~Y)n=G!5V+@x=AXu>zy>eX7s-JeD7m zbo-jTha8BG9g#Lt5rUNb^SM6E!L18L#@V^`FZ8qDKD3FCQF9zn(M8E`T!IlZR*RzF zJuvMPQAB3Qt@%RbEaA_Y@oT#CEaLC5yvQ$<7@HTyr;A2H6vYm3WD{R%tEPAf-@Z?i zu)p6jxm^AbaB|PSzVx8vCTqN?4ny_&rtquyqmhuvxmG1hg4~hx0IbCEp3me8qYqu_ zAI}gk+2+MOk^$u(B~ZG?<$vEf(sEs7nteKz!Og4@>IvYWPt+lF9-Ir5d zXez>e)h1NNoYJYbFD#!{Rkti4eddaLaA2_fm36X1VbN~$Q5N*_O$lB9n>I2+!!1EJ ziXA47^W$&%CH~ zO)u7bjAVXa(s&zwx1VDXcxWbx+p{VjAl4ZNFhyP}* z4*P2oTZ$9DXZ$2w;pf&UVa-fh8VOau{IOh zeVqKyX~M>IR(@5l`{VqWpqXIyy_LrR`ND>Dm(YCGGrTvNz;x8zJ<@PBE7#^QCTqZF zNAHu~Offm39Vqt-g@=?a+%ZwVVM{WTB^r4{f-PPjQMgWXT*VZ z&WiO+xV%XyFtMr91QT9krk@q9MVQkfzDFEmpi@Q)#S$7s7|0X-A`V~c5Los0wa!yA zQX0hv436te<*~QSnSL`(u4@`TRc)(KWJ-omL~v0MooSX?*DO`?f_7N4^6eHPDyCw< z^Kt(RXAAw?E0sG@OT;|Zg_fnpB*{#;*o}vY#-@8BLOKyc2^psXQ#y&@QhbgIR)U!@v_ABW2&0pDo8=q@clT>7S-8lq*oWtL@B^upQR@8jtw}bJ{)?uHd zL3KoS9C&hqrTzMkQiOw6o>dUT=YH7DK11PxtbSt;(Jhv9xNve&L!)R!a%_Kdx~QgW z5^;)8TDx>cJ6<%kk;57g1t#Af%+Hi{+9Yc@eW$!sh__)0yW z>o~n4pf{$}f8}Lk^O8ci|NFI-=!ObbKIZxqR=5zI9tjN@^4`{BAJdk|49I(7(0L^x zslD3Q2@UC&Iz$iP_~qd4TGXXj$gUK8S%w@9TQ9W7l-*2px#1u1ZA~_)opOSvUFmx3 z48y#LxcIBKTIt=iVZEBHaK^!C`iF^Iw)Y#uQw*2^*mJf}^6C9124ZivQh{My zMLBU3<~KT0wV0#e%|@_;Y32FcG~p;l?%=t8(L4q7ClMOYb)Hw(%wEeXNN9hrAHG73 z=$<-Eh;dE6{suST-gor&vSCya+QcsS8LWS*r&V#z1FkU9o^$@GUxbb2H?PvK18{`L zNWI7oKZ*OHv)8^gzkZr{G~=^(Fez#qn6tRiyVlfvw!l+#(PU_MW$Bl+&|!5StD1V? z%!VYr{YmKb_Wn6(63N@7xFmQ_qxkBC`GRfLvj1{* literal 0 HcmV?d00001 diff --git a/client2/public/images/gov/hets.jpg b/client2/public/images/gov/hets.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8fd6042179ef8ad4f46ab864422b5143d5bc227 GIT binary patch literal 68151 zcmeFZ2|Scv`!IgnL#0JjvV>A(8T%5GrKA#B)21=T&WIUnOuJH1grcG-TL{^=N>Wmi zEqf(f*6iEN{LejOq`o~Z&-46#pZEX1rp%mk?sLwyU*|g8O@2@QNTn73wd!k5%m(_A(MukfMf;E+b4c1g%~Ncmn>fqi2E^%PPn#itpTR zWGF7BNU5`dQfHYsi}Qt*cb^cYrt`TjkDe-|JX5AT8wcOZz#j|^g4ms109*9%IA=T# zWMPp&`mQ)b3oO=wQbWfHhru}E9pMLX8vfOEaDnq2l(vSp9&il}TO8a5eoXBXfxDm=2VdWK zuwot$^qg_FSSMHToExsG>5Oxtkp;-MaGA>(Si9=ZWi(x!G{0q>aNja}EF4_tp6s>8 zxy@y^J3461WdLWtb*+K6x1MDLRY;J5wuUCa1~wkZz*0cK5{tLkhW!9%DIaYYr+<`b zIQ+AohKr?pD<=N6%px_620;1~M5=t3txd$jU*UaVlD7_9-@~o6^@I^;y z1w0x2VVkv4psqm4%{Ue*Du%FjqERfur6Ne4z|`bPH|9)-$^S5l(Sf3tWbE06J~Y8xZr+L-Go;BeRXyVYfY>J z)@2@Zms9)K(4Kn$nm~K8PB5=oaad;3j*ql9HgYF7RO0R!zxU**7cOUA@~Ls4Mu%P9kK+2y9F571;9{m1JXF~=SoRA zgBmM-Q$qmK1pir#1;V%hbl-)$w^Adi%TJtr4*H=5dyOxK>*Fg(n{GtYsV}skW&?$ zCCc61UBX>P0_$QeiBM8fl9ZB`l$I6;HN;&#op2}*aVJ+HS`S(nSG0>QC8`mCdjumk z9;Ye@Fr|=SiJt4#8CVOYPfN5U#sTAqal*L*b|GM@sN_02&sF{@U*}cS)%|r()B@HmHSiB1w1F8$rK)K?!y8&{3CGGDUZ+8Q9%{8}maKO9bfXBkR z{JfKS6)37hg9{YFNZt=9Z}X8NjqnZ zHOxb2Wla|h%yuIXK+>#5=bJR(Ih(Y!gw*_r+q`xd5PM=&1>u>TI07M#kTC-0BLgOL zQeYyaEG0#)s*AO>wetL-s=N_x()V3eV7`_hp8b=`y1L5LQ4i&yg+=3GL($Pv6~yCh zEtQqF%WRj^R8m*eR77ZLAP|ZQGO}74a*8{&w6@D?s4Gwq10Bq7NcAC>STtxq$3SIi zX)6UqSqwrP%<-heEiGl`#X;6W93d?wgGO1&%1fa!wBB@_TyZETGzLZk@K(YW^du`K zqa7vN@y#2aSQ?_Wrb3bL0DPI(ApbdoGfkOiI1iO%GFg>kTPjf z2C@fE@taJP4RI(JFi8V*D=S+EzhN!|Zr<4XFZIll>RV{I z%$LXv9?T4Fy)eL< zLByu)4#qVJMTE3G0t|1|A{$jfDG4Qnj2uFaR)lx51ujI#32lRMrRei)e{kI9I_n@b zP}cKZ1&I7W2<3!>7gJRQbv<2dQI=q&5;wqD;~h{gaL=?VJ5Y|c4q*7CRuTZUzJH1a z9sHyjb-31Z#yAPUNm?6Vz;G05hy#mlU}OW+Q8+6AhC?ZN6@5dHkdl&80U8f$j{ulf zNhnCEIHK$^Se%sv7=NWDj@xDj_<5*4$WEA4c$>Vw2d~r=JHeIse{M-$sA~?txQ>@ zp)yX3x}qRJ?MZ;r6(!P|twj~H6dcP?no=Sm)Hl7G&nq}U*H(6=;6&}+)CLG{wmU~k z_(Tc&DD`lZcu(IzPjkDW;cOijc+``Y1DZdJCs+xZUtr;Y2YLWknCGzm0hPk*zlBN- z{$Z*qFlkvTM5$lGg9ASUc+{d`^6%66w=k)?_8)`&#_vBRRvYHg-@>I)H_PC^hYDNb ze;MfSGzpfh2GF_x5G;-KKT}^A=&XPFTe#nt`cpOjExD=)B^d#2RT(7#4OLm175=e8 zgT}K6&q9|0UYueRRKh`zzcO0`RcRRo09{%UK$nsKYuaU~)8si5mR9@@I_U8?&}9(- zx{}nt2VIsrL7juH^u5sk06I)NLRJ9=PiyzzT6MwgO0v~54!vf_vNHv*~?IbPt&8nfG<4@j^({GVEX0%8a`E!2fpVK#A@Hjgg=OAQhg8O6gzYVUl-2WlafxG+-{c?%`KFs~O znCZ`<%h7ao7W((h2Oa(zwlsn=(o%ran*K3x(D?g-<_FP(u;(|>DKQ?H?gGh6(+u{{ z!T%WK&4o&{k_TP>8a~+i1e`}Gz~d}J?(apfL^Cv+&sCsFV-^F@=Wj5OgJWz2aQy&- zxwzqvS?~>M8U}O2z$^x!&);BxkOLS1Mrf!i(k%JU;m?gzv+(CQLIn?c{55n%n0$)U zm;dV#Pmw0DS=c|ge9+;qVZ-qi;Jq9iX&|I%qWp8(=b|ba@8xL2)-3NqpTEIC9(MZ( zN}Q=kv!y>rK%NGVhQJSTCg}1v@F{U7CCvQ$5&s`y<{Uq$BI3c8;Y4vz{vZzZSg`4c08|9|iwAxl_b0Ly0y1+Uxx&^tt)TtkV73=h4;} zr4{7`G-sVRb@9zmU(bkE0M15&#b_xhczqUpW{atcxknxB)lx#!Jz(`sMgk$D@NK0* z9WFb3mXMF327zSZzBo7Mw(_-02|;hU~~9kIaOPE z{xT-z;k-3cT7AmK>)Z}3oS0XM%8q#psh~&N3LvGFx^PO_1g3CqK18^$UoV_$!fL7u z0t7QvX(@r-s^81w4;E1oQZy}_)mP~`nNpQTTI$zw0vI3w2C^~$g?|qNnIAAf{1_!E z{d%O(RF#H#0453lE(VG}*eqghf=A;4)pGt9)I-|^<>@-B?*9e-FaR>4#*crk8MFqo zdO^!lIr7`+4fdcwEMUS$K%i&92oEG+QnjXI1#pwbN1nJdq+M1e%FUWFQP}AGsw56jHxDQAV zjL4muAjPMmRVH^f+ z1JY6;z1YRb0Nnp#+zQ?+u-JND+G1WB2QKV^x{xN;862AgSJ(tLp*IVFZ39Jtofvlq z3=Su*56<$TTr9yIEk|dRlP3gGX@*-tEB zW#3wUE5qIeS6sn0V1_H-$}Da`P}W)SUVw&gWx`S5lHC~y%B+}24;QR2^KOvYV$c#W zL+3uftuR;fUnl0llYrsP-JuYmolk_d8VznR;#~y5jSnSA~{Lu(!$TfluW z41BW$BVYow44h^K;-0;fAYkkC-A#{qJ^Y)^=Jfz4sd^0(D`Q9yr?~{Qtb!9_=qra9 zSF%G4hi-!>baQgs!)gLv9|*GauC|n0w2-EOkpLR+;zq5) z2>&pF%i|mnC$t9QgM^?>;6k%Bxa6z?Z37pacR_mKlCv3f1VV%RmX6>>3+~Wy=p=Lw zx(Ho?LZEOc5{iN1p=2lx%7XHtC(v`~74#OWff}I?P&?EE4MJnkG#wos3*8dBm2_+9 z_~|y#iP1^ZDblIYZKvBqXFz90ca+YW&WR3Bcbx7t-9@?}x^TKXbn$elbUAcS=w8xQ z($&*_r0b>|qMM>;pkGYSNzY5akzSHskzSpCH@y-4VR~!&WAtA1XXpdyuhZY9e?Xr} z|AhV(eGUBw`X2gG@a_$E1}=v64B`xm44Mpj3#F&(s zbeQ%tSu?paons1Ry3drsRKirl)Xp@<%*@QiEW)h7yp!3C*^b$p`4aOj<`m|~%$3Y- z%%dzUENfWASX5c`SWqlDmUApOSRSwxvAknxXPH>UzKDO3^r9V$4lHt7bZSxPqJ%|- zi{35jTr|zPjCBL6GOHe|C95ZEAZrY3E^7sAJL@#tayAh*RW>6wJGPT-*V&TUO4yp% zhS}NK1=*F@_p#fupJ2bv{*e6z`$zW4#VZzzF4kOpXfb|qz~b1&j~CZ39$vC!$;Kty zmK<1uTN1D&eo66?mL(HQS1y%Us9rnt`#gRHm=yd!g9r#711k- zSG28USShqpb0vD^>6I}nOIEgXGINS>>Tud|UgS*Te8V}oYQ-wqRVJ%ERz<8TSoML6 zfomg|4wnO0AXge!E!Pw`FSj~3hWi3{GWR>~@zp%5x2?vk_FtW{x@Ps%8i6(2*VwPQ zx+ZH)^IFEWqHFi9bzggXZOPhR9!?$=9yE_XPa03dI{I~@>kQU;uZvz+zHXG4k5`-5 znfC^7F>fy)7vDBMJHBgtg?!!oEBV#~a;F-YS`gQAfuE(#x zv;NKcX+aS|W5H8`DT2*HY(k1cRzlZ=o(c^L^9$<=9~Vv(ZrH%OL2-l4hOiB#8^$+^ zY&6~Iw=rvDm&j@n9T6{)M3JUVOEw`l9ouwwQ}t%%&5E1tH{aU)R+L^;PSi#;LbO7R zUQAxhR_vBoPG z`p5M1_A&3%-xsm3!vJA$+@REOrJ=cDg5j8vhEbqVqwywVyzx^L4wFMB@h0P@TBbp! zANEV`_u2o-Y^|BCS@r>z111OV9~eEj{b0z!_Cs=q&K;^fEOOZ6@XI4>k2oADFy}Bw znWrCRI%;|};phxX4|NwcYN2Cs(_#> za7_7F$gx3}-7fcC>0A%HX5%QvCFk<+H9 zbIn+q}*Zd@SwTl$w>l)4ytapn^GQrTt1 zmm7Gl+W@uMi)fur47mkvi~9g=~dq3du!YMWc_MANM}7e$w{T{ApwH{^IIq`<}fi z*Iv!^-BI#X1QE>#%sCP8E@p@WL79tWWQBPIS*S@biRQKV%<@>IBhx)G#ZVl6oCz_a={F|3GhqkP1 zx!bzAHRXf+hk}n{XEltrejG*XeWPXe3x`re)o>NZc-E35xlIWA6iPe3JY0o1F--dxe+=8rWb$wq5t+_nET9Y zO;1lpPe1qIPZQ+F(DFreE9eCn=$1qD%jp=F(~+COYfiMt&*(r{3o+9(%!_nb7BMq1 zvNEuN*JiPUVrB*aA5@}#z#|40`bBiC5F7h4@G2e#Mmh!t7$bUSRy-X&1LJb070l~d zRtiFk5S;4LLaSK!X>g&0Ww;HFom_2kb%W-e)WMCiE^KR_RLY5bG?YK}HR!IEk?Zyy z3fkyR#wMm~)1JQjG-P=i7kma2onBnkwpr0?7%!@%yi;cv2-d7^Z0+3KJv_b6p7T3@ z!T(xFXxQ}|;W78_$Hv7cJj%$-%FfAsR`R^`#mlnln%cVe^$nlfJ370%zl@BIjZaKY z0rKe>=ouLqm>3xunVFd!0m{o6*RNngFhhbX)%USTqd1Q((l{w}b(OoaSfRN*I; znl6LfA5Y0{2r^ua*7|xkZKK>8Bl+!?B5bawgLmLye2p=96NNKpDF_d5UVAO((X;B$ zBO&)PN^06iH))$%DY~5ty`TBKwqwlN-7hRQtF*3jeCK`}kMq~#vR}OKno!a)v-P}i zBR=P4efOlO@~#7RUjE?;xn&JsrpOJ@Vjv#+fb zP0?g%PjVv}vV2R1-tu}AMaE2LW>kmC&>bfN8A|3OlJeBP5I*kd;F!MNLa6O8AntAF zpTfAcPH*%ho#<)pMy3^YejJD-vb&NYqVxE`X#Kb$8Dg`RA~Zc8CS~CVzPN89Lsep# zWT;*iIl^*;4CxR<$Pkj_I2r0X7)geD{E7(46}gcUhDxVN9SV`7c_{?L9BtB#!&#)4 zcgRqb^7xcqZ_4C^cPAOrXd**o=#c6((aoot3_ZP3&OeUGCqqfi-cz^AkRxS%MPs@g zM7p}7cLWTfqPP_~#RZy8eH>`*N$-y(alSc9hH@@<5}kTltNZtnq5GzeWGKys(6zLH z6g(|P^5vTZoXA3wp*jxVAH{NHK`IMUS+JD_TUqd63**YdxUw+XFT`LAG1x+63??l9 zKZ%UVZ$FYD4)L$tBz!?Jm|9qIkfC&r<91{ySlOqK(A8eXKQ09(Wd#JYi)4tUGc|Gu z%uedJAjfLziaxd%3X-8WS=oe<#b6FKh8k!cveqj|A+F2OBz15j$5VP*2YtQQkfBZ9 zuAcg1Um~ z6#Rg1PxC^-H-3=cEpX}gIzg^l;L;y(sd|=6X5&MxB*RF-qHyjh3|NafSar|MZ)zzS z(k8T2j6BKCdc!c`H?^BILx$){{ba~xs`H`RKp(P_Xx&V#Xz-YMI5CqO`JAJp5Z{o4 z>_U1rHX*C+t3Ha#ZB<=WldN?Q?{83uzb`7lM_rbd_ZVv2R*2oa10Ajs0|sI zT1$rX@~ZB+6Q+)lp`DS<$Ppxk|nhfcu8LgKFXabq$)u4J0|`HpRDG|t%jak z4;a3XY~KrrE$$&hZU>u0s=8`EC5Ru_#Z}$aPLf?)d)p}4W>tq1pw_gj$U~1|Vrpc< zp(9+@B=;)vl0nFD($*f9_r*~uf9B^Z(n0&P9PD5|ZWv6urrkCsu_b%^B`@}Aw$=e6ca!3Pqn@s{+`9&KM^E2Fz{WQy6*&8d35py z8Dj03yff(9W^H*qrtkLai6_}!WGE4wNgzX|gGBcNm4o8>_Q=A#aeI7=*n}F=WhD9C zQzM^3d$+3H`#N42cHPr4+Zx1l`Heik>)29@<|KJR{5NLodnD=33-{3mK}t4Hitd-6TT@ z^GRT^Y-DJ}VjLVLaSbaXq?n2k%9uZrzH$(;J*_?4%Oi(wp-JPCMBAR$5!Q-fV0Mue zgDGTahomPN8dvfjpBi<^nu&7aA6N!@CKW6|`hSLdU!suL-G@H+541-&L@300H{wQ* z^fu+SrNmDQtvp&LEPj|rD$1|!B8S-DCBQ^E49uSK_dwH|jnX9YL9@$lSLa->tHS$OZVT6r;cpWf^q`@{|5ZcEG zV<*Q-r$$^-X6~4Stq#Sa9(O%L62CMVDmxrD-4r>Rm_m5FiBRrJ^35s^B(C8tAwvx; z;AB~J2%#OAA?X+>07ucLDu*R!?$r|tfXyDr9VgQJ&6FZLdyXrDU5~3x=ENwUX`+{s zDM=sLVdpw?_{i4+lm(9cAFpF~3D?b6d2@f1e9=-m@uYFh;mC;Ir72Jz=+oG0cuP;UFoQf6XFYG~a4htv0OE9F;9*~Xi#!bh2{-SIvv;>gj4B!!E@R~@Zt zVif7}4qvIJFZK`DziHUp#gN~ppu*MZnsG!~?%4r5{h)%f-xRVj-1q4VgDS_RY0(}rn~l=OxccLtI_?Tj5V!}9 z*(Ss#JxqIAZoJdotK-d)_Q4%Jx!UUW&y<$C+t&1%o{4_tTRnx=1O zr64?VyH2L(%bM+EIK`P;Pb`@ZE67|PsvBz+YTmu;DPpW!|8wA@_%AyeiIIg@#GE1? z9V6_Jlkk1LN1tJgnfHM85yDebWZ1@duuXnq#jd@Si6=L@`kkl8Ojeh8`@IkQZ3*ye0W!@f-!%p zK7WUojAGHmUhAQ=rO&R`%%ICVc^y56ZVeAHud#e6(6jnTMe$R)m9F==ua@$a@i*`F zKpQvL_`X1qp)J1R~t8q8Rfqi$q09Ks%-ITgBd zl+KYsvSH2szlD{r^C+jK4qy~>YL62ub_{2w375qZQ-b-y+ol<$Svp%FK|4=h4pJ>A_ z>P^@X=f?6zg{t7$wE@QT*=-SII%Oi_V(s4xiTGY1a4^-+4mCfzvR1l ziH0hCeK4J3-G4cIMBVq&t8;NR-Y3K@Hl&Rg9^KaD#w1j$w1^B{O3NU$_^D4v_$h#G13~7^)r;$c8yXobX8anf>2)I3zw>Sg&5{|j=ujYa zU=wr$^Tc{~KD0aTD4|}=uY+G(5a3pUpVV{~4Ly1GX( zG2VoDhT+}HhTFlT@Z^y|u9=-5I^7{dfO0aF>qlt6M}~&Wr%%A=pl_Lz?h^XU;~zbpBu1&Q@u2$;u(Um-&^ zHC=?hu$g2o{%)X&iH>zu94*45*C>liMqprN1IG=rRA!36;7vz{o@{^TTS}@Ul#Qm6 zq1OY`+F?=1Y%(--AB!BeCZ&|rmGifl<1g~^>b0knA?&INK*7cMuV^wvxLq>F-%&AX zoD)V08Rs9xOl@rsoHSGNCV58zxbby$GA+yT*M0tsvN``1#XlpaO?u_mRzVWIEkcHT z2kgCH24axyN1BnHj{tdbQ>BsaWax7N;6nv4=fogL<`!Xfd%%_SZ_b2sB&LkhKYvd-H1twUIsdlY|SNL$MGxih3Es>Hc zXoh!@e7WOt?+Z>wii@ICFRW9Xkr!Pf7?5?$=~6rT$@xYV`?c13s(6RDRnf`1C}QOMbJ4F~lp2nUd!sWP z?Rnn}a)C92fM8-!WKd*a-*NsA>%8g>c`lctQb!aoZD-;VTXiWWHtKmB;?YC>wyz_y zSGRCJGLkh)Ez#A{(Pb0WUS}8Q4{q4>Z*=!ub9={@&(%S8I$L$rtmBo8_ZctWwrvyi znBncx`_m~VJuSq#-0>oOf5AYrH^uO11^%(+#E`FH$7bC74p$8oB}|c_46m@nscEk< ziBHe5uQSe9NFY}|8tZfO7BfAO@X}D%^z<7!KG`HyUCt{tF%4Utc=Xb5ooaKxh)eUs z$^l}F5?|Ha-G_h6L*X=!&tgP@8aFiLa&5w+f9O3w)5z22}%=? zD6bPyL>rvj&8Ln^i^|^9!*wHt=ajSGTo<1?j*2%9HQP7%zC)X~xrv>-) zNBac-o_ngiKH>LOA-mAgy}xu~pmG8c+H$ZgH9S$stn(t)p)Xwn9qf#CY`$`8%^Mj< z$1e&)x&o%5wg;3wRvftT@tnrxVeg0S#LPBalVufl^#`?$=)t>z^626hmO+s4T8GB% z{nOd%neVmDn!avbrOk!@9Cd8;@hah^g?EZxl}_SD_=i4qi}EFQ&uE#6SB0MDKiJTm z5pwsGYJ0=M`{CTCFEQ3TZly+e^9m2$7vWfZdH3a$jW_Ht@$qrR{Wcx9D#Ejv3ktn7 zV$Qd*WXh>&)&$5QUh!{())>D!o{=?F))$5iQbZ7rPZmZ?0*<2-1n}QY_&q7=Es)eGFH&oV2)ZcSAQ+wYW-k`obB) zr5kIea#E#E68fqob6@olwra5wU&Rr2?AIImDmIgw@7v~rI~Q3n5_!`lu=8WpF5Beq$!{#Zt$O9i zP^@&{hm4LA+Ub0vh9YpX~;ybZ1jlIB-3BVMQH41MKPn0~pwC`?<2S9p7nyy@kd z!@R4dm8BLxco1{Wg!x0jqA~uDr%R*XDDk?09kAM5GBkL{(ew*3 zli=bozmu8YYvs$t%4Rjc(AVK|8}qJ+RA`LnOiLvYs_?^p;~_q1ZAt_}u3PY||4q-j zoxhXR*%Tr2f$;irXL|bNt@ymmz-NRYo=Cg?%XvW$p7t-v%8^o4${)(!N@7O@gh#Hw zQ2ucUch$(C`iZcs`c}KHva&@g?bj``JNBAq-QM8AH^qcG%9i#hj_r!GI`f%z%PWym zuePi!D%4wiDR{%p@&_@e9tc@15)wFlWruoCJBZbnI)YWE0o6h@p?jA*IN58(H_R{< zT~;*mdOzXKqM|Oo)Pqx111oG*>fU5XDF&QM z&K;jo%7WMB^2a7Glc9T?n~=oo-s7X%A%yPmhh*sHa>83x@BeE_xme`v-s&-PrULD* zcYK`NdVEJmvBgU4Cj|~WY(YiQ@cwd6e2C}j!S^%wyI;18*?hIV@+CbfCYINPD-$=l7`WBXKK&Hu%`L~oC9~2$#@~-O zF#6<1_9f!0*0HX$Q8dz5JtzFR&?rzm{m*>2U@Fr^?^dV zRgsPb6cCSfL{1?O6AIu>mZd#2ZwLcQq@7^1vg{3^ZoromJ>*A}$&4JngdgY$lm!dA zQ$57q(SZqf^A1-sEm0i zInyj3N}m#^3(|AMEAz*To(%*<6uCP&yxv{gp}^JIRDeuRSDNWJNi(oae2E##NUPQp z^NI=GfqprDzUdXCe11t$@`S-?Y?^dAQohi{k;E0a*X=$XfA7WmF1GsOc1w^GN_ew2};q=P{@7=i@d)YvCA7&rc6H|8l&MWSl>8XbgJD9vXq+`z` zBTc_QWR>t_a4o_WDLc%Yg20;8Hr71d7ABE!=LN(p3wbTQ!2L5RohQW2fVGD`eX%ob zyvyftiBJrNMw!UzH-sSMlyrLJ=yYq*ysF+)ZLg6dzMzh`syB(ZZW3roi|fo)AdnD{ zOlct!wc9zStR0b^t9x4O_<(jrkJe4s1CR8h{te92za#(S`d7K7&$prX%}DF?=?w3S z$DPz(^!k9;K{Q2FxqXg()xWL^H8?>my66zFBj!;J^J&%#_wQZYH&RT$=>vxayO@}6 zZiAQ@JI=pS>>lU7?K)`nVd2O}Biinsc*3y_&Aol%uc{0Y@v;zGVZW@w&qH0Lg7_tlc-lVR+tSk5LH+w(dWo5&U2z?MPnw{zU{O$vK<(nB=(#@x}cQYOOf*O-(m(Xoi z%I&-Rh>tgD`KLX_8NS=lhF71c^F1)Kj>?jCwQ4LIySqC&`RkLxPlipc(ge2CC4ukh z6ni@BhA&ROI^H|kc&&UNmQ+_Z+G<#*BWt9}Uma2}9#Qud%^OjoougKkKGAtp@9t~i z8@UND^0RE#$7%>2y4l{M(f;Pp&W47Un1Xdy*Ov&$CujZ+j$tQ61g9| zSj>ClBd2A8VPzb+QPX!}lCC%*VN9lL!(6xxFA-^Tw8ak7PbPkqPVmPDMsCPMC#O~~ zO<7tM(=@8|rtn%cvw1;}&s!O9cA@*V%*SzO)dlvibP=x$^(1&NR?xl6dWais9rmzDK=5dHn(uz=bW=y_onDjA z8b%Mt*L$+|lgQAq(EzNVJjq4dx^C(q$(4>)`z| z;zfbAelMgmj=#rma=6{U=j{5{Ud>pJ6`x>2`@f!V-&NzhUF1GMP#v9qW4Hs8;3mbdn7zLM{ zz5U*$pi|tDyC}bJMzzfI%^iK43k|2DuGsB!e1tZx^E4|7KLHl`(r®M!1-3YMj}9wU@$@ArERmVqB(!J2oC$c)G6k(Lr(7UiEVw!y1!iIOCJ ze$H++Fl&|?2=Gyje4ea_GH}Z3z5V*$ZAo#ay-#{Xb+Q7?mjvsxvn^>gy>$Oc>bi3; zQ^clD?7r=O|GlRtAGKaU>CCMUJt2 ze#QiD(ACvEro6W1A;Sr13PQ%_OZJFQ4FET?jl0bJ>OqcArlq%=Ci&}Kl^yzH>T|@a z%yk%3)eqiG2`t^7m6<7_LxxbUDp|*B4bYo1>X#TF@;ZO;igmi9sY**XI^zIG-R*5r zlXNB5XF}A`Lo9cRbuL-;V?D3mbdfG?+CLTic++I+-M|~X$HUe3&&2da-ncdW-dxZ- zT7J@}yC`kQ*k3Uwazei5v0 z4)fabuU9_5TMC^!S-P-~@n6};STOwWR@q@)OUfjk$Tabyp0$5<)uW0`5PAoTDbZ1gVWi*2F6F+zUaU(k51zIE9YOLQteXkTgbEpTe& z;8}|+@nw$5cN*i3-us^iA@eoI+^j;uM(ynCXtr?A+?c#-g{)=6!xr50IMz&yN|1+a& zQVSXSxL#+MJo3%Um3l3iJrh$QTny$7rRV!PVyYc|)XYS(kO#?7YH7;x-9Fk99L0CB zjr$Wxdt=S5H-7+Qcu6w!nlP`vhA+3S4(@i-=DF##5`X-3 zV}{Eql5BGG>VT-1=r#=Bsi7y2ME!$bEOH!G>kLHS+jp$od1cE>29DG{V3W7hPd_F9 z7~=HN>q~1q!-i4d+(A|CmBJzJII(~DiGN)%cVvCReirQKf5?7{iarVwZ|uIWZ0WiAvvJbR|NYM~6EoPi%MEvB{fOGbM(LY7*==1Sh+59Y|oascA{h4Y)05(7y9Z zL264|y=QV&sgHb?=ury~`p=xm0lTP30i7=P{*7;@i?%d-Y)~c{CkM6 zZ^wU;D1UGprKhQruA)Jg86k7+`W2y)KJk}oDsuV`1ngP|*0Cj>eIZ#b#!bDSbWL{_ zZb6sl`&9GGAKr%WGi#`!I+7+WPMd_X55?Q~Q_m$V%~+_F^(r1WovHO`P2ug?JS?xz_RSC&xDXGnwx?4L9+>Pi+evuSc?eC}NGZ zRW9`o^SbEu51agHLD9llwEyl|w1qj`&xeU_^vp@*4L5~O{*tYF#%^Fso)82MsXp}Z zi7f24|8lK8tK;e2%Ls3wjLo4YGM|qmoLl`hCr499&}wt}ut#m-je{#y%iBfTo4W@b z?~)-rw}aW{C+phVCarUjcWuOCMuS^gTr~z7H4YroA@zwHiPc?)Sj@@s7n9K zH1T=CPE~l?wa-4zCJkqNy(xrOLX-E(y|_CmQOU9X$^NQ`=l(!@`nmc8^^ zuV}aEP>%0~rj1@sH=8ojxZ)zFF9%1TO3q6hT4fN%s)0&)B9njYS@w&4*IysH*WcHC zssvqrzK-kei9JOPair_AD>!axeibqMBG^H&cf=mp4Ngd&`docIaLj=a<#A^cv-RA` zTJSPkp~B6_FHT%8yx$WT#H(JQ9EQJhv(m8tIO@<|-|%pC&U)V1oVX+D4*fG4JD>Ot zaGROxCRU~B3+OePjAmd%KlRua26!AFxta3vTIIEw>kQTWIek2#70!-XDhlVY;+iZS z4^;LaufAG&e9X4eeeMM1Pp>}`{=+k4T_H1%NnkyHDao4=vaGs#I}(ekbk@6CTQ(pu1)k7Y3lm|PJ)@?~O;{b8}^kM3_atP}$~ z;2y}}BH||&5;#_S&77F03hs6#2dWY(he>gb;F4A{nEltb1tYt_%B3+_l}#!DxA8uZ z_JaFd=lQ4kN&5(6z2JsqWoOEi8li@VFa_S;wNU^6B>pS~4u=q2G1M_}q0vKPWa8`B zMk3$X{f4`5&<`VGi4yL~z0;zqFV81F?zlr@EmTo)=_`vYC^3D-6(9H6WAw|V#1oIR z+&Yu(TDMp>X6aUyq`R=1v#p9ZSX8zn=@i|QX)mcpC7IAn`xgUa%~{2H`rEK8Ornme z7pq99k9;ZjIg`st*^o0Rn%P7kH4T7s+TgWqEM$m@TW6Yo8tA`REl@s%qCUPOCrEAJ z2=$G8aBMnqs)*ZMis0!}y9I|whE@>sO+P4*Bw|Yfi6n3C_k;*!yGe)nlxY*8Cah~X z6xnXsJ}}vTnv@)CeyGA@do7Bx0nMa3P<{Ofsf*O!b?aqN87gxCkJq!nZzLd2%bu3= ze>$f2w%noj{_bV=-HDra7@YHy5q?Cn!CWj$Oj_e~&#BRSV}15}r+tEtGKYozm)Pua zSk16&?Ft!U`THM|)erwtkH@Fd}4+^*+C;w+@jbu3$$wfk1gtchoKtH=$+caj*aoPc#I}^aJ3g zS2_V~BpXK(!IUWJ7PxjSuQ#RCOsGM^uN;57fxuogAgrcOs3w6e*FJaf*6n(5{=71w zf|Nk0eFN@R@`w=E^%s4KgkRC!wW8>3>v$0VCgc|a=x!_z*z9*GffEo1mIRXm+|5Vz z;J1yBu$n&|n10D|jeiuGK$t!}Jw7!C);vb+(gDtqqv_xl8S_hU%t0k(3U~$Z*7PaH zl#lMj&wgbbQ;{`DVlr`>=&b-=2QFs@CUkmJ^}sEh1{)dCx9VW}z?;VZ!6hQ80PF}7 z*FFGyJF!FuaHCW`jZpcf2c{3aFr9Q#Yyv2Y=lY@3q}WkCaOl6t7u;P1eu;G1gfMDI z%ES+hM%5#`I`L!((Ac%~MC7%|!7ws(p1AUB*k^P1KCt35$rIMZt5B($*O0wsubpqY z;_>_F6lF5x?9^+evSpJS?*`lFCbgedY@U%Wk-QM0nYjP7cw{qi*rj<;}d}it0(>78H(#-D_|4`D<_{`uF zGGr1Q9p8(rr0##cjGjybdspR!fcj4rV*{ko9DdKlm*zupL!C2UOUMu}uLVC4NLeM& zk_w~9uWdEn-ki8~zuxtT=Ki|79eM0HV&HJ#5O=h~^2gYut4A!C8L=ivsYElG-rv&y zraAk?{aBJ@#yIaHsT%bpVe>t2byjKVzg}Z9n!X=9jelO3U6RnCJ{iAmjb8BP7s#uO zD_Cz=<{jw`8+4LiVVix4v}bFLU-;EiNQ4GmPxtUlX3>p64T5w)`2E&q%$3tlV>?=6 zqGJ16z|n7k2)EH%FOQL}{&$WBBh!X5mgiXvOFes7vtzN#J=H^a&WE2kAl)onKi6>B|F1WL6qgfa@7}vve?0gPloR>vacIk z)wP>4Z-a+>W}mDoUY%BNu?=;qb+wHm8S)bQ31Nf+V?qL z>ugklU#a0~+TOG4l@mb9;my``!TEzCoed4&TsOGaFKP|mUz}~)Re@E6< z<7%mC*T+-KueR5w@gu-Wq$qIHd7FpwQa)B#Ta&gr+0N8R;opprgz9;94V9`Z_o35j zj0xQDm7Wi-551G&~fN$uU{JB5!|c6eQMPqEE> zmE`J>rRyj;D0c+;kpHr8L(vO-f?v7bXW}q`$?&X1V9xi3& z$XC{+7O_DdGQ@58sgy*9R4?`-Uq=olx=Iqo`jKB=jd%hJO>-Ha8CM4zFor3~*7<@x zQd2*jhyE1xyRI|OfJ1MMR3?1g>${gQaIJ+@k#mq_;(G{ed`}ama&N5|7MV%RBSSM^ zfg3c5NVzJR-`ca3vIPCpF6Y=Y)j<%CoOU;TjGZwky2wA>CNG&U2<{sl@C+k`a`TUR zPL->HNq-17tf=!G$JC=+ym}~7pfZenp)UXHFj5O zodJ>)T|LVti%2Gyfj{;FM=JyQ5*yz~NBzO(ye1M1|5utTzS=(;YXt|@k6Pz8rpZ6( z*kkqKiIM1JH^%0*6OUX#oX*#X(@yOxq(VHV-djf}T(S+4=NdE5>2u?GeKXIu-65?( zu`JSDkYg3<^W#%n19xZkl}+2``A=iBZITU7@|Q1ve7a+iz+^zydy*MpFdCr9zp2}; z(`Y6;0z2a{Fj*oY5$Rf6Q^38$O-<*N_PY1CN`vEW;Lrx%%&>YgZsIXXc-5#rlh+GA({V}1W-XJ5CkGFgo{K(zbLRRC zBN<{}>xI~O%OQ_5RgcqEQ`l8g)^>}*vmRlC5<$O!ou4&~+wcOXSQ+_`ZDw4tsKVfc zzzOwIGu57NFD*JOotP*ThdF8-asq=vSv*+sgpp4hNG4vWQ(=g8f@4@?-Sf{Sy&i=M z;~O>{ zRU-OJ_Bs2!^WNF_yx+O+@o!-LRx;NbV}5gt@B4;!PV1O}{>G&!XDVj6!t*T!)X3B!oV$DTcAu*nU0Nk9kQKtUrLBuI5<-b^K>Cd7EdXp3$k;;b2V21=?;{5I}k@e5vH-6wJV~mA|Vt;lFK%h zy!v?r8Gxjwh%0O$ZO6Cmu|AFIP0{{*&au6YOGszi$kS&pW>p7_b!HZIC!E#t4j+}h zLz5zojT{6^i_|7hwgEE~9#8)r$m|T> zXAK?=xW|LA**N8)fIVCWkUt;Wk9PwYwDQAPLpeSfwk@%-FdZ)f zzOra35`T>V@Fb;hnLrj1gRR6}+M)wQ>QJOW?si-JE990285G_D7DH+f(_GxY#4qVnZIsV|=S7I{+(ZVEo{h$%3qW^&9x6 zTY#@EzB~=+x5Q0tP@RN##FJwI`}Hr^EElOmw5LQfL5Xdr$uxk2`!|bBz-4-Lg06PY z2pGq+f&}1ltF0Ni+TI7q>Q8Y~(v{#$ew$Q|Tafl-0L!Aj3UIrH0hz20=(^@5blY4& zA2LJu(@!RKQqQAv(_s*cd0_-zxn`I@Ij3qlNLyo6Ok2;TUTYzCAULhIqcx~eL)Er2 zx4a-Kx>Ts^vpcIYPNeUoGb#ImvUu-we=bI#>Nf_kZH{2fFl9Mzaa$%*f zs)hv6Do@D|v|2Sv$;K(X11}UW*Ck||BXrG4Vr#;^TA+~b$8EnyKAzVvD-@eRKD9qg zIc;UjkABrOuishjBB157uSBe8@S|#5SnK2pu_9%)v_<+foquXXQf6k-y|3wBVj=Qi zdTy{B|EGKz>RT(=eVVE&mrq>J+^5754H3RWqY-g0!B;6QSnZ@*OUrdlRURcS$exfp zkSS0?``cJ3Z2Num-2C$ob~ohyk3-HE)drn7u*mz=gP9mrgo$izdmWSPWQX#Fv5C#& z2P9p_;%}R8?Ef~%Sd}<@rbX<~KJPkv<#!Q=mm?cB>ftIXaOTi1I9vVMLP6@u2%jb~IE76U3UZsyQDj|#~BV36iECFH~`b^l3d*Z0^I1$4#f5v4%JZg?pQ!`rl-rGJ1 z#0tD6j9j^qbQPawPX2FTwtq`J_3N-{OQ1r=T6{)6%kt~rK8;L&=vaHGmdP>FUQE`} zhJ-ktN4LMJk>6Hqa%TM=zQw_Wm#r>}&@9CwbBZ<4bbSXB=^A;zS8VtQaR(yj>kB~X zEp-)gwy63ZAK9aZlL6b2MRN8I-|%#+7kQd!R&P6TZL6o1@wg4Dj6{+y!oR{BIX>A| zP31O`6lcq8y$(!aCDQnEHM_?+Fh!r7Cj=tmnPhIhi->>JVZ^3qd3fT}N3hcs4K^3e z#Mo=czN%uN{XYNK+~9v?~ZRZzFjEp2*eUJ^c1`Xcx9ER!WP$W6km4X*v@sZYM*=8aXzHIosXmsn@EqzU9A$D z%xYqpq_asV({VX>-(TTLZQ@td4n%|$j7wgO=a+W7JkL@Y-+y)XbI;JdTbTaAfhQOB zUk)<4O9f_qGGBCkXLc*hmG6$>X~QE@&XN~ov=7yaoM2Nr>8tsS73F#Y09WQGvTPLs zd$g$OWg1xh=@s@$JRb{GG<}-ppPi}5>Ps(A%Q|*!Lc(Hw^7ha2+ke_{?zY5tTjKwk zmiVv3?cW@+FXNb`ElB9i=cV%FoA}`&pRR6{TDa3@D>f!XKQ%U5F!AVQAKtWKw(^TF zy^gR50}mhHzREDWf&HyjawB#FHtIRthmMX=!fRQO{drTpHp3gX(eTqYxR6utuS=zq zh0kVr8m$$9xjgopnsr*y_obVO-#gn)(Ts`7k=Syvw`!(F25h=ye7BBOr>ucaOtYq@ zcf*&b9f~g)+3BlB-W#p!(}s*jEWEapK8%MNH|$er5RQ)tObtK{mF#1kIK-;$<9CX# zzavz3g-4+guIE5}RWlJY7$;=a2od3E@~akReV#-{hH^s3G1Y^H0#)L3ik8yqYxBpJ^$0d!GkU}q z$e~`z6{`hz)mcR=(=kGhy|o%V#dowKE{zl%xUY(+z|N&hHx}Hl&7UvSHV@D6hp!93 z&l2V9zcHVTHID7}LsXB24fBr;i#1qc<%`Xzw#}$IKg&T6eEVS8W-IMF#&F>tgBgc# zkPI~wz04RrVw~pQWUm1kNSc3hu-#2Cy9wt1c7pjW<0RIMPBu!fZKCmK-uG{=;kUCg zH`ZBSqC_#)6@p_K6=;!C+gcyA@;lC{fi<<8X*Qnnahblx2^F`l=R1Edn!|P{@FwatAue#SJ z(31#6?&*T^UU+p;jMSx83BB*)(JqrIk6$pn_GK=1g{`iYbAOU$MCP#afmFWLu)dBq z>3;pkUqhetN2TMfwceZhkVU0AC~x<^J45$+>=NhpD_h*#^|=Nft89^Ds#e|AjbZ{i8H6V>9x|gj^HgDgkqvB zCG14R3?sRDyc=JV=x)oxXE*)z=pj~0heCqrVOS@B=e1Sg(i#l2j}MK56(>>HPoOg0@k2TOw>jS+6NSG z^I{4XyGidhx6eWM^o19kd4QfpBnAgQbw*lV5T@-Ko1s)&G53GUIctipRXTRTgFcPZ zJ+yJAnWrNh?qn8$&{C+tGs-Eb9U1M7UF$%xs-MPCxXsm}M__H2NV^->{}y5Wv)xbzA7fdT5B$$SdT{SA5!%)*(hd+Avcb@9ZRYFh_h0L zZOp-tO+x*`_4Xi6-Tre;1ELyfY>InjuBoJx5aIT(3v6PlVIO)5UaX(#uVl1oX~fRm z!O@q!Mioh{t)JQOBAeU)sCxDsM6-HFC+Q}6MRQ*WNom;Qe?7SH)_o=~FF||Cx%E99 z`$i3l6d|ECxqjjmq#0VbKS|)+^(6f(Ptsi;_#dLf-*>G+ivQye@(jlnx3d!y(A`9h*|~3LG9*rK=M?cu8D2+tU;RRKp4TAEM`d_MwIkDl zo?7of&OT^Ih1v82+Z~LG83R<+ANeJ*hp-ebg)k?Nz;%8)6*%fk8?N6LzvH1w6zX5o zJaij+f0fJ5UL^S4d8-_3-U?pg?9(@7O;OFFj@sja1`3*|Iow72=8jO-igdWq5fdC> zj_xD6Sw^W-3*tAL9}WpLroXah_x!|xl&+F8SV_(np82!n9>6QvHT(Swv)|po`ZIww zWI;JzNx~Ig!HW}C4$S&9cZulO$m^l2uE_?aaT9rzvcBE03z zb4TG5psQp%)coFQyPq-Mn@l zW%7a9sDBVgJ;Hl`=n>5|RttK)SQTz}l_IgxRtE#&p5f18L0eYrH|Q`az>-d>>&d+L z6yH^I6*()o^Yn{eMTtRj*dF+nU6tMNa!I!N%%7yi?Cxs2yV^gprpb8)Xd@E1=8Y`r z#~u;$zJwsA{iwVxNp!g}CPw^ugGz8}3Yt)vY~VcKde_i5tA5O(yU5+0p_CWRW0~%o z7G2=WXl!P7I3HQ=(dycay)%q8YxHx7`>N`DB1s6HCqsRTo0je6aXK{^W)N$Mvx{sk z9eBfc{#n=A&imee!8d64G_ZEj(@t%W=7Hf@_PRiCj3`ceuQRh$@Uvbi8w5i?k6vB+T` z2v616&*g>>6l&KTdfksbB83pqa2?bOIqc-923O$;YGl7i-4f&Zy~M8lP%LKa;#cX1 zAJNMq4KQ}u~Qm!G>?&(-M6HpSM|W$^GiU{LVY0;L>s+_|-cQ z7x9)`l%9D)Sl^MxPQ#PmGr3npHs2MAx+4p))xl>a-U_*EGpYueiPhCN)|%Xn&rpm@ zimDzxWgeXQoh{I1L#)Qw*A{0UE+C#nn~|(=V9n&?J6F~mx_V_xOYu;0Mdfgc@3wP5 zLciRRqv!5UCHtaRo_z8U{U+^=y=-oKr@UX%;(^WW$~XObm(0H|#aLL)`5!rXWmb%8 z&#PqL7YuLeR68?eRpew9_9~p^9?>4YGzb^%TDd>i)aJl`%A7OxZFC46EoEv$FKc^P zYkleE^OHOoCn0;TLsqF$#W8L!@83X6te+&O1`i?E3%w*B+x4KiAI;#Sb7{aT4iyi!-Gd8Vj4&j$Z7jeX+C3nX;ky zNUE z4}ps<)eTx{lQaR_#0pGlQQ2*+J_-qY5wkIvM#X}dItLSp)`ZyD!(4o}l z;UQre_KQoLB0Mi&$eusL-p1n5FEx(5*Z9Xd`ZvYszoD?FDuA%~Ha-A1WleOfAJEaI z!wl{~xZJs(IMc*Etk6t0o;wheE2dA~blpU`8#s2VMWJSV_|CZLAikAg2TFQZ?iR>r zi#^H&&hPH=82?O9>mKE89Sq_$KiMSbLV0-nWTN{?&-NBrr&E4pX)c;K1!}Tpq2qF@ zHyh7V(i;OUT(^^@(AeJj*k39&T4FVz!s@y>;O%oB6>?Mi{Jna#{l{}%{RaAdw@OZl ztI1yZ+E9DX(@N&MRBLL^>}@b!=JAK8Ss4$uY1uR7iBy0|l~1{c7!b9CTg^(5mquZ_ zU*H#9loq0+?@M;)^Z7e_Qj!QUx?cWF`_t<>O@b0u!%VUUUt!$yTeqKTL{IQ$_=KU= z;j0aI-w^Zdo?%g#`#Byu-%3LIWhYOVkjHB>pckkzL+0o<72}MrX7ZHlO}rO-Pa|L{ zh)C>WxJOL5OR=>QH|QEJ6UpLVz3`}Aw-++}!Pa8Ii+=w|^BD9pbMcQkKL?SO=bmqP zelF$cTX=>#&jA>}0la5_j81wpjHDcYL8=j2x%$z0;S-`(DYHX}pkMep*9@B zmh3yaSgeMug&S|Ahxd7=1}v9sDK?Okbipi~H!16=w_TLj@ff<*Ww07rXwudj9{>-M zfklMd^y^-(e%P@`j$IB_6KCCyhD2RJPUUczkQA`6O6JUjslqA~N{A4J z(Jj+msU=$;ixq`_AA^1MOAhaXE(Y6>iZ#Mxi7UKxa&pYR*6RzZPOt3lWESvleF=44 zkg9#{$HEGg_c)>|PG%bnBDfRi4`a=%Yb&C4AnE;v*`|` zF6tF*m`;0O5wMQIDhQyw!~0^}3d?Pr^=Wzlw9 z7`$0(w=~>$u=`0TmPttY6xLj|SN$rz^PSbYJI3)Uu8;cAQDg>9kuNeL?uHHarGv69 z?nNR4$yU|=uwsXg4FE_aj*PXyUeX)G9Eja~tdU0j6FDTWkUSVZ@f*;3G93kTP=#sR zt%sG@P_aLCfV+g2|5|wQiw*l*LjJoSIOrBabOwA7DLTe1g z4M+vD{5s6nfI+zJ0L2w_MFYhRp>(coJ&Zr8j=uxwzq{AJk*g>ca(vHu8P-$ctb1KK zAWBrEAMPz{@f6*mnI$@mG`C|<$L8|^Cc}K^OK>O8k27coN8!T;YXi_BM2XA`Unyci z7KsUEYhEBcI&69NJtRD&u=Q|Z@&UbrR}1Y3d?i`LjR7v-3D?-^#{uX!vkv_qwBBAh z!}@6ElB+Qo5>V04mx#|juJ_dVWXb zThAP-7%alLgD?Y?fCrcXO)NxKhpo@kF_lrI zL0NeVCYH#%E6RQck`%w1LusxDCKN!I`fwq4lrU(xI!Oki zn<(1?7t|td1W91FCmq?ghYeENLhA)yzZkO9Cb&j!(9P>XnLaM9ZPZ0OZAu`EoN^pX z4t|MBRZvUEcr+FO<^KY1c%zCg;Oo?E@Jw=T_ad)abYuYUeJ!7yc-Ry`(_;&u-UdXO zc~s-4cOaH92b!(kC%xn|KoVYzBil}^??CQ*-U2f6HuBwgN-+TBv`C^P0OW>1JOv@j z0pSXqfa}4=;if?4PBUi*GGh-Q`0uXChLSE)5np>q66Yw5x!V_qaFlRd2Yg!)`28+y z){~R-k5fq=N^5^uSB0hSw<0OIxQQp6%`MO}n4`hwFkL`y!Ob+>A$VPu?sq$e)XU0&#V)Bmzz5(B`cd=_L$R3P+Qkr+= z9@5Lkv`@F`!XIz6U$&UzEbvNw#=SX_>PaE`=iw{oU(GP#L z=PJzN21Ra&&)Lqj5I2~Wbc#Q+up%@bFsFrHa7mJyUHYw%OaU zT`&=8Hs>~Da~KwQF#z1WbtqrF2f68~&QGGVuzBCp?;iQY9QMj+>alBf{9+5Iuxr(D zV02QZ?O8TorGsEt1(VJK=E!nWkCe8$PRr}!z1d3z8EDpnA^Vgdu0ax_eeWL>4zF7` zM|RpXblsVF*`Xz8E&>U?ejtH5{(NtT#UDHgKiKadM0Utuz4HG|nCxEj&!w0D$JWj9 zfJY?76V_yr=Xr(ntWQsN++_)YuiR28#(4MDA`@~$!l0ivPL20P&5E6dZs4WgCDnBx z=9Mwrq~a5D)NaL!)6en*`w_*HdiuRKW$|X6)Go&gp=YV&w5g*HD2Y%#quz4#aonH@ z6A){y8)g|URHF7xu70agK)>&n(ZSFO%ih+`VQnY>p}&u?ek93NolQ9s5G{o(sFE&i zzUdlzvmC!&*~enI^dg~r0bvAdM>fosEJ}?Ql&4$H<+S=xcwbB(jyugox-9M=2Q5uT zXQal+m!^gYXFFKDMU+lT&H)RK%3?g=@3>x0e%gL8tDz;$TU8E}miAuzAY~d++cubL zQDD>KB8iE4onx$U?qr>Rer8^V|BD;685~gdj(AY}0S7VQuLQOW$_F~&uarUt<)$1L z;ID+DWC6KT&oHPrL4m!}3h*qk0DsbV|AY8mSbGormB4P?ZH?R-=*9j13Xc^a#xSLA9FT`vMqmN9+3Vl3-`ASrUfS_Fvr7hSXX==q zF3e7)jSj0mt_=S?)QshSHRdKTg1PCGA!3wpOq1g*R8Wz)7U)s$VvoexZD2yIF%ctp z-Itn59B1iiw`pmT9A>wZ?);{c`kSuycSH{YjgJ+oa6r83(tlo2UXOUdT*d2RBh?t$ zALHwzqt2&lmKW}*nFUv+=gU7W)D#z~rKV8S>#P;ID3!C8{X|ck!Rc`NGApXEGxb!7 zi`L}}t+6$=k180?prLOQXH1~J$VD_PCRTF4xV?uj9(!n9zBl=pET>hOdX}VWXC1X- zK>7N69_&NYYpTywx@{Y+CLLUPR4$8`=DMxBMCLX(7sD@v)i-#iAQ$*#=^Cf5`KW1i z%wx7qPf0b=&VM^+u{s92-KrWCOZ5r2KCT4h$Q@j>A;vfMv$=Lo~|pQdPrMn28@HYIntSA?qK8__8gg~Wh(K^vE^h;s|} z=cRARbyHUKWmj03s2zikD-M|k%4rAQG@6?FDh#S%+1Y77ro}1C?Ds**lOA7jY6g|| z9|xr_Wzwtt0)ffrLvvEHMO<7Y7`W1AE%(Lc&yG{c@Ti)Yk_Q-X*nPCRXGPS zT}v~Q<_nr;IIm0J?;#GZYUf#5 zr4EEL#VGQ(pbFjj%RXz}UU3Md#d*QHka_t@7l{ETWhE4 z_kGQnqf;il6*&>JVlg@HnD6myZuTYii1qQ3)1BCJT=+^Ap9sclMS)m2^e+26PZJ}f zKSNphyEJ*$TCD{Bu-nYI#tK|B&r!UwbXu4&&e5m0l*CGWc`&^*Bh+J}b>;27fVxGp zloh){U;XyoPbjupR9oiKI`@?Luj<7As0;jNF8jYugTFg@{stcZ8((sONxV$b{k>PN zp>wXOjhw8beoU2%bRVsK=CojxGJP6piMSr(euyb|gQw{ttdp%|Q|7zI>5>S-yyzeh zpQoA|E*@)NK~WwcVM51J?&ZES6m$rdrwzP@Z1kK;3fOa2@n+g^ex}!vQYhRkr-@WF z7CAm}+|zjpN?b|aHzEDt7AM(_rpZ--MDDtk-qsdd))0M|&}tY__L^Dn>En3zZNKv; zXsYr$x)&}6zc7pmMBuMlN3x5eB4;&739pgQ-Lh7W?m$?R7b5+opC}?H=lv$;XFY2O zD>-*agqSvWjbtze$;HlpVk}la7u|Ee)yd|0|HQ|BWMar#C%*(-Ieh zTbUOFNXB0usET{rObwTva?2DbC-rM6XL9 zM+Rpt-R&^sh}{XE z)7O>#J_{eCwpDlRY*(O=Y-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSkxdHA|FPC?Uy#b;&2jxh_l`@A?jEgEV@&`njxgN@xNARl_7u literal 0 HcmV?d00001 diff --git a/client2/public/index.html b/client2/public/index.html new file mode 100644 index 000000000..fdf3af75e --- /dev/null +++ b/client2/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + MOTI Hired Equipment Tracking System + + + +
+ + + diff --git a/client2/public/manifest.json b/client2/public/manifest.json new file mode 100644 index 000000000..1f2f141fa --- /dev/null +++ b/client2/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/client2/public/robots.txt b/client2/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/client2/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/client2/src/App.test.js b/client2/src/App.test.js new file mode 100644 index 000000000..1f03afeec --- /dev/null +++ b/client2/src/App.test.js @@ -0,0 +1,8 @@ +import { render, screen } from '@testing-library/react'; +import App from './App'; + +test('renders learn react link', () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/client2/src/images/blueline.png b/client2/src/images/blueline.png new file mode 100644 index 0000000000000000000000000000000000000000..cb01efb3ec6ddf7781be3f82c83ee0d5dc0f6b81 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61SFYwH*Nw_oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J`1m?9Cx9{-)^9gY-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSo9FbnKx9mKhQOj4NvxlIAdaUU=Gk5~R`7)z4*}Q$iB}nqelJ literal 0 HcmV?d00001 diff --git a/client2/src/images/gov/bceid_logo.png b/client2/src/images/gov/bceid_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea1cd2fe326fba142851d10db433b558e077aa5 GIT binary patch literal 2637 zcmV-T3bOTyP)d0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU*?@2^KRCwC#S_^PgeskK^5fxfV%Gf=U$juZq0 zNnQ!*qyZ7Gz|IhoJ`x~Zd(uZ{N zQO*#WOA%u7Uh;qJgEd{ zD2uz0aS4POU<7f!gb|T@8A(P9qn5FYv6Zot(b>=OM=)kHE@n()lwu4M^9V6~81ogz z9>%{JTX5`1spK&_xVoA;TWiVi1^N(NfDC9kjL!LOAdJ62ATmw@f{QYyGUhQZP|yF1QSJ8fw)*wdu?)!|-;yIsq*Z!{31yEnWp@Q8^}5h4UK5UABA1FdkyeRT^{|qL4HhSdkvy9JUKEpBQan#wOXmDxrkKe1TFUQMZHL2KYH37Rvjmq|Xz zxE04s88(*CmbBy+>~b~l;%~&+xXqfp=FsbP&6V@`#d#m z`KB8$j(V75n@!mbk86{6-^5s?uF3JwvJqUn$H63F*ssprQnN21rV#@1q5&jS%MmL+ zdYmT3YpLzfX7c$%PS2fy$y(^S2F(K3ls+1>eunR-ZvDjTwbzTBMV_U zk$9yas`HyMUr&PbIzlQZ}?}4t4ua*cjCoB1dMy^Ph~I zLUrE6)%y-934+mSC%VRd8g-sUb9KYSi{RV}!eZ1e27>$zHl`5L=*jAQ>jx&ZK%q`Z zPDj0ES^6@@?GE!_qV5s;v1xW4@Q2FCA1*)9f~&XjYodDY0@mjbWN#`G9 z%wW9a@a$=}G2R(mq21ptwC?aDZL_B&#mD)77`NCIa1yLhXTh8h7&T^Rg7PZQ;dd4f zh0c~PKf=2E;-yz9i~bziV1>|BOBjurRGK0#&sN#aj}6v}V!Ixp*zQM}!9`kV0mQK} zst&tFjhllEtwz`hEH1zC2V~l63=VGVexVn1Izup!@_fv?vPicGPBf z+G1FdLt>E?C6DZ;4u;ipl;5_)TPgnLij2^D)@!#h&b8H!o1t)XP=;8+>kSC`39CL! zaWd-9JG&$Rs8~!{Bl%9Ir^@6eU=*YHv z$p{3jgyb@9sA!F?fvfL5wu-f}+btM>6%8>OZSx?p!K&jdEm&r=swp_$VPo2i!CFx! z^DC6ErUdsKRewuO`7LC=eI`UH&LksMm$J2uA4)=#_K()sm*C|FO>jcnZSl-{;sW_~Yt0 zKn@MlevrH;8XhfGicz90+@gJ1xnqu#@%<~)+ZcureF5tflCR@`{vZSwQpKU9u>ZAX zrFzh7(2g1iNt5}n68n6?q9}8`)b@WYSE8#mmHMzgsPvCAo@yn^g@ zsSfgHN1RH|e1Hlk&9~qGTgq&;i({>(@=yg(1o1T1=9Ed8Qwapqu4=JDTo=Qz_M;@I zdy9i~c3!5;4!LI?x=nowE*BF@Iy5(PZEm%loOgfqm&%}}AEE9IxG6BM0rlX1duG+q z{2C?d)?@!6>C`a^kDATaR_PSu{b01|;MPL00*qm8$H?OjZ8yPvNGB2fUw{DszM#8l+K$(900000NkvXXu0mjfpz{(m literal 0 HcmV?d00001 diff --git a/client2/src/images/gov/favicon.png b/client2/src/images/gov/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bc4b5a97e8eff63c1c5e86239902157cc0d2acdd GIT binary patch literal 11639 zcmeHtXH-+&wl<;n-cbwz6i^5yl!O*~k=~IafrJn`geHhmrHC{UP^9+X*c-3=Plno-?`rz@;-QYG|?C%GcPl3Ets8~ix2|oW{VQ? zb8*L^@$h8i{oE0DPAD&+Eeefsl?83Jc7T8wq%6o(Tw7S%T?yrYQTO*m8T#uO+4(!! zL6IPNIdU047>>XN<%IzHxj4IGVScipU%W8f{Y5tz1pEc@a*_p^Y3l)%+&oc0h!8|b zSWv|e<0A@^BL~WOBJE)Y%BsIp;99aE2QM#o7#Qs9>nr3dCgkRc28%$UP_VElSX5LH zhY-ZxarHv@3A$prFDQQFP)1?xJTdNG7&lko1t-GR&D%>B1j3C2e<#O{+Nt>AI)8U? z(f&n`^+JL*a197|cF)V^J4fzv6aA+JkXH z{qp=*8#N7Wy+3R&WJF_J+<#eIp#O?Q+WmoZ_x5!Dg+bbZQO+nATp(B+v&i4@UKsm7 z7wB*ExfuCxf#BTz!T&e(KlJ()%P(DF%5HYv7fv;lWkDD5!jNuu7$of1t+cH z5JcKaK?NZQdl5mXm^egG0)m7<5fF%&gsAObs5D%$UI&C^8|q=j+y z_WN_d2;+h>^g>*SCL#`j3PT{GqGBRaVv=Gae}YU*LxUvP>D3rYPNK-$4nafAq5 zu3=mdXcXAp75!`AVpU+cx!`m~T$Bcm_*Xw}DljEa6vE5R)5y)uSr&8=D)55wS49D3 zeyi8mss95f^INv6<80kL@BGETA=H)|y~_dB?nb@0;lb^Vv_{|WFn1}%&o$`$MOuR{MT!4{x6oGe7HpeQTrM|7;;6;L;0+v%Td#*`t%Q!26?zrY9#6htos1m1i_ND$14v zPG?Vd*9ek3wua=}x10mtV!i}-4+YDM4W}Rc46r(;PWrlhx_$cTU~5_R%mwUJIf_@-OE zH-CKZrybw($}be(GHv$*<&)&wGVje?JwvF@eMmpwe&~>W{N?Gj9cMzxmSb6mUDe@(n!;+Y}PJTW`6-ML)>l`4JJu@$R_2+cp}S z;cz$3>XgU0*qU@j=qbT3|ucMc=|xJ@P2c2SlIC+%$=RU+nbFoI~}|d30=G0pUq~s z_rzY^m@{?BPg#ED{TjV2Ury(Ip9HA3_t|&iiCtlfT{!lb@n* zI9NY^tDHRd0dK!a*)#K6*WCPM3rxMaQ+eZvoi5yLwLWdF{7{Zq@-n6D(f(|-i2ZZS zlDU1l#MCM~>5du}lERlfhZ;kPq}r&!HtN$h!Q zV@J;oz>~}W;$|CHh@y5zB^+ye^Cd1?E_y8;amxY!^ zP3^fGfV_wi)4VEW?J4-E;^oho+}lpWC4&uxt#}hw!$wnh(l4)aFnlaG?LsUi7v(J( zvej0$nx;t>1QhL=y%q1cD$X|WB<;(TLvVd|e$)J1GXJgXx%xKa#csJ1ob1EsAM1&e zQibK(3U01CeE6NrD|GIL7!Cu;`v;d{LoLJS?++PkU(b=+O4sf?Y1z2&u~JU-)MlPg zEkxUib(xjyYKk(2aM=rT%hmyDjgeid$tS%!zCu z2MS<(xMpO}v|Qzt$ArrsL16nTrHa!6Wk}K3$vk!Q#+=>_v54BnL$q@f^(R=o+?qXo z2T{+ggdtvCLC53fAtgYb!E#QvD;Ef1LW1N_hx$)=9XwSK0PP(ZnH8fAO{(?H1~zL% zckw6Cx(_JJB!VOce{?YU7fKmhR}@M zI+((B;h6B^o}mO;P~q*|HX*W3nO#|4Fm$zV*U^OT>xbeJ`@St~#vU z>#+~vCEOjTF)O6#e#}|wEkf_abS6hJ17$giD?*|*Je~l69^G9~m)hM1s^S4Hx}SmH zR^;4<@W~bS(`aE}BlCw+hJx8jL12T80;t8P_EnE;X=0TIwwHYAp`2H*ikKEXssSW% zscUxA-?%U18$BL`u5dr%tKRB#PB2>S%q%~`K8|jNkjgw~AQ?!}8NA-w=^rbuSy}h) z)^3A`ML7T9P=bwxzSj1c#3w2nF%vbZhYJ(WXhcI)jFWhL3zVWWBXw&y z(QGLPH$9aET9KvkH=eW=8JV@@-2RF1cBl}L06?+wWC~n&`tW`{Pv@Ri@UQ&DIx3ky za+L0S-RaHvRRs-YiLJ+I!cUV9^>yB^dVX}*`ll+q#v6#xcLuF_V>!7--ghUKww(3;1Rp#Ubi(P+nwa4KAy*% zmb7(STCtGC#i$jod#(}apV`;ABn_{edF<2cSwngy~ROchfgjU?H8)88Z+Ma zaLN+ImwB{V##n$+B&DF&7BkWWsIUNl0>r}jgQ*d~72>cf_4Lf6cqE@(6jNQwHMAj) zmUSi*g$ypE5o$+YieGvU$DSz%wRy0SR}^g)%T%l5>B+vPkrX!r8<}L#)lsdI*pIP- z3}_57?Wdz)tJ!ui^LBwche&VBXF)n@c+PMxg-KcT`&SVYQSmdo-Ne*lH=VAdp(Dz& zz&kX~P&O z*EHd*{!Ti`>dbj!@jW5S`wjq2NoDp|Pa?Ncz2H`1nlpL`zBw`eBmh>#$0R=uIJGC{ zx%W}tj5goyZk<&y;L)v7WkiY$n|0@tfRE9>w+BA~LL_H3cO1z*wzN*)>N+h;lW|2; zaXhZb?#%Jb7@rE2yS>ked_8bk7+{OK+C{&6ixy$nHcm`Y;GuARmVNaZLp%vnN^rrN z_(G33{5=tIU#IUX5sL!dp8n2f=w&A0h$Ns-*eiG~=3%5C>Y3`PWH zm+l=}TSD7<7nvBF>rzdv;lk@g3h9}{+!5}a3v|K76;35dPrCEsb8_DUYN%~Qc$4sb zD4x2r^f6@;v&L7C9mZ9Ivtp?^t;q}S_T%xSQ^V~P)ErNy=fd*oZQFn~w~{~U?QA%Y zX9G0SPxOJLBK{flua-(jt+L=85Otm`=Fqg2Sjr#*pU97{SNK#^RpOsnmwNiohC^2ne8$=r>|S_7BrQvvw!)LGd!2b z=w*1_)t`~f5ud5Yz=Z7Gxs0oy6spOtt#|1Gpn4zb{S z>@I_(%`qa>WUAF=QEUDWc-mq^)LtxD&!XWDYJ9djeJ09Vil4>$bVtn>#BW?OhgXQ$ zR8-yY{xWRZ1<%diBJh4eSwu1J1v2}bi#Wk|iEU9%<$;h_1#873<3}H;XtHz)iEY&1 z6SxBPSTwu7X2)v-_UNYzdo?w$x2>wS08(FF2=&N{O5PVLQ`S~~mC0oNpX-_OFFJJ^3n`~8LfsDZ#|r((Qk`T@uC2mrXDNr=Q0&p#&E_4=OG!c2Mox+ z;VT=|DvU5mK@!=D(`nc9+-jJwK?m(El5gnj9+)LM8f3!n5(F!d!TSu4t0H2h%;^cM z%~`~T*w~G$D1NZr*#8<4AMaOweJ&YAQq$?Y$MuS!bYYq}wOfdzi%AE@XAqLazA;DM zMt$yOzKedpDYUW@ZKu*YJO$AzN~3ixCgXPJw;#%>8jXZgzOge>W6}PmSHa$}fv?ip z3d+!U^cg>v*dTy-cQpFxP!|pB<`u?RlZ~;@yv4Kkg6S=adiF|N6pe|Mi@21U8qHKA z3;{1JQ|-q)8)Uw$66Ce?(kIMaBg2e!EFnUYhmil{Ne4=C8WD^yaiqYyf=StkU7&_)vt=wca#yO zTe!PVpB-qUws>i74UVkuCmiv&)zt9d8fdI~H7jT(z^Clw-E=>qfz5g`bvyU6%C7zb zgVj!)&kv0E77Gz!OXnx13Vhf5MSXYFY*q1ptz+!ILmY^29{$e=cuj3B6gB=>{-OV zfvTK-U*Prb4ySVhg6mBu?TBsDErCD)_4u>y*2p>Y$*ydZI<}>&!{tM-1FLVsoIoS+ zFxS3vylskR#YBcj9ChVd37huq2KJFM>D;f`A~>!*nigL8e8V7BOvUnMZ^l*FBqCJg zVW)gHGaLRlrHLFMMon2?lQq2dc}xE~lhfVP_Q?HuErIXO4xIipePZN;qB&x~iB+dp zsB)At|4C4>Y8dFKIdlw{v7b#ytJ{|G;QY!nU z8#UyPN&~Ybl7f|5c#RxAz1v}=mjSia$2B{?_k0qo6ebcp;Fr8M?%I(_$}v??d<$dL z)zasn|5{ZsjcQ7I&$~}YcaH=fo}-#9ID2S-;#9WKjbmfU9X~P`%;%p&u{TWT$`E1n|jedUYFBs>T)qi=}z#F zhjI*cPS;fdBK5G2Xxhu#^H>mANjeMcPoVU^6ByT?|Gg~dejK4rCogp3n|#V3@8$MR zQKbhAYx=X)-hvN_i^2$RP$&j>h(wNGe<*8V9JG@gqPLb}O|Nbmq8&b48b9G@%K#C5 z){w+fr2dp^!Vo5+K61%a{)G=gxZOd zOMPG&*hr44dd{5IT`j8Z;sGu;#o@(dgzx#l<`Llxo_b_)!hS0E%j`qlLw%B?VYC6K-*{bJucsFrSSUO7zJ+BZ z21wyZ<2Qt4r2-7!aiF|*QbA_2Jzo`aHMc;WIwSwZj5SX!hz*Kyi!XiSSOc|z&cWcX z+98P6R%>Mso8kQs_NKFlMG_}V@OSBz-BE=9d_QgD5p8V|Y?~jW|KLDK zCooqmG5dv>tR{d>D6EW2Xne7Kau{$`YDBukgg8Y}zZWn+jEaL#Bxy=>x8b=>A2^Uy z$J@E)X&G5csjA9qa05@hHWY@wb6ds4?UR$Ld>Kw&A%Rd-buL_Qd04PdJ2sml_qfho zeZ*ELVc#j#`WmGb$q)>EzD<9V7l!7B7lSFj9g zQF1Vsb)aN3g6F%bE!_qK-Co#k$T^~&R*@dQ<=ccV7xWv(d)`$6dU0uQIN6S={s|9AvlBfY7Qc8|fxGDiCkV!1>Pj*)!~PS% z7RF`1#4|PQnJ`e)4Nd^dvzqRtQiR^EV+k5a6`=TJweSK@@mME6dZ2XdB_5H&VzGKM z$)Mhk%LUM!>&e>wrKG*COuHz-7^1!lGg3Ro6j;)^s;mSV`QHED0-$vj z%ca+?)lgFylIGF~)&4*MS3Xis*%~kF5{7XVX4V}uOKgYNXvXPQX>FRF913QM5`yyZTZE&8|(`6s^YOU-u}(g7^c?mw>0aeMC!m3w7pk z+%MFVHRxXI^v5;`RTv^Q{0+|Uz#rNx1>oK5my|_9k~1C+D;O4WTU)B+lY+=v;)-5oEQZNUo9e`;{xgBkJ5Z>3n0&L2~md$ z>M(DK*iMUKi z%>`~I&{>rh!dGdhqJ;ovg-4h3%4Z{=;_?b?OAXS#$SfcnvgUjMb4Gnh#!$ zM4RgBueRQfY=8pweyZqR$Fu#Auu9WS(RcMbky_t1+h^IU>u+y169eOioJ@(g^7n|7 zZfAv>4MYGv;v>Q2DrxW9=LbgeXTvxHM_vlYbhxbPze1RE>^Cfg{@0o5g(&k2MP_8GedYA`e2$qPjeBQm|m?U_-494)3IUI#tOo{R)Cy1n?P z122~gtY5ZSR@UA~H?l^K)Sptz9b-<%P#imfROzzD-94n_d*q|kJSWrFM)H79Bn&^y zP%;Xb2nOY4+#`(?TCL!l@g$Ld9>pm~ffbg^R>DN*V=DV%Tnp^nwm*u zatP-Z_sjgXYy(O>|I7BwF>qj1hebq72uHxTfNMu04o)AqiW@iu$6dR=t)k`@#jkAw zUN}~sW#hnunXM+%gN zH$D+{bJ?|(0zEO~fuXi$Lw6Ty*^swJ8;8!C+(A4sC9zC+`LB|``Pp8wh#Ztr8L~`cR2W`Y}0%_KVsZ>6Mg=l1cEXG>qg%BEilKcrg z)U}D=EE~6H2g#3K5>8sb{rFq|;@o{zkcn)9ig@mm^um{9Ux)D^%V!cG7pywM1Pxlu zzCsXir71x)i5;j^yVPiP_5D%-r835dIvbyF-TQj4bw@GY0BqtYj1+na z;6sXWFH%u6RW#fW`f2$M)NK+XavDe3zTa32wgkMaN>t%+Xc}V{i$BA=EdMpr_Be%q z9o%t#4nHpr9!{?Lx_KYaSURH|>aJ*qdx2G6Ps>Q<{QUgr`_|d?FQ#Dh``R&(WAE?SAFBNxTS=YZ!&UONDg~E(c;cj=hl582Ylo3(7H#*`2h8g6~6GaWgj)KSIL4!O~tW|g9dDOtOV5)^@i!k#bp%@(tlD1iC*TPbe1cn z)XE%_L#0o0;^{gqZfX>-kEIpru8DOv$+#^ubfS-0;O7CI@7@8tJy9-g&lEC!lffZL zA2|Bz>o2|3Y8$0?gM5%2SDJPCIAJ3Hd9J>kqc8GFP0rTX)D@-4H1n-`9r^Ee*S=GL X8-R7U>Gn=9UX9jJ(NV5Yv$_7|bA(B{M@2j>Z&aYmC7#n=#DToZlbk_dd_(dG7nZKHu+keXr%8JIvJNg5W;!eSCa;f(92+ zXx{U5P-CoQlOolb>AAPfdWkpWet&>SJk8X6i9B^8K@iUJRz;O0rDW0?wM zH<_OvPnih^?|;mLFZlopt0 zQM4!6!%?al8Ze|1456+9RaVwh)rCS~NEH=*6&OMdg@P*oY@4244c**#My3Z3HSM4^I^NRXU4foxAF1X`v({L|8gNbF_7VPtPZJj|jBqQc?NBql3Ve!c z=p5J!CvL9|=iF7`gF2kK5)^mKfIU3*VQ^x$`1JM)due4I7nrPK83gotamz&#^4|g< zJ%GM|o~(1+S7N|$0*Pv}ON{_@5dd~jT`Fpm^Nm}tUD^B*n5(DW&YYN81m2l8_k7ys zEFHh(WnhWs)+z(b-Jiy00G6*IIr(%M`Wnl2mSfNT=?=Ub`(!m}b8lM9?>@{%@mRHxmu5ECuPj75;xRughU!Dj}dYM)6 z!P@T$&}QKiSCCuvzN2r_`Bu6aJ(K&+IIXmq`vwM#r9aAfqw92M<<*&6eiy=%%YgUR zsU_XOXv*01!uG~wO>19rQ9ZXocbmJ3^UnZgYgMgd-n?gD^UCACmgP3;c|_%yGaq-i zm1f7FfNs+4;>z|yOL%evFp>LdY#}P+wIJNi+R&7Ax~dFxbRU6L^Hu=UHYYac0Z z9OTw0?pCwsRGt(;d0rx?9Ya`q$5sO!cE>LTP$J62FZiI{(?xY`4`@*g$r;=-;my*+ zYa3ewqtgpt*V9LzRq*QJDbr(LqJvjy_ zT?~^w`^eYAtXHgtAHk{xT|_9snuQJp+JW_q#Zetipj2oY78guj6PY zc+Y#cYppZdIj)~1c8v{-)b8s4=RH!S+M3|Q8Sj$Hx#l)xyI&jNY2D#cd1(D zj}4X@)3$N1D*8+Y(=j=vrD~Am6$L{}%lds{X-u>W+VLZLYtCS_q0~jnQYQP&7nRG- z`f3Fxh6M4EYiV7Fp%rI0C(H6B2OBN~z`NhwL*HwY6Lm}UJQ;K4UH@i9W5dlHEL#(p z!ej_X;ER7xsT^{r z=W55P8R7ew=<}If>8K{z$-vFFT>jc20eNZ4+9N;HSb;KD_xxOm|FzPP-LIXkOCq|m z6j9A8@&rGvIYYzzPERc6wR|fx$dGD{N1Nx_*(#mgaRTT4+wae`IP}&O(>s3rxyc~Q zYNz4(vkXR~=fvh+IbX?)hsI5ST-)YrFgUNrC3W$B&~(Y5UTWW66SEB1x_mt4G8>~; zaX{eDAcu>~sWW$AMuwxm{1Q9qdsO&U>lZt>?k*gzAPsrER8}eWUhmWRDM`?&6vp01 z@9Dj+t$5769Y;a-A=8JXuTPH7+wLjY@sT6}k4`ylmYJPWctyzBD)v4Csv?`&KT0SL z6Q_+IPsSS`&208nU4)go9|*K^2c5(cjm(iv1k63ujrGIQaRM70 zVd(&4hBBnR*ZMN+w#xN*y|yB?gI$xf$5Ge4_gjtMDpzwhNhvmxFO5~sc-9}7pC~dL zX(s#5m*`!dA$x9PMpI%bKeop02}fSj=*-UiM0ic`kfmXwVyixZF02sAOd_}6L)Fn_ zh_@q~n)1TmKa;2{EPSD;ZRIH7Fk{6eL*5?t>Qk%fukB-h9h&W_U_IGiv$o?BapP2& zdWhJwp5n~j1EyL>gg*W$y|c9+YZ_OaI4&V1Kq7kURi~PX2eRoNr)KSmV8IhF?+p=8 zp!lC^y)8&I(J$YT+IO<~Y)n=G!5V+@x=AXu>zy>eX7s-JeD7m zbo-jTha8BG9g#Lt5rUNb^SM6E!L18L#@V^`FZ8qDKD3FCQF9zn(M8E`T!IlZR*RzF zJuvMPQAB3Qt@%RbEaA_Y@oT#CEaLC5yvQ$<7@HTyr;A2H6vYm3WD{R%tEPAf-@Z?i zu)p6jxm^AbaB|PSzVx8vCTqN?4ny_&rtquyqmhuvxmG1hg4~hx0IbCEp3me8qYqu_ zAI}gk+2+MOk^$u(B~ZG?<$vEf(sEs7nteKz!Og4@>IvYWPt+lF9-Ir5d zXez>e)h1NNoYJYbFD#!{Rkti4eddaLaA2_fm36X1VbN~$Q5N*_O$lB9n>I2+!!1EJ ziXA47^W$&%CH~ zO)u7bjAVXa(s&zwx1VDXcxWbx+p{VjAl4ZNFhyP}* z4*P2oTZ$9DXZ$2w;pf&UVa-fh8VOau{IOh zeVqKyX~M>IR(@5l`{VqWpqXIyy_LrR`ND>Dm(YCGGrTvNz;x8zJ<@PBE7#^QCTqZF zNAHu~Offm39Vqt-g@=?a+%ZwVVM{WTB^r4{f-PPjQMgWXT*VZ z&WiO+xV%XyFtMr91QT9krk@q9MVQkfzDFEmpi@Q)#S$7s7|0X-A`V~c5Los0wa!yA zQX0hv436te<*~QSnSL`(u4@`TRc)(KWJ-omL~v0MooSX?*DO`?f_7N4^6eHPDyCw< z^Kt(RXAAw?E0sG@OT;|Zg_fnpB*{#;*o}vY#-@8BLOKyc2^psXQ#y&@QhbgIR)U!@v_ABW2&0pDo8=q@clT>7S-8lq*oWtL@B^upQR@8jtw}bJ{)?uHd zL3KoS9C&hqrTzMkQiOw6o>dUT=YH7DK11PxtbSt;(Jhv9xNve&L!)R!a%_Kdx~QgW z5^;)8TDx>cJ6<%kk;57g1t#Af%+Hi{+9Yc@eW$!sh__)0yW z>o~n4pf{$}f8}Lk^O8ci|NFI-=!ObbKIZxqR=5zI9tjN@^4`{BAJdk|49I(7(0L^x zslD3Q2@UC&Iz$iP_~qd4TGXXj$gUK8S%w@9TQ9W7l-*2px#1u1ZA~_)opOSvUFmx3 z48y#LxcIBKTIt=iVZEBHaK^!C`iF^Iw)Y#uQw*2^*mJf}^6C9124ZivQh{My zMLBU3<~KT0wV0#e%|@_;Y32FcG~p;l?%=t8(L4q7ClMOYb)Hw(%wEeXNN9hrAHG73 z=$<-Eh;dE6{suST-gor&vSCya+QcsS8LWS*r&V#z1FkU9o^$@GUxbb2H?PvK18{`L zNWI7oKZ*OHv)8^gzkZr{G~=^(Fez#qn6tRiyVlfvw!l+#(PU_MW$Bl+&|!5StD1V? z%!VYr{YmKb_Wn6(63N@7xFmQ_qxkBC`GRfLvj1{* literal 0 HcmV?d00001 diff --git a/client2/src/images/gov/hets.jpg b/client2/src/images/gov/hets.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8fd6042179ef8ad4f46ab864422b5143d5bc227 GIT binary patch literal 68151 zcmeFZ2|Scv`!IgnL#0JjvV>A(8T%5GrKA#B)21=T&WIUnOuJH1grcG-TL{^=N>Wmi zEqf(f*6iEN{LejOq`o~Z&-46#pZEX1rp%mk?sLwyU*|g8O@2@QNTn73wd!k5%m(_A(MukfMf;E+b4c1g%~Ncmn>fqi2E^%PPn#itpTR zWGF7BNU5`dQfHYsi}Qt*cb^cYrt`TjkDe-|JX5AT8wcOZz#j|^g4ms109*9%IA=T# zWMPp&`mQ)b3oO=wQbWfHhru}E9pMLX8vfOEaDnq2l(vSp9&il}TO8a5eoXBXfxDm=2VdWK zuwot$^qg_FSSMHToExsG>5Oxtkp;-MaGA>(Si9=ZWi(x!G{0q>aNja}EF4_tp6s>8 zxy@y^J3461WdLWtb*+K6x1MDLRY;J5wuUCa1~wkZz*0cK5{tLkhW!9%DIaYYr+<`b zIQ+AohKr?pD<=N6%px_620;1~M5=t3txd$jU*UaVlD7_9-@~o6^@I^;y z1w0x2VVkv4psqm4%{Ue*Du%FjqERfur6Ne4z|`bPH|9)-$^S5l(Sf3tWbE06J~Y8xZr+L-Go;BeRXyVYfY>J z)@2@Zms9)K(4Kn$nm~K8PB5=oaad;3j*ql9HgYF7RO0R!zxU**7cOUA@~Ls4Mu%P9kK+2y9F571;9{m1JXF~=SoRA zgBmM-Q$qmK1pir#1;V%hbl-)$w^Adi%TJtr4*H=5dyOxK>*Fg(n{GtYsV}skW&?$ zCCc61UBX>P0_$QeiBM8fl9ZB`l$I6;HN;&#op2}*aVJ+HS`S(nSG0>QC8`mCdjumk z9;Ye@Fr|=SiJt4#8CVOYPfN5U#sTAqal*L*b|GM@sN_02&sF{@U*}cS)%|r()B@HmHSiB1w1F8$rK)K?!y8&{3CGGDUZ+8Q9%{8}maKO9bfXBkR z{JfKS6)37hg9{YFNZt=9Z}X8NjqnZ zHOxb2Wla|h%yuIXK+>#5=bJR(Ih(Y!gw*_r+q`xd5PM=&1>u>TI07M#kTC-0BLgOL zQeYyaEG0#)s*AO>wetL-s=N_x()V3eV7`_hp8b=`y1L5LQ4i&yg+=3GL($Pv6~yCh zEtQqF%WRj^R8m*eR77ZLAP|ZQGO}74a*8{&w6@D?s4Gwq10Bq7NcAC>STtxq$3SIi zX)6UqSqwrP%<-heEiGl`#X;6W93d?wgGO1&%1fa!wBB@_TyZETGzLZk@K(YW^du`K zqa7vN@y#2aSQ?_Wrb3bL0DPI(ApbdoGfkOiI1iO%GFg>kTPjf z2C@fE@taJP4RI(JFi8V*D=S+EzhN!|Zr<4XFZIll>RV{I z%$LXv9?T4Fy)eL< zLByu)4#qVJMTE3G0t|1|A{$jfDG4Qnj2uFaR)lx51ujI#32lRMrRei)e{kI9I_n@b zP}cKZ1&I7W2<3!>7gJRQbv<2dQI=q&5;wqD;~h{gaL=?VJ5Y|c4q*7CRuTZUzJH1a z9sHyjb-31Z#yAPUNm?6Vz;G05hy#mlU}OW+Q8+6AhC?ZN6@5dHkdl&80U8f$j{ulf zNhnCEIHK$^Se%sv7=NWDj@xDj_<5*4$WEA4c$>Vw2d~r=JHeIse{M-$sA~?txQ>@ zp)yX3x}qRJ?MZ;r6(!P|twj~H6dcP?no=Sm)Hl7G&nq}U*H(6=;6&}+)CLG{wmU~k z_(Tc&DD`lZcu(IzPjkDW;cOijc+``Y1DZdJCs+xZUtr;Y2YLWknCGzm0hPk*zlBN- z{$Z*qFlkvTM5$lGg9ASUc+{d`^6%66w=k)?_8)`&#_vBRRvYHg-@>I)H_PC^hYDNb ze;MfSGzpfh2GF_x5G;-KKT}^A=&XPFTe#nt`cpOjExD=)B^d#2RT(7#4OLm175=e8 zgT}K6&q9|0UYueRRKh`zzcO0`RcRRo09{%UK$nsKYuaU~)8si5mR9@@I_U8?&}9(- zx{}nt2VIsrL7juH^u5sk06I)NLRJ9=PiyzzT6MwgO0v~54!vf_vNHv*~?IbPt&8nfG<4@j^({GVEX0%8a`E!2fpVK#A@Hjgg=OAQhg8O6gzYVUl-2WlafxG+-{c?%`KFs~O znCZ`<%h7ao7W((h2Oa(zwlsn=(o%ran*K3x(D?g-<_FP(u;(|>DKQ?H?gGh6(+u{{ z!T%WK&4o&{k_TP>8a~+i1e`}Gz~d}J?(apfL^Cv+&sCsFV-^F@=Wj5OgJWz2aQy&- zxwzqvS?~>M8U}O2z$^x!&);BxkOLS1Mrf!i(k%JU;m?gzv+(CQLIn?c{55n%n0$)U zm;dV#Pmw0DS=c|ge9+;qVZ-qi;Jq9iX&|I%qWp8(=b|ba@8xL2)-3NqpTEIC9(MZ( zN}Q=kv!y>rK%NGVhQJSTCg}1v@F{U7CCvQ$5&s`y<{Uq$BI3c8;Y4vz{vZzZSg`4c08|9|iwAxl_b0Ly0y1+Uxx&^tt)TtkV73=h4;} zr4{7`G-sVRb@9zmU(bkE0M15&#b_xhczqUpW{atcxknxB)lx#!Jz(`sMgk$D@NK0* z9WFb3mXMF327zSZzBo7Mw(_-02|;hU~~9kIaOPE z{xT-z;k-3cT7AmK>)Z}3oS0XM%8q#psh~&N3LvGFx^PO_1g3CqK18^$UoV_$!fL7u z0t7QvX(@r-s^81w4;E1oQZy}_)mP~`nNpQTTI$zw0vI3w2C^~$g?|qNnIAAf{1_!E z{d%O(RF#H#0453lE(VG}*eqghf=A;4)pGt9)I-|^<>@-B?*9e-FaR>4#*crk8MFqo zdO^!lIr7`+4fdcwEMUS$K%i&92oEG+QnjXI1#pwbN1nJdq+M1e%FUWFQP}AGsw56jHxDQAV zjL4muAjPMmRVH^f+ z1JY6;z1YRb0Nnp#+zQ?+u-JND+G1WB2QKV^x{xN;862AgSJ(tLp*IVFZ39Jtofvlq z3=Su*56<$TTr9yIEk|dRlP3gGX@*-tEB zW#3wUE5qIeS6sn0V1_H-$}Da`P}W)SUVw&gWx`S5lHC~y%B+}24;QR2^KOvYV$c#W zL+3uftuR;fUnl0llYrsP-JuYmolk_d8VznR;#~y5jSnSA~{Lu(!$TfluW z41BW$BVYow44h^K;-0;fAYkkC-A#{qJ^Y)^=Jfz4sd^0(D`Q9yr?~{Qtb!9_=qra9 zSF%G4hi-!>baQgs!)gLv9|*GauC|n0w2-EOkpLR+;zq5) z2>&pF%i|mnC$t9QgM^?>;6k%Bxa6z?Z37pacR_mKlCv3f1VV%RmX6>>3+~Wy=p=Lw zx(Ho?LZEOc5{iN1p=2lx%7XHtC(v`~74#OWff}I?P&?EE4MJnkG#wos3*8dBm2_+9 z_~|y#iP1^ZDblIYZKvBqXFz90ca+YW&WR3Bcbx7t-9@?}x^TKXbn$elbUAcS=w8xQ z($&*_r0b>|qMM>;pkGYSNzY5akzSHskzSpCH@y-4VR~!&WAtA1XXpdyuhZY9e?Xr} z|AhV(eGUBw`X2gG@a_$E1}=v64B`xm44Mpj3#F&(s zbeQ%tSu?paons1Ry3drsRKirl)Xp@<%*@QiEW)h7yp!3C*^b$p`4aOj<`m|~%$3Y- z%%dzUENfWASX5c`SWqlDmUApOSRSwxvAknxXPH>UzKDO3^r9V$4lHt7bZSxPqJ%|- zi{35jTr|zPjCBL6GOHe|C95ZEAZrY3E^7sAJL@#tayAh*RW>6wJGPT-*V&TUO4yp% zhS}NK1=*F@_p#fupJ2bv{*e6z`$zW4#VZzzF4kOpXfb|qz~b1&j~CZ39$vC!$;Kty zmK<1uTN1D&eo66?mL(HQS1y%Us9rnt`#gRHm=yd!g9r#711k- zSG28USShqpb0vD^>6I}nOIEgXGINS>>Tud|UgS*Te8V}oYQ-wqRVJ%ERz<8TSoML6 zfomg|4wnO0AXge!E!Pw`FSj~3hWi3{GWR>~@zp%5x2?vk_FtW{x@Ps%8i6(2*VwPQ zx+ZH)^IFEWqHFi9bzggXZOPhR9!?$=9yE_XPa03dI{I~@>kQU;uZvz+zHXG4k5`-5 znfC^7F>fy)7vDBMJHBgtg?!!oEBV#~a;F-YS`gQAfuE(#x zv;NKcX+aS|W5H8`DT2*HY(k1cRzlZ=o(c^L^9$<=9~Vv(ZrH%OL2-l4hOiB#8^$+^ zY&6~Iw=rvDm&j@n9T6{)M3JUVOEw`l9ouwwQ}t%%&5E1tH{aU)R+L^;PSi#;LbO7R zUQAxhR_vBoPG z`p5M1_A&3%-xsm3!vJA$+@REOrJ=cDg5j8vhEbqVqwywVyzx^L4wFMB@h0P@TBbp! zANEV`_u2o-Y^|BCS@r>z111OV9~eEj{b0z!_Cs=q&K;^fEOOZ6@XI4>k2oADFy}Bw znWrCRI%;|};phxX4|NwcYN2Cs(_#> za7_7F$gx3}-7fcC>0A%HX5%QvCFk<+H9 zbIn+q}*Zd@SwTl$w>l)4ytapn^GQrTt1 zmm7Gl+W@uMi)fur47mkvi~9g=~dq3du!YMWc_MANM}7e$w{T{ApwH{^IIq`<}fi z*Iv!^-BI#X1QE>#%sCP8E@p@WL79tWWQBPIS*S@biRQKV%<@>IBhx)G#ZVl6oCz_a={F|3GhqkP1 zx!bzAHRXf+hk}n{XEltrejG*XeWPXe3x`re)o>NZc-E35xlIWA6iPe3JY0o1F--dxe+=8rWb$wq5t+_nET9Y zO;1lpPe1qIPZQ+F(DFreE9eCn=$1qD%jp=F(~+COYfiMt&*(r{3o+9(%!_nb7BMq1 zvNEuN*JiPUVrB*aA5@}#z#|40`bBiC5F7h4@G2e#Mmh!t7$bUSRy-X&1LJb070l~d zRtiFk5S;4LLaSK!X>g&0Ww;HFom_2kb%W-e)WMCiE^KR_RLY5bG?YK}HR!IEk?Zyy z3fkyR#wMm~)1JQjG-P=i7kma2onBnkwpr0?7%!@%yi;cv2-d7^Z0+3KJv_b6p7T3@ z!T(xFXxQ}|;W78_$Hv7cJj%$-%FfAsR`R^`#mlnln%cVe^$nlfJ370%zl@BIjZaKY z0rKe>=ouLqm>3xunVFd!0m{o6*RNngFhhbX)%USTqd1Q((l{w}b(OoaSfRN*I; znl6LfA5Y0{2r^ua*7|xkZKK>8Bl+!?B5bawgLmLye2p=96NNKpDF_d5UVAO((X;B$ zBO&)PN^06iH))$%DY~5ty`TBKwqwlN-7hRQtF*3jeCK`}kMq~#vR}OKno!a)v-P}i zBR=P4efOlO@~#7RUjE?;xn&JsrpOJ@Vjv#+fb zP0?g%PjVv}vV2R1-tu}AMaE2LW>kmC&>bfN8A|3OlJeBP5I*kd;F!MNLa6O8AntAF zpTfAcPH*%ho#<)pMy3^YejJD-vb&NYqVxE`X#Kb$8Dg`RA~Zc8CS~CVzPN89Lsep# zWT;*iIl^*;4CxR<$Pkj_I2r0X7)geD{E7(46}gcUhDxVN9SV`7c_{?L9BtB#!&#)4 zcgRqb^7xcqZ_4C^cPAOrXd**o=#c6((aoot3_ZP3&OeUGCqqfi-cz^AkRxS%MPs@g zM7p}7cLWTfqPP_~#RZy8eH>`*N$-y(alSc9hH@@<5}kTltNZtnq5GzeWGKys(6zLH z6g(|P^5vTZoXA3wp*jxVAH{NHK`IMUS+JD_TUqd63**YdxUw+XFT`LAG1x+63??l9 zKZ%UVZ$FYD4)L$tBz!?Jm|9qIkfC&r<91{ySlOqK(A8eXKQ09(Wd#JYi)4tUGc|Gu z%uedJAjfLziaxd%3X-8WS=oe<#b6FKh8k!cveqj|A+F2OBz15j$5VP*2YtQQkfBZ9 zuAcg1Um~ z6#Rg1PxC^-H-3=cEpX}gIzg^l;L;y(sd|=6X5&MxB*RF-qHyjh3|NafSar|MZ)zzS z(k8T2j6BKCdc!c`H?^BILx$){{ba~xs`H`RKp(P_Xx&V#Xz-YMI5CqO`JAJp5Z{o4 z>_U1rHX*C+t3Ha#ZB<=WldN?Q?{83uzb`7lM_rbd_ZVv2R*2oa10Ajs0|sI zT1$rX@~ZB+6Q+)lp`DS<$Ppxk|nhfcu8LgKFXabq$)u4J0|`HpRDG|t%jak z4;a3XY~KrrE$$&hZU>u0s=8`EC5Ru_#Z}$aPLf?)d)p}4W>tq1pw_gj$U~1|Vrpc< zp(9+@B=;)vl0nFD($*f9_r*~uf9B^Z(n0&P9PD5|ZWv6urrkCsu_b%^B`@}Aw$=e6ca!3Pqn@s{+`9&KM^E2Fz{WQy6*&8d35py z8Dj03yff(9W^H*qrtkLai6_}!WGE4wNgzX|gGBcNm4o8>_Q=A#aeI7=*n}F=WhD9C zQzM^3d$+3H`#N42cHPr4+Zx1l`Heik>)29@<|KJR{5NLodnD=33-{3mK}t4Hitd-6TT@ z^GRT^Y-DJ}VjLVLaSbaXq?n2k%9uZrzH$(;J*_?4%Oi(wp-JPCMBAR$5!Q-fV0Mue zgDGTahomPN8dvfjpBi<^nu&7aA6N!@CKW6|`hSLdU!suL-G@H+541-&L@300H{wQ* z^fu+SrNmDQtvp&LEPj|rD$1|!B8S-DCBQ^E49uSK_dwH|jnX9YL9@$lSLa->tHS$OZVT6r;cpWf^q`@{|5ZcEG zV<*Q-r$$^-X6~4Stq#Sa9(O%L62CMVDmxrD-4r>Rm_m5FiBRrJ^35s^B(C8tAwvx; z;AB~J2%#OAA?X+>07ucLDu*R!?$r|tfXyDr9VgQJ&6FZLdyXrDU5~3x=ENwUX`+{s zDM=sLVdpw?_{i4+lm(9cAFpF~3D?b6d2@f1e9=-m@uYFh;mC;Ir72Jz=+oG0cuP;UFoQf6XFYG~a4htv0OE9F;9*~Xi#!bh2{-SIvv;>gj4B!!E@R~@Zt zVif7}4qvIJFZK`DziHUp#gN~ppu*MZnsG!~?%4r5{h)%f-xRVj-1q4VgDS_RY0(}rn~l=OxccLtI_?Tj5V!}9 z*(Ss#JxqIAZoJdotK-d)_Q4%Jx!UUW&y<$C+t&1%o{4_tTRnx=1O zr64?VyH2L(%bM+EIK`P;Pb`@ZE67|PsvBz+YTmu;DPpW!|8wA@_%AyeiIIg@#GE1? z9V6_Jlkk1LN1tJgnfHM85yDebWZ1@duuXnq#jd@Si6=L@`kkl8Ojeh8`@IkQZ3*ye0W!@f-!%p zK7WUojAGHmUhAQ=rO&R`%%ICVc^y56ZVeAHud#e6(6jnTMe$R)m9F==ua@$a@i*`F zKpQvL_`X1qp)J1R~t8q8Rfqi$q09Ks%-ITgBd zl+KYsvSH2szlD{r^C+jK4qy~>YL62ub_{2w375qZQ-b-y+ol<$Svp%FK|4=h4pJ>A_ z>P^@X=f?6zg{t7$wE@QT*=-SII%Oi_V(s4xiTGY1a4^-+4mCfzvR1l ziH0hCeK4J3-G4cIMBVq&t8;NR-Y3K@Hl&Rg9^KaD#w1j$w1^B{O3NU$_^D4v_$h#G13~7^)r;$c8yXobX8anf>2)I3zw>Sg&5{|j=ujYa zU=wr$^Tc{~KD0aTD4|}=uY+G(5a3pUpVV{~4Ly1GX( zG2VoDhT+}HhTFlT@Z^y|u9=-5I^7{dfO0aF>qlt6M}~&Wr%%A=pl_Lz?h^XU;~zbpBu1&Q@u2$;u(Um-&^ zHC=?hu$g2o{%)X&iH>zu94*45*C>liMqprN1IG=rRA!36;7vz{o@{^TTS}@Ul#Qm6 zq1OY`+F?=1Y%(--AB!BeCZ&|rmGifl<1g~^>b0knA?&INK*7cMuV^wvxLq>F-%&AX zoD)V08Rs9xOl@rsoHSGNCV58zxbby$GA+yT*M0tsvN``1#XlpaO?u_mRzVWIEkcHT z2kgCH24axyN1BnHj{tdbQ>BsaWax7N;6nv4=fogL<`!Xfd%%_SZ_b2sB&LkhKYvd-H1twUIsdlY|SNL$MGxih3Es>Hc zXoh!@e7WOt?+Z>wii@ICFRW9Xkr!Pf7?5?$=~6rT$@xYV`?c13s(6RDRnf`1C}QOMbJ4F~lp2nUd!sWP z?Rnn}a)C92fM8-!WKd*a-*NsA>%8g>c`lctQb!aoZD-;VTXiWWHtKmB;?YC>wyz_y zSGRCJGLkh)Ez#A{(Pb0WUS}8Q4{q4>Z*=!ub9={@&(%S8I$L$rtmBo8_ZctWwrvyi znBncx`_m~VJuSq#-0>oOf5AYrH^uO11^%(+#E`FH$7bC74p$8oB}|c_46m@nscEk< ziBHe5uQSe9NFY}|8tZfO7BfAO@X}D%^z<7!KG`HyUCt{tF%4Utc=Xb5ooaKxh)eUs z$^l}F5?|Ha-G_h6L*X=!&tgP@8aFiLa&5w+f9O3w)5z22}%=? zD6bPyL>rvj&8Ln^i^|^9!*wHt=ajSGTo<1?j*2%9HQP7%zC)X~xrv>-) zNBac-o_ngiKH>LOA-mAgy}xu~pmG8c+H$ZgH9S$stn(t)p)Xwn9qf#CY`$`8%^Mj< z$1e&)x&o%5wg;3wRvftT@tnrxVeg0S#LPBalVufl^#`?$=)t>z^626hmO+s4T8GB% z{nOd%neVmDn!avbrOk!@9Cd8;@hah^g?EZxl}_SD_=i4qi}EFQ&uE#6SB0MDKiJTm z5pwsGYJ0=M`{CTCFEQ3TZly+e^9m2$7vWfZdH3a$jW_Ht@$qrR{Wcx9D#Ejv3ktn7 zV$Qd*WXh>&)&$5QUh!{())>D!o{=?F))$5iQbZ7rPZmZ?0*<2-1n}QY_&q7=Es)eGFH&oV2)ZcSAQ+wYW-k`obB) zr5kIea#E#E68fqob6@olwra5wU&Rr2?AIImDmIgw@7v~rI~Q3n5_!`lu=8WpF5Beq$!{#Zt$O9i zP^@&{hm4LA+Ub0vh9YpX~;ybZ1jlIB-3BVMQH41MKPn0~pwC`?<2S9p7nyy@kd z!@R4dm8BLxco1{Wg!x0jqA~uDr%R*XDDk?09kAM5GBkL{(ew*3 zli=bozmu8YYvs$t%4Rjc(AVK|8}qJ+RA`LnOiLvYs_?^p;~_q1ZAt_}u3PY||4q-j zoxhXR*%Tr2f$;irXL|bNt@ymmz-NRYo=Cg?%XvW$p7t-v%8^o4${)(!N@7O@gh#Hw zQ2ucUch$(C`iZcs`c}KHva&@g?bj``JNBAq-QM8AH^qcG%9i#hj_r!GI`f%z%PWym zuePi!D%4wiDR{%p@&_@e9tc@15)wFlWruoCJBZbnI)YWE0o6h@p?jA*IN58(H_R{< zT~;*mdOzXKqM|Oo)Pqx111oG*>fU5XDF&QM z&K;jo%7WMB^2a7Glc9T?n~=oo-s7X%A%yPmhh*sHa>83x@BeE_xme`v-s&-PrULD* zcYK`NdVEJmvBgU4Cj|~WY(YiQ@cwd6e2C}j!S^%wyI;18*?hIV@+CbfCYINPD-$=l7`WBXKK&Hu%`L~oC9~2$#@~-O zF#6<1_9f!0*0HX$Q8dz5JtzFR&?rzm{m*>2U@Fr^?^dV zRgsPb6cCSfL{1?O6AIu>mZd#2ZwLcQq@7^1vg{3^ZoromJ>*A}$&4JngdgY$lm!dA zQ$57q(SZqf^A1-sEm0i zInyj3N}m#^3(|AMEAz*To(%*<6uCP&yxv{gp}^JIRDeuRSDNWJNi(oae2E##NUPQp z^NI=GfqprDzUdXCe11t$@`S-?Y?^dAQohi{k;E0a*X=$XfA7WmF1GsOc1w^GN_ew2};q=P{@7=i@d)YvCA7&rc6H|8l&MWSl>8XbgJD9vXq+`z` zBTc_QWR>t_a4o_WDLc%Yg20;8Hr71d7ABE!=LN(p3wbTQ!2L5RohQW2fVGD`eX%ob zyvyftiBJrNMw!UzH-sSMlyrLJ=yYq*ysF+)ZLg6dzMzh`syB(ZZW3roi|fo)AdnD{ zOlct!wc9zStR0b^t9x4O_<(jrkJe4s1CR8h{te92za#(S`d7K7&$prX%}DF?=?w3S z$DPz(^!k9;K{Q2FxqXg()xWL^H8?>my66zFBj!;J^J&%#_wQZYH&RT$=>vxayO@}6 zZiAQ@JI=pS>>lU7?K)`nVd2O}Biinsc*3y_&Aol%uc{0Y@v;zGVZW@w&qH0Lg7_tlc-lVR+tSk5LH+w(dWo5&U2z?MPnw{zU{O$vK<(nB=(#@x}cQYOOf*O-(m(Xoi z%I&-Rh>tgD`KLX_8NS=lhF71c^F1)Kj>?jCwQ4LIySqC&`RkLxPlipc(ge2CC4ukh z6ni@BhA&ROI^H|kc&&UNmQ+_Z+G<#*BWt9}Uma2}9#Qud%^OjoougKkKGAtp@9t~i z8@UND^0RE#$7%>2y4l{M(f;Pp&W47Un1Xdy*Ov&$CujZ+j$tQ61g9| zSj>ClBd2A8VPzb+QPX!}lCC%*VN9lL!(6xxFA-^Tw8ak7PbPkqPVmPDMsCPMC#O~~ zO<7tM(=@8|rtn%cvw1;}&s!O9cA@*V%*SzO)dlvibP=x$^(1&NR?xl6dWais9rmzDK=5dHn(uz=bW=y_onDjA z8b%Mt*L$+|lgQAq(EzNVJjq4dx^C(q$(4>)`z| z;zfbAelMgmj=#rma=6{U=j{5{Ud>pJ6`x>2`@f!V-&NzhUF1GMP#v9qW4Hs8;3mbdn7zLM{ zz5U*$pi|tDyC}bJMzzfI%^iK43k|2DuGsB!e1tZx^E4|7KLHl`(r®M!1-3YMj}9wU@$@ArERmVqB(!J2oC$c)G6k(Lr(7UiEVw!y1!iIOCJ ze$H++Fl&|?2=Gyje4ea_GH}Z3z5V*$ZAo#ay-#{Xb+Q7?mjvsxvn^>gy>$Oc>bi3; zQ^clD?7r=O|GlRtAGKaU>CCMUJt2 ze#QiD(ACvEro6W1A;Sr13PQ%_OZJFQ4FET?jl0bJ>OqcArlq%=Ci&}Kl^yzH>T|@a z%yk%3)eqiG2`t^7m6<7_LxxbUDp|*B4bYo1>X#TF@;ZO;igmi9sY**XI^zIG-R*5r zlXNB5XF}A`Lo9cRbuL-;V?D3mbdfG?+CLTic++I+-M|~X$HUe3&&2da-ncdW-dxZ- zT7J@}yC`kQ*k3Uwazei5v0 z4)fabuU9_5TMC^!S-P-~@n6};STOwWR@q@)OUfjk$Tabyp0$5<)uW0`5PAoTDbZ1gVWi*2F6F+zUaU(k51zIE9YOLQteXkTgbEpTe& z;8}|+@nw$5cN*i3-us^iA@eoI+^j;uM(ynCXtr?A+?c#-g{)=6!xr50IMz&yN|1+a& zQVSXSxL#+MJo3%Um3l3iJrh$QTny$7rRV!PVyYc|)XYS(kO#?7YH7;x-9Fk99L0CB zjr$Wxdt=S5H-7+Qcu6w!nlP`vhA+3S4(@i-=DF##5`X-3 zV}{Eql5BGG>VT-1=r#=Bsi7y2ME!$bEOH!G>kLHS+jp$od1cE>29DG{V3W7hPd_F9 z7~=HN>q~1q!-i4d+(A|CmBJzJII(~DiGN)%cVvCReirQKf5?7{iarVwZ|uIWZ0WiAvvJbR|NYM~6EoPi%MEvB{fOGbM(LY7*==1Sh+59Y|oascA{h4Y)05(7y9Z zL264|y=QV&sgHb?=ury~`p=xm0lTP30i7=P{*7;@i?%d-Y)~c{CkM6 zZ^wU;D1UGprKhQruA)Jg86k7+`W2y)KJk}oDsuV`1ngP|*0Cj>eIZ#b#!bDSbWL{_ zZb6sl`&9GGAKr%WGi#`!I+7+WPMd_X55?Q~Q_m$V%~+_F^(r1WovHO`P2ug?JS?xz_RSC&xDXGnwx?4L9+>Pi+evuSc?eC}NGZ zRW9`o^SbEu51agHLD9llwEyl|w1qj`&xeU_^vp@*4L5~O{*tYF#%^Fso)82MsXp}Z zi7f24|8lK8tK;e2%Ls3wjLo4YGM|qmoLl`hCr499&}wt}ut#m-je{#y%iBfTo4W@b z?~)-rw}aW{C+phVCarUjcWuOCMuS^gTr~z7H4YroA@zwHiPc?)Sj@@s7n9K zH1T=CPE~l?wa-4zCJkqNy(xrOLX-E(y|_CmQOU9X$^NQ`=l(!@`nmc8^^ zuV}aEP>%0~rj1@sH=8ojxZ)zFF9%1TO3q6hT4fN%s)0&)B9njYS@w&4*IysH*WcHC zssvqrzK-kei9JOPair_AD>!axeibqMBG^H&cf=mp4Ngd&`docIaLj=a<#A^cv-RA` zTJSPkp~B6_FHT%8yx$WT#H(JQ9EQJhv(m8tIO@<|-|%pC&U)V1oVX+D4*fG4JD>Ot zaGROxCRU~B3+OePjAmd%KlRua26!AFxta3vTIIEw>kQTWIek2#70!-XDhlVY;+iZS z4^;LaufAG&e9X4eeeMM1Pp>}`{=+k4T_H1%NnkyHDao4=vaGs#I}(ekbk@6CTQ(pu1)k7Y3lm|PJ)@?~O;{b8}^kM3_atP}$~ z;2y}}BH||&5;#_S&77F03hs6#2dWY(he>gb;F4A{nEltb1tYt_%B3+_l}#!DxA8uZ z_JaFd=lQ4kN&5(6z2JsqWoOEi8li@VFa_S;wNU^6B>pS~4u=q2G1M_}q0vKPWa8`B zMk3$X{f4`5&<`VGi4yL~z0;zqFV81F?zlr@EmTo)=_`vYC^3D-6(9H6WAw|V#1oIR z+&Yu(TDMp>X6aUyq`R=1v#p9ZSX8zn=@i|QX)mcpC7IAn`xgUa%~{2H`rEK8Ornme z7pq99k9;ZjIg`st*^o0Rn%P7kH4T7s+TgWqEM$m@TW6Yo8tA`REl@s%qCUPOCrEAJ z2=$G8aBMnqs)*ZMis0!}y9I|whE@>sO+P4*Bw|Yfi6n3C_k;*!yGe)nlxY*8Cah~X z6xnXsJ}}vTnv@)CeyGA@do7Bx0nMa3P<{Ofsf*O!b?aqN87gxCkJq!nZzLd2%bu3= ze>$f2w%noj{_bV=-HDra7@YHy5q?Cn!CWj$Oj_e~&#BRSV}15}r+tEtGKYozm)Pua zSk16&?Ft!U`THM|)erwtkH@Fd}4+^*+C;w+@jbu3$$wfk1gtchoKtH=$+caj*aoPc#I}^aJ3g zS2_V~BpXK(!IUWJ7PxjSuQ#RCOsGM^uN;57fxuogAgrcOs3w6e*FJaf*6n(5{=71w zf|Nk0eFN@R@`w=E^%s4KgkRC!wW8>3>v$0VCgc|a=x!_z*z9*GffEo1mIRXm+|5Vz z;J1yBu$n&|n10D|jeiuGK$t!}Jw7!C);vb+(gDtqqv_xl8S_hU%t0k(3U~$Z*7PaH zl#lMj&wgbbQ;{`DVlr`>=&b-=2QFs@CUkmJ^}sEh1{)dCx9VW}z?;VZ!6hQ80PF}7 z*FFGyJF!FuaHCW`jZpcf2c{3aFr9Q#Yyv2Y=lY@3q}WkCaOl6t7u;P1eu;G1gfMDI z%ES+hM%5#`I`L!((Ac%~MC7%|!7ws(p1AUB*k^P1KCt35$rIMZt5B($*O0wsubpqY z;_>_F6lF5x?9^+evSpJS?*`lFCbgedY@U%Wk-QM0nYjP7cw{qi*rj<;}d}it0(>78H(#-D_|4`D<_{`uF zGGr1Q9p8(rr0##cjGjybdspR!fcj4rV*{ko9DdKlm*zupL!C2UOUMu}uLVC4NLeM& zk_w~9uWdEn-ki8~zuxtT=Ki|79eM0HV&HJ#5O=h~^2gYut4A!C8L=ivsYElG-rv&y zraAk?{aBJ@#yIaHsT%bpVe>t2byjKVzg}Z9n!X=9jelO3U6RnCJ{iAmjb8BP7s#uO zD_Cz=<{jw`8+4LiVVix4v}bFLU-;EiNQ4GmPxtUlX3>p64T5w)`2E&q%$3tlV>?=6 zqGJ16z|n7k2)EH%FOQL}{&$WBBh!X5mgiXvOFes7vtzN#J=H^a&WE2kAl)onKi6>B|F1WL6qgfa@7}vve?0gPloR>vacIk z)wP>4Z-a+>W}mDoUY%BNu?=;qb+wHm8S)bQ31Nf+V?qL z>ugklU#a0~+TOG4l@mb9;my``!TEzCoed4&TsOGaFKP|mUz}~)Re@E6< z<7%mC*T+-KueR5w@gu-Wq$qIHd7FpwQa)B#Ta&gr+0N8R;opprgz9;94V9`Z_o35j zj0xQDm7Wi-551G&~fN$uU{JB5!|c6eQMPqEE> zmE`J>rRyj;D0c+;kpHr8L(vO-f?v7bXW}q`$?&X1V9xi3& z$XC{+7O_DdGQ@58sgy*9R4?`-Uq=olx=Iqo`jKB=jd%hJO>-Ha8CM4zFor3~*7<@x zQd2*jhyE1xyRI|OfJ1MMR3?1g>${gQaIJ+@k#mq_;(G{ed`}ama&N5|7MV%RBSSM^ zfg3c5NVzJR-`ca3vIPCpF6Y=Y)j<%CoOU;TjGZwky2wA>CNG&U2<{sl@C+k`a`TUR zPL->HNq-17tf=!G$JC=+ym}~7pfZenp)UXHFj5O zodJ>)T|LVti%2Gyfj{;FM=JyQ5*yz~NBzO(ye1M1|5utTzS=(;YXt|@k6Pz8rpZ6( z*kkqKiIM1JH^%0*6OUX#oX*#X(@yOxq(VHV-djf}T(S+4=NdE5>2u?GeKXIu-65?( zu`JSDkYg3<^W#%n19xZkl}+2``A=iBZITU7@|Q1ve7a+iz+^zydy*MpFdCr9zp2}; z(`Y6;0z2a{Fj*oY5$Rf6Q^38$O-<*N_PY1CN`vEW;Lrx%%&>YgZsIXXc-5#rlh+GA({V}1W-XJ5CkGFgo{K(zbLRRC zBN<{}>xI~O%OQ_5RgcqEQ`l8g)^>}*vmRlC5<$O!ou4&~+wcOXSQ+_`ZDw4tsKVfc zzzOwIGu57NFD*JOotP*ThdF8-asq=vSv*+sgpp4hNG4vWQ(=g8f@4@?-Sf{Sy&i=M z;~O>{ zRU-OJ_Bs2!^WNF_yx+O+@o!-LRx;NbV}5gt@B4;!PV1O}{>G&!XDVj6!t*T!)X3B!oV$DTcAu*nU0Nk9kQKtUrLBuI5<-b^K>Cd7EdXp3$k;;b2V21=?;{5I}k@e5vH-6wJV~mA|Vt;lFK%h zy!v?r8Gxjwh%0O$ZO6Cmu|AFIP0{{*&au6YOGszi$kS&pW>p7_b!HZIC!E#t4j+}h zLz5zojT{6^i_|7hwgEE~9#8)r$m|T> zXAK?=xW|LA**N8)fIVCWkUt;Wk9PwYwDQAPLpeSfwk@%-FdZ)f zzOra35`T>V@Fb;hnLrj1gRR6}+M)wQ>QJOW?si-JE990285G_D7DH+f(_GxY#4qVnZIsV|=S7I{+(ZVEo{h$%3qW^&9x6 zTY#@EzB~=+x5Q0tP@RN##FJwI`}Hr^EElOmw5LQfL5Xdr$uxk2`!|bBz-4-Lg06PY z2pGq+f&}1ltF0Ni+TI7q>Q8Y~(v{#$ew$Q|Tafl-0L!Aj3UIrH0hz20=(^@5blY4& zA2LJu(@!RKQqQAv(_s*cd0_-zxn`I@Ij3qlNLyo6Ok2;TUTYzCAULhIqcx~eL)Er2 zx4a-Kx>Ts^vpcIYPNeUoGb#ImvUu-we=bI#>Nf_kZH{2fFl9Mzaa$%*f zs)hv6Do@D|v|2Sv$;K(X11}UW*Ck||BXrG4Vr#;^TA+~b$8EnyKAzVvD-@eRKD9qg zIc;UjkABrOuishjBB157uSBe8@S|#5SnK2pu_9%)v_<+foquXXQf6k-y|3wBVj=Qi zdTy{B|EGKz>RT(=eVVE&mrq>J+^5754H3RWqY-g0!B;6QSnZ@*OUrdlRURcS$exfp zkSS0?``cJ3Z2Num-2C$ob~ohyk3-HE)drn7u*mz=gP9mrgo$izdmWSPWQX#Fv5C#& z2P9p_;%}R8?Ef~%Sd}<@rbX<~KJPkv<#!Q=mm?cB>ftIXaOTi1I9vVMLP6@u2%jb~IE76U3UZsyQDj|#~BV36iECFH~`b^l3d*Z0^I1$4#f5v4%JZg?pQ!`rl-rGJ1 z#0tD6j9j^qbQPawPX2FTwtq`J_3N-{OQ1r=T6{)6%kt~rK8;L&=vaHGmdP>FUQE`} zhJ-ktN4LMJk>6Hqa%TM=zQw_Wm#r>}&@9CwbBZ<4bbSXB=^A;zS8VtQaR(yj>kB~X zEp-)gwy63ZAK9aZlL6b2MRN8I-|%#+7kQd!R&P6TZL6o1@wg4Dj6{+y!oR{BIX>A| zP31O`6lcq8y$(!aCDQnEHM_?+Fh!r7Cj=tmnPhIhi->>JVZ^3qd3fT}N3hcs4K^3e z#Mo=czN%uN{XYNK+~9v?~ZRZzFjEp2*eUJ^c1`Xcx9ER!WP$W6km4X*v@sZYM*=8aXzHIosXmsn@EqzU9A$D z%xYqpq_asV({VX>-(TTLZQ@td4n%|$j7wgO=a+W7JkL@Y-+y)XbI;JdTbTaAfhQOB zUk)<4O9f_qGGBCkXLc*hmG6$>X~QE@&XN~ov=7yaoM2Nr>8tsS73F#Y09WQGvTPLs zd$g$OWg1xh=@s@$JRb{GG<}-ppPi}5>Ps(A%Q|*!Lc(Hw^7ha2+ke_{?zY5tTjKwk zmiVv3?cW@+FXNb`ElB9i=cV%FoA}`&pRR6{TDa3@D>f!XKQ%U5F!AVQAKtWKw(^TF zy^gR50}mhHzREDWf&HyjawB#FHtIRthmMX=!fRQO{drTpHp3gX(eTqYxR6utuS=zq zh0kVr8m$$9xjgopnsr*y_obVO-#gn)(Ts`7k=Syvw`!(F25h=ye7BBOr>ucaOtYq@ zcf*&b9f~g)+3BlB-W#p!(}s*jEWEapK8%MNH|$er5RQ)tObtK{mF#1kIK-;$<9CX# zzavz3g-4+guIE5}RWlJY7$;=a2od3E@~akReV#-{hH^s3G1Y^H0#)L3ik8yqYxBpJ^$0d!GkU}q z$e~`z6{`hz)mcR=(=kGhy|o%V#dowKE{zl%xUY(+z|N&hHx}Hl&7UvSHV@D6hp!93 z&l2V9zcHVTHID7}LsXB24fBr;i#1qc<%`Xzw#}$IKg&T6eEVS8W-IMF#&F>tgBgc# zkPI~wz04RrVw~pQWUm1kNSc3hu-#2Cy9wt1c7pjW<0RIMPBu!fZKCmK-uG{=;kUCg zH`ZBSqC_#)6@p_K6=;!C+gcyA@;lC{fi<<8X*Qnnahblx2^F`l=R1Edn!|P{@FwatAue#SJ z(31#6?&*T^UU+p;jMSx83BB*)(JqrIk6$pn_GK=1g{`iYbAOU$MCP#afmFWLu)dBq z>3;pkUqhetN2TMfwceZhkVU0AC~x<^J45$+>=NhpD_h*#^|=Nft89^Ds#e|AjbZ{i8H6V>9x|gj^HgDgkqvB zCG14R3?sRDyc=JV=x)oxXE*)z=pj~0heCqrVOS@B=e1Sg(i#l2j}MK56(>>HPoOg0@k2TOw>jS+6NSG z^I{4XyGidhx6eWM^o19kd4QfpBnAgQbw*lV5T@-Ko1s)&G53GUIctipRXTRTgFcPZ zJ+yJAnWrNh?qn8$&{C+tGs-Eb9U1M7UF$%xs-MPCxXsm}M__H2NV^->{}y5Wv)xbzA7fdT5B$$SdT{SA5!%)*(hd+Avcb@9ZRYFh_h0L zZOp-tO+x*`_4Xi6-Tre;1ELyfY>InjuBoJx5aIT(3v6PlVIO)5UaX(#uVl1oX~fRm z!O@q!Mioh{t)JQOBAeU)sCxDsM6-HFC+Q}6MRQ*WNom;Qe?7SH)_o=~FF||Cx%E99 z`$i3l6d|ECxqjjmq#0VbKS|)+^(6f(Ptsi;_#dLf-*>G+ivQye@(jlnx3d!y(A`9h*|~3LG9*rK=M?cu8D2+tU;RRKp4TAEM`d_MwIkDl zo?7of&OT^Ih1v82+Z~LG83R<+ANeJ*hp-ebg)k?Nz;%8)6*%fk8?N6LzvH1w6zX5o zJaij+f0fJ5UL^S4d8-_3-U?pg?9(@7O;OFFj@sja1`3*|Iow72=8jO-igdWq5fdC> zj_xD6Sw^W-3*tAL9}WpLroXah_x!|xl&+F8SV_(np82!n9>6QvHT(Swv)|po`ZIww zWI;JzNx~Ig!HW}C4$S&9cZulO$m^l2uE_?aaT9rzvcBE03z zb4TG5psQp%)coFQyPq-Mn@l zW%7a9sDBVgJ;Hl`=n>5|RttK)SQTz}l_IgxRtE#&p5f18L0eYrH|Q`az>-d>>&d+L z6yH^I6*()o^Yn{eMTtRj*dF+nU6tMNa!I!N%%7yi?Cxs2yV^gprpb8)Xd@E1=8Y`r z#~u;$zJwsA{iwVxNp!g}CPw^ugGz8}3Yt)vY~VcKde_i5tA5O(yU5+0p_CWRW0~%o z7G2=WXl!P7I3HQ=(dycay)%q8YxHx7`>N`DB1s6HCqsRTo0je6aXK{^W)N$Mvx{sk z9eBfc{#n=A&imee!8d64G_ZEj(@t%W=7Hf@_PRiCj3`ceuQRh$@Uvbi8w5i?k6vB+T` z2v616&*g>>6l&KTdfksbB83pqa2?bOIqc-923O$;YGl7i-4f&Zy~M8lP%LKa;#cX1 zAJNMq4KQ}u~Qm!G>?&(-M6HpSM|W$^GiU{LVY0;L>s+_|-cQ z7x9)`l%9D)Sl^MxPQ#PmGr3npHs2MAx+4p))xl>a-U_*EGpYueiPhCN)|%Xn&rpm@ zimDzxWgeXQoh{I1L#)Qw*A{0UE+C#nn~|(=V9n&?J6F~mx_V_xOYu;0Mdfgc@3wP5 zLciRRqv!5UCHtaRo_z8U{U+^=y=-oKr@UX%;(^WW$~XObm(0H|#aLL)`5!rXWmb%8 z&#PqL7YuLeR68?eRpew9_9~p^9?>4YGzb^%TDd>i)aJl`%A7OxZFC46EoEv$FKc^P zYkleE^OHOoCn0;TLsqF$#W8L!@83X6te+&O1`i?E3%w*B+x4KiAI;#Sb7{aT4iyi!-Gd8Vj4&j$Z7jeX+C3nX;ky zNUE z4}ps<)eTx{lQaR_#0pGlQQ2*+J_-qY5wkIvM#X}dItLSp)`ZyD!(4o}l z;UQre_KQoLB0Mi&$eusL-p1n5FEx(5*Z9Xd`ZvYszoD?FDuA%~Ha-A1WleOfAJEaI z!wl{~xZJs(IMc*Etk6t0o;wheE2dA~blpU`8#s2VMWJSV_|CZLAikAg2TFQZ?iR>r zi#^H&&hPH=82?O9>mKE89Sq_$KiMSbLV0-nWTN{?&-NBrr&E4pX)c;K1!}Tpq2qF@ zHyh7V(i;OUT(^^@(AeJj*k39&T4FVz!s@y>;O%oB6>?Mi{Jna#{l{}%{RaAdw@OZl ztI1yZ+E9DX(@N&MRBLL^>}@b!=JAK8Ss4$uY1uR7iBy0|l~1{c7!b9CTg^(5mquZ_ zU*H#9loq0+?@M;)^Z7e_Qj!QUx?cWF`_t<>O@b0u!%VUUUt!$yTeqKTL{IQ$_=KU= z;j0aI-w^Zdo?%g#`#Byu-%3LIWhYOVkjHB>pckkzL+0o<72}MrX7ZHlO}rO-Pa|L{ zh)C>WxJOL5OR=>QH|QEJ6UpLVz3`}Aw-++}!Pa8Ii+=w|^BD9pbMcQkKL?SO=bmqP zelF$cTX=>#&jA>}0la5_j81wpjHDcYL8=j2x%$z0;S-`(DYHX}pkMep*9@B zmh3yaSgeMug&S|Ahxd7=1}v9sDK?Okbipi~H!16=w_TLj@ff<*Ww07rXwudj9{>-M zfklMd^y^-(e%P@`j$IB_6KCCyhD2RJPUUczkQA`6O6JUjslqA~N{A4J z(Jj+msU=$;ixq`_AA^1MOAhaXE(Y6>iZ#Mxi7UKxa&pYR*6RzZPOt3lWESvleF=44 zkg9#{$HEGg_c)>|PG%bnBDfRi4`a=%Yb&C4AnE;v*`|` zF6tF*m`;0O5wMQIDhQyw!~0^}3d?Pr^=Wzlw9 z7`$0(w=~>$u=`0TmPttY6xLj|SN$rz^PSbYJI3)Uu8;cAQDg>9kuNeL?uHHarGv69 z?nNR4$yU|=uwsXg4FE_aj*PXyUeX)G9Eja~tdU0j6FDTWkUSVZ@f*;3G93kTP=#sR zt%sG@P_aLCfV+g2|5|wQiw*l*LjJoSIOrBabOwA7DLTe1g z4M+vD{5s6nfI+zJ0L2w_MFYhRp>(coJ&Zr8j=uxwzq{AJk*g>ca(vHu8P-$ctb1KK zAWBrEAMPz{@f6*mnI$@mG`C|<$L8|^Cc}K^OK>O8k27coN8!T;YXi_BM2XA`Unyci z7KsUEYhEBcI&69NJtRD&u=Q|Z@&UbrR}1Y3d?i`LjR7v-3D?-^#{uX!vkv_qwBBAh z!}@6ElB+Qo5>V04mx#|juJ_dVWXb zThAP-7%alLgD?Y?fCrcXO)NxKhpo@kF_lrI zL0NeVCYH#%E6RQck`%w1LusxDCKN!I`fwq4lrU(xI!Oki zn<(1?7t|td1W91FCmq?ghYeENLhA)yzZkO9Cb&j!(9P>XnLaM9ZPZ0OZAu`EoN^pX z4t|MBRZvUEcr+FO<^KY1c%zCg;Oo?E@Jw=T_ad)abYuYUeJ!7yc-Ry`(_;&u-UdXO zc~s-4cOaH92b!(kC%xn|KoVYzBil}^??CQ*-U2f6HuBwgN-+TBv`C^P0OW>1JOv@j z0pSXqfa}4=;if?4PBUi*GGh-Q`0uXChLSE)5np>q66Yw5x!V_qaFlRd2Yg!)`28+y z){~R-k5fq=N^5^uSB0hSw<0OIxQQp6%`MO}n4`hwFkL`y!Ob+>A$VPu?sq$e)XU0&#V)Bmzz5(B`cd=_L$R3P+Qkr+= z9@5Lkv`@F`!XIz6U$&UzEbvNw#=SX_>PaE`=iw{oU(GP#L z=PJzN21Ra&&)Lqj5I2~Wbc#Q+up%@bFsFrHa7mJyUHYw%OaU zT`&=8Hs>~Da~KwQF#z1WbtqrF2f68~&QGGVuzBCp?;iQY9QMj+>alBf{9+5Iuxr(D zV02QZ?O8TorGsEt1(VJK=E!nWkCe8$PRr}!z1d3z8EDpnA^Vgdu0ax_eeWL>4zF7` zM|RpXblsVF*`Xz8E&>U?ejtH5{(NtT#UDHgKiKadM0Utuz4HG|nCxEj&!w0D$JWj9 zfJY?76V_yr=Xr(ntWQsN++_)YuiR28#(4MDA`@~$!l0ivPL20P&5E6dZs4WgCDnBx z=9Mwrq~a5D)NaL!)6en*`w_*HdiuRKW$|X6)Go&gp=YV&w5g*HD2Y%#quz4#aonH@ z6A){y8)g|URHF7xu70agK)>&n(ZSFO%ih+`VQnY>p}&u?ek93NolQ9s5G{o(sFE&i zzUdlzvmC!&*~enI^dg~r0bvAdM>fosEJ}?Ql&4$H<+S=xcwbB(jyugox-9M=2Q5uT zXQal+m!^gYXFFKDMU+lT&H)RK%3?g=@3>x0e%gL8tDz;$TU8E}miAuzAY~d++cubL zQDD>KB8iE4onx$U?qr>Rer8^V|BD;685~gdj(AY}0S7VQuLQOW$_F~&uarUt<)$1L z;ID+DWC6KT&oHPrL4m!}3h*qk0DsbV|AY8mSbGormB4P?ZH?R-=*9j13Xc^a#xSLA9FT`vMqmN9+3Vl3-`ASrUfS_Fvr7hSXX==q zF3e7)jSj0mt_=S?)QshSHRdKTg1PCGA!3wpOq1g*R8Wz)7U)s$VvoexZD2yIF%ctp z-Itn59B1iiw`pmT9A>wZ?);{c`kSuycSH{YjgJ+oa6r83(tlo2UXOUdT*d2RBh?t$ zALHwzqt2&lmKW}*nFUv+=gU7W)D#z~rKV8S>#P;ID3!C8{X|ck!Rc`NGApXEGxb!7 zi`L}}t+6$=k180?prLOQXH1~J$VD_PCRTF4xV?uj9(!n9zBl=pET>hOdX}VWXC1X- zK>7N69_&NYYpTywx@{Y+CLLUPR4$8`=DMxBMCLX(7sD@v)i-#iAQ$*#=^Cf5`KW1i z%wx7qPf0b=&VM^+u{s92-KrWCOZ5r2KCT4h$Q@j>A;vfMv$=Lo~|pQdPrMn28@HYIntSA?qK8__8gg~Wh(K^vE^h;s|} z=cRARbyHUKWmj03s2zikD-M|k%4rAQG@6?FDh#S%+1Y77ro}1C?Ds**lOA7jY6g|| z9|xr_Wzwtt0)ffrLvvEHMO<7Y7`W1AE%(Lc&yG{c@Ti)Yk_Q-X*nPCRXGPS zT}v~Q<_nr;IIm0J?;#GZYUf#5 zr4EEL#VGQ(pbFjj%RXz}UU3Md#d*QHka_t@7l{ETWhE4 z_kGQnqf;il6*&>JVlg@HnD6myZuTYii1qQ3)1BCJT=+^Ap9sclMS)m2^e+26PZJ}f zKSNphyEJ*$TCD{Bu-nYI#tK|B&r!UwbXu4&&e5m0l*CGWc`&^*Bh+J}b>;27fVxGp zloh){U;XyoPbjupR9oiKI`@?Luj<7As0;jNF8jYugTFg@{stcZ8((sONxV$b{k>PN zp>wXOjhw8beoU2%bRVsK=CojxGJP6piMSr(euyb|gQw{ttdp%|Q|7zI>5>S-yyzeh zpQoA|E*@)NK~WwcVM51J?&ZES6m$rdrwzP@Z1kK;3fOa2@n+g^ex}!vQYhRkr-@WF z7CAm}+|zjpN?b|aHzEDt7AM(_rpZ--MDDtk-qsdd))0M|&}tY__L^Dn>En3zZNKv; zXsYr$x)&}6zc7pmMBuMlN3x5eB4;&739pgQ-Lh7W?m$?R7b5+opC}?H=lv$;XFY2O zD>-*agqSvWjbtze$;HlpVk}la7u|Ee)yd|0|HQ|BWMar#C%*(-Ieh zTbUOFNXB0usET{rObwTva?2DbC-rM6XL9 zM+Rpt-R&^sh}{XE z)7O>#J_{eCwpDlRY*(O=Y-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSkxdHA|FPC?Uy#b;&2jxh_l`@A?jEgEV@&`njxgN@xNARl_7u literal 0 HcmV?d00001 diff --git a/client2/src/index.js b/client2/src/index.js new file mode 100644 index 000000000..7b5a6e7b8 --- /dev/null +++ b/client2/src/index.js @@ -0,0 +1,20 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./js/App"; +import reportWebVitals from "./reportWebVitals"; + +import "bootstrap/dist/css/bootstrap.css"; +import "./sass/main.scss"; + +ReactDOM.render( + + + , + + document.getElementById("root") +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/client2/src/js/App.jsx b/client2/src/js/App.jsx new file mode 100644 index 000000000..5f5bc8ddb --- /dev/null +++ b/client2/src/js/App.jsx @@ -0,0 +1,371 @@ +import React, { useEffect, useState } from "react"; +import { Provider } from "react-redux"; +import { Router, Route, Redirect, hashHistory } from "react-router"; +// import { hot } from "react-hot-loader/root"; + +import * as Api from "./api"; +import { ApiError } from "./utils/http"; + +import * as Constant from "./constants"; +import * as Action from "./actionTypes"; +import store from "./store"; + +import { ProgressBar } from "react-bootstrap"; +import Main from "./views/Main.jsx"; +import Home from "./views/Home.jsx"; +import BusinessPortal from "./views/BusinessPortal.jsx"; +import BusinessOwner from "./views/BusinessOwner.jsx"; +import Equipment from "./views/Equipment.jsx"; +import EquipmentDetail from "./views/EquipmentDetail.jsx"; +import Owners from "./views/Owners.jsx"; +import OwnersDetail from "./views/OwnersDetail.jsx"; +import Projects from "./views/Projects.jsx"; +import ProjectsDetail from "./views/ProjectsDetail.jsx"; +import RentalRequests from "./views/RentalRequests.jsx"; +import RentalRequestsDetail from "./views/RentalRequestsDetail.jsx"; +import RentalAgreementsDetail from "./views/RentalAgreementsDetail.jsx"; +import OvertimeRates from "./views/OvertimeRates.jsx"; +import Users from "./views/Users.jsx"; +import UsersDetail from "./views/UsersDetail.jsx"; +import Roles from "./views/Roles.jsx"; +import RolesDetail from "./views/RolesDetail.jsx"; +import Rollover from "./views/Rollover.jsx"; +import DistrictAdmin from "./views/DistrictAdmin.jsx"; +import TimeEntry from "./views/TimeEntry.jsx"; +import SeniorityList from "./views/SeniorityList.jsx"; +import StatusLetters from "./views/StatusLetters.jsx"; +import HiringReport from "./views/HiringReport.jsx"; +import WcbCglCoverage from "./views/WcbCglCoverage.jsx"; +import AitReport from "./views/AitReport.jsx"; +import Version from "./views/Version.jsx"; +import FourOhFour from "./views/404.jsx"; + +hashHistory.listen((location) => { + if (location.action !== "POP") { + return; + } + + redirectIfRolloverActive(location.pathname); +}); + +// redirects regular users to rollover page if rollover in progress +function redirectIfRolloverActive(path) { + var onBusinessPage = path.indexOf(Constant.BUSINESS_PORTAL_PATHNAME) === 0; + var onRolloverPage = path === "/" + Constant.ROLLOVER_PATHNAME; + if (onBusinessPage || onRolloverPage) { + return; + } + + var user = store.getState().user; + if (!user.district) { + return; + } + + const districtId = user.district.id; + + Api.getRolloverStatus(districtId).then(() => { + const status = store.getState().lookups.rolloverStatus; + + if (status.rolloverActive) { + hashHistory.push("/" + Constant.ROLLOVER_PATHNAME); + } else if (status.rolloverComplete) { + // refresh fiscal years + Api.getFiscalYears(districtId); + } + }); +} + +function onEnterBusiness() { + // allow access to business users + if (store.getState().user.hasPermission(Constant.PERMISSION_BUSINESS_LOGIN)) { + return true; + } + + // redirect HETS users to home page + if (store.getState().user.hasPermission(Constant.PERMISSION_LOGIN)) { + hashHistory.push("/"); + return false; + } + + return false; + + // TODO: redirect other users to 'unauthorized access' page + //hashHistory.push('/'); +} + +function onEnterBusinessDetails(nextState, replace, callback) { + if (onEnterBusiness()) { + setActiveOwnerId(nextState, replace, callback); + } +} + +function onEnterApplication() { + // allow access to HETS users + if (store.getState().user.hasPermission(Constant.PERMISSION_LOGIN)) { + redirectIfRolloverActive(hashHistory.getCurrentLocation().pathname); + return; + } + + // redirect business users to business page + if (store.getState().user.hasPermission(Constant.PERMISSION_BUSINESS_LOGIN)) { + hashHistory.push(Constant.BUSINESS_PORTAL_PATHNAME); + } + + // TODO: redirect other users to 'unauthorized access' page + //hashHistory.push('/'); +} + +function setActiveRentalAgreementId(nextState, replace, callback) { + store.dispatch({ + type: Action.SET_ACTIVE_RENTAL_AGREEMENT_ID_UI, + rentalAgreementId: nextState.params.rentalAgreementId, + }); + // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay + // mounting the in order that `mapStateToProps` is called with the current store's state. + Promise.resolve().then(callback); +} + +function setActiveRentalRequestId(nextState, replace, callback) { + store.dispatch({ + type: Action.SET_ACTIVE_RENTAL_REQUEST_ID_UI, + rentalRequestId: nextState.params.rentalRequestId, + }); + // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay + // mounting the in order that `mapStateToProps` is called with the current store's state. + Promise.resolve().then(callback); +} + +function setActiveProjectId(nextState, replace, callback) { + store.dispatch({ + type: Action.SET_ACTIVE_PROJECT_ID_UI, + projectId: nextState.params.projectId, + }); + // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay + // mounting the in order that `mapStateToProps` is called with the current store's state. + Promise.resolve().then(callback); +} + +function setActiveOwnerId(nextState, replace, callback) { + store.dispatch({ + type: Action.SET_ACTIVE_OWNER_ID_UI, + ownerId: nextState.params.ownerId, + }); + // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay + // mounting the in order that `mapStateToProps` is called with the current store's state. + Promise.resolve().then(callback); +} + +function setActiveEquipmentId(nextState, replace, callback) { + store.dispatch({ + type: Action.SET_ACTIVE_EQUIPMENT_ID_UI, + equipmentId: nextState.params.equipmentId, + }); + // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay + // mounting the in order that `mapStateToProps` is called with the current store's state. + Promise.resolve().then(callback); +} + +function keepAlive() { + Api.keepAlive(); +} + +window.setInterval(keepAlive, Constant.SESSION_KEEP_ALIVE_INTERVAL); + +function showSessionTimoutDialog() { + store.dispatch({ type: Action.SHOW_SESSION_TIMEOUT_DIALOG }); +} + +var sessionTimeoutTimer = window.setInterval( + showSessionTimoutDialog, + Constant.SESSION_TIMEOUT +); + +export function resetSessionTimeoutTimer() { + window.clearInterval(sessionTimeoutTimer); + sessionTimeoutTimer = window.setInterval( + showSessionTimoutDialog, + Constant.SESSION_TIMEOUT + ); +} + +export function getLookups(user) { + if (user.businessUser) { + return Promise.resolve(); + } else { + var districtId = user.district.id; + return Promise.all([ + Api.getDistricts(), + Api.getRegions(), + Api.getServiceAreas(), + Api.getLocalAreas(districtId), + Api.getFiscalYears(districtId), + Api.getPermissions(), + Api.getCurrentUserDistricts(), + Api.getFavourites(), + ]); + } +} + +const App = () => { + const [loading, setLoading] = useState(true); + const [apiError, setApiError] = useState(null); + const [loadProgress, setLoadProgress] = useState(5); + + useEffect(() => { + Api.getCurrentUser() + .then((user) => { + setLoadProgress(33); + + return getLookups(user); + }) + .then(() => { + setLoadProgress(75); + setLoading(false); + }) + .catch((error) => { + console.log(error); + + if (error instanceof ApiError) { + setApiError(error.message); + } + }); + }, []); + + if (loading) + return ( +
+ ); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default App; diff --git a/client2/src/js/actionTypes.js b/client2/src/js/actionTypes.js new file mode 100644 index 000000000..57d9d379b --- /dev/null +++ b/client2/src/js/actionTypes.js @@ -0,0 +1,228 @@ +// API Requests +export const REQUESTS_BEGIN = 'REQUESTS_BEGIN'; +export const REQUESTS_END = 'REQUESTS_END'; +export const REQUESTS_ERROR = 'REQUESTS_ERROR'; + +// UI +export const UPDATE_EQUIPMENT_LIST_UI = 'UPDATE_EQUIPMENT_LIST_UI'; +export const UPDATE_PHYSICAL_ATTACHMENTS_UI = 'UPDATE_PHYSICAL_ATTACHMENTS_UI'; +export const UPDATE_OWNERS_UI = 'UPDATE_OWNERS_UI'; +export const UPDATE_OWNER_CONTACTS_UI = 'UPDATE_OWNER_CONTACTS_UI'; +export const UPDATE_OWNER_EQUIPMENT_UI = 'UPDATE_OWNER_EQUIPMENT_UI'; +export const UPDATE_USERS_UI = 'UPDATE_USERS_UI'; +export const UPDATE_PROJECTS_UI = 'UPDATE_PROJECTS_UI'; +export const UPDATE_PROJECT_CONTACTS_UI = 'UPDATE_PROJECT_CONTACTS_UI'; +export const UPDATE_RENTAL_REQUESTS_UI = 'UPDATE_RENTAL_REQUESTS_UI'; +export const UPDATE_TIME_ENTRIES_UI = 'UPDATE_TIME_ENTRIES_UI'; +export const UPDATE_HIRING_RESPONSES_UI = 'UPDATE_HIRING_RESPONSES_UI'; +export const UPDATE_OWNERS_COVERAGE_UI = 'UPDATE_OWNERS_COVERAGE_UI'; +export const UPDATE_USER_ROLES_UI = 'UPDATE_USER_ROLES_UI'; +export const UPDATE_PERMISSIONS_LOOKUP = 'UPDATE_PERMISSIONS_LOOKUP'; +export const UPDATE_ROLES_UI = 'UPDATE_ROLES_UI'; +export const UPDATE_HISTORY_UI = 'UPDATE_HISTORY_UI'; +export const UPDATE_DOCUMENTS_UI = 'UPDATE_DOCUMENTS_UI'; +export const UPDATE_DISTRICT_EQUIPMENT_UI = 'UPDATE_DISTRICT_EQUIPMENT_UI'; +export const SET_ACTIVE_RENTAL_AGREEMENT_ID_UI = 'SET_ACTIVE_RENTAL_AGREEMENT_ID_UI'; +export const SET_ACTIVE_RENTAL_REQUEST_ID_UI = 'SET_ACTIVE_RENTAL_REQUEST_ID_UI'; +export const SET_ACTIVE_PROJECT_ID_UI = 'SET_ACTIVE_PROJECT_ID_UI'; +export const SET_ACTIVE_OWNER_ID_UI = 'SET_ACTIVE_OWNER_ID_UI'; +export const SET_ACTIVE_EQUIPMENT_ID_UI = 'SET_ACTIVE_EQUIPMENT_ID_UI'; +export const UPDATE_AIT_REPORT_UI = 'UPDATE_AIT_REPORT_UI'; + +// Search +export const UPDATE_EQUIPMENT_LIST_SEARCH = 'UPDATE_EQUIPMENT_LIST_SEARCH'; +export const UPDATE_OWNERS_SEARCH = 'UPDATE_OWNERS_SEARCH'; +export const UPDATE_PROJECTS_SEARCH = 'UPDATE_PROJECTS_SEARCH'; +export const UPDATE_RENTAL_REQUESTS_SEARCH = 'UPDATE_RENTAL_REQUESTS_SEARCH'; +export const UPDATE_TIME_ENTRIES_SEARCH = 'UPDATE_TIME_ENTRIES_SEARCH'; +export const UPDATE_HIRING_RESPONSES_SEARCH = 'UPDATE_HIRING_RESPONSES_SEARCH'; +export const UPDATE_OWNERS_COVERAGE_SEARCH = 'UPDATE_OWNERS_COVERAGE_SEARCH'; +export const UPDATE_USERS_SEARCH = 'UPDATE_USERS_SEARCH'; +export const UPDATE_ROLES_SEARCH = 'UPDATE_ROLES_SEARCH'; +export const UPDATE_AIT_SEARCH = 'UPDATE_AIT_SEARCH'; + +// Lookups +// export const UPDATE_CITIES_LOOKUP = 'UPDATE_CITIES'; +export const UPDATE_DISTRICTS_LOOKUP = 'UPDATE_DISTRICTS'; +export const UPDATE_REGIONS_LOOKUP = 'UPDATE_REGIONS'; +export const UPDATE_SERVICE_AREAS_LOOKUP = 'UPDATE_SERVICE_AREAS'; +export const UPDATE_LOCAL_AREAS_LOOKUP = 'UPDATE_LOCAL_AREAS'; +// export const OWNERS_LOOKUP_REQUEST = 'OWNERS_LOOKUP_REQUEST'; +// export const UPDATE_OWNERS_LOOKUP = 'UPDATE_OWNERS_LOOKUP'; +export const UPDATE_OWNERS_LITE_LOOKUP = 'UPDATE_OWNERS_LITE_LOOKUP'; +export const UPDATE_OWNERS_LITE_TS_LOOKUP = 'UPDATE_OWNERS_LITE_TS_LOOKUP'; +export const UPDATE_OWNERS_LITE_HIRES_LOOKUP = 'UPDATE_OWNERS_LITE_HIRES_LOOKUP'; +export const UPDATE_EQUIPMENT_LITE_LOOKUP = 'UPDATE_EQUIPMENT_LITE_LOOKUP'; +export const UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP'; +export const UPDATE_EQUIPMENT_TS_LOOKUP = 'UPDATE_EQUIPMENT_TS_LOOKUP'; +export const UPDATE_EQUIPMENT_HIRES_LOOKUP = 'UPDATE_EQUIPMENT_HIRES_LOOKUP'; +export const UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP = 'UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP'; +export const UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP'; +export const UPDATE_FISCAL_YEARS_LOOKUP = 'UPDATE_FISCAL_YEARS_LOOKUP'; +export const UPDATE_EQUIPMENT_TYPES_LOOKUP = 'UPDATE_EQUIPMENT_TYPES_LOOKUP'; +export const UPDATE_ROLES_LOOKUP = 'UPDATE_ROLES_LOOKUP'; +export const UPDATE_PROJECTS_LOOKUP = 'UPDATE_PROJECTS_LOOKUP'; +export const UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP'; +export const UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP = 'UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP'; +export const UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP = 'UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP'; +export const UPDATE_USERS_LOOKUP = 'UPDATE_USERS_LOOKUP'; +export const UPDATE_RENTAL_CONDITIONS_LOOKUP = 'UPDATE_RENTAL_CONDITIONS_LOOKUP'; +export const RENTAL_CONDITIONS_LOOKUP_REQUEST = 'RENTAL_CONDITIONS_LOOKUP_REQUEST'; +// export const UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP = 'UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP'; +export const UPDATE_OVERTIME_RATE_TYPES_LOOKUP = 'UPDATE_OVERTIME_RATE_TYPES_LOOKUP'; +export const UPDATE_ROLLOVER_STATUS_LOOKUP = 'UPDATE_ROLLOVER_STATUS_LOOKUP'; +export const UPDATE_SEARCH_SUMMARY_COUNTS = 'UPDATE_SEARCH_SUMMARY_COUNTS'; + +// Current User +export const UPDATE_CURRENT_USER = 'UPDATE_CURRENT_USER'; + +// Users +export const USERS_REQUEST = 'USERS_REQUEST'; +export const UPDATE_USERS = 'UPDATE_USERS'; +export const CLEAR_USERS = 'CLEAR_USERS'; +export const UPDATE_USER = 'UPDATE_USER'; +export const ADD_USER = 'ADD_USER'; +export const DELETE_USER = 'DELETE_USER'; +export const USER_DISTRICTS = 'USER_DISTRICTS'; +export const CURRENT_USER_DISTRICTS = 'CURRENT_USER_DISTRICTS'; + +// Favourites +export const UPDATE_FAVOURITES = 'UPDATE_FAVOURITES'; +export const ADD_FAVOURITE = 'ADD_FAVOURITE'; +export const UPDATE_FAVOURITE = 'UPDATE_FAVOURITE'; +export const DELETE_FAVOURITE = 'DELETE_FAVOURITE'; + +// Contacts +// export const UPDATE_CONTACTS = 'UPDATE_CONTACTS'; +// export const ADD_CONTACT = 'ADD_CONTACT'; +// export const UPDATE_CONTACT = 'UPDATE_CONTACT'; +export const DELETE_CONTACT = 'DELETE_CONTACT'; + +// Documents +export const UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS'; +export const ADD_DOCUMENT = 'ADD_DOCUMENT'; +export const UPDATE_DOCUMENT = 'UPDATE_DOCUMENT'; +export const DELETE_DOCUMENT = 'DELETE_DOCUMENT'; + +// Roles, Permissions +export const UPDATE_ROLES = 'UPDATE_ROLES'; +export const UPDATE_ROLE = 'UPDATE_ROLE'; +export const ADD_ROLE = 'ADD_ROLE'; +export const DELETE_ROLE = 'DELETE_ROLE'; +export const UPDATE_ROLE_PERMISSIONS = 'UPDATE_ROLE_PERMISSIONS'; + +// Equipment +export const EQUIPMENT_LIST_REQUEST = 'EQUIPMENT_LIST_REQUEST'; +export const UPDATE_EQUIPMENT_LIST = 'UPDATE_EQUIPMENT_LIST'; +export const CLEAR_EQUIPMENT_LIST = 'CLEAR_EQUIPMENT_LIST'; +export const ADD_EQUIPMENT = 'ADD_EQUIPMENT'; +export const UPDATE_EQUIPMENT = 'UPDATE_EQUIPMENT'; +export const UPDATE_EQUIPMENT_NOTES = 'UPDATE_EQUIPMENT_NOTES'; +export const UPDATE_EQUIPMENT_RENTAL_AGREEMENTS = 'UPDATE_EQUIPMENT_RENTAL_AGREEMENTS'; + +// Equipment Attachments +// export const UPDATE_EQUIPMENT_ATTACHMENTS = 'UPDATE_EQUIPMENT_ATTACHMENTS'; +// export const ADD_EQUIPMENT_ATTACHMENT = 'ADD_EQUIPMENT_ATTACHMENT'; +export const ADD_EQUIPMENT_ATTACHMENTS = 'ADD_EQUIPMENT_ATTACHMENTS'; +export const UPDATE_EQUIPMENT_ATTACHMENT = 'UPDATE_EQUIPMENT_ATTACHMENT'; +export const DELETE_EQUIPMENT_ATTACHMENT = 'DELETE_EQUIPMENT_ATTACHMENT'; + +// Owners +export const OWNERS_REQUEST = 'OWNERS_REQUEST'; +export const UPDATE_OWNERS = 'UPDATE_OWNERS'; +export const OWNERS_LITE_REQUEST = 'OWNERS_LITE_REQUEST'; +export const UPDATE_OWNER_EQUIPMENT = 'UPDATE_OWNER_EQUIPMENT'; +export const OWNER_EQUIPMENT_REQUEST = 'OWNER_EQUIPMENT_REQUEST'; +export const ADD_OWNER = 'ADD_OWNER'; +export const UPDATE_OWNER = 'UPDATE_OWNER'; +export const CLEAR_OWNERS = 'CLEAR_OWNERS'; +// export const DELETE_OWNER = 'DELETE_OWNER'; +export const ADD_OWNER_NOTE = 'ADD_OWNER_NOTE'; +export const UPDATE_OWNER_NOTES = 'UPDATE_OWNER_NOTES'; +export const ADD_OWNER_CONTACT = 'ADD_OWNER_CONTACT'; +export const UPDATE_OWNER_CONTACT = 'UPDATE_OWNER_CONTACT'; + +// Projects +export const PROJECTS_REQUEST = 'PROJECTS_REQUEST'; +export const UPDATE_PROJECTS = 'UPDATE_PROJECTS'; +export const CLEAR_PROJECTS = 'CLEAR_PROJECTS'; +export const ADD_PROJECT = 'ADD_PROJECT'; +export const UPDATE_PROJECT = 'UPDATE_PROJECT'; +// export const UPDATE_PROJECT_EQUIPMENT = 'UPDATE_PROJECT_EQUIPMENT'; +// export const UPDATE_PROJECT_TIME_RECORDS = 'UPDATE_PROJECT_TIME_RECORDS'; +export const ADD_PROJECT_NOTE = 'ADD_PROJECT_NOTE'; +export const UPDATE_PROJECT_NOTES = 'UPDATE_PROJECT_NOTES'; +export const UPDATE_PROJECT_RENTAL_AGREEMENTS ='UPDATE_PROJECT_RENTAL_AGREEMENTS'; +export const DELETE_PROJECT_RENTAL_REQUEST = 'DELETE_PROJECT_RENTAL_REQUEST'; +export const ADD_PROJECT_CONTACT = 'ADD_PROJECT_CONTACT'; +export const UPDATE_PROJECT_CONTACT = 'UPDATE_PROJECT_CONTACT'; + +// Rental Requests +export const RENTAL_REQUESTS_REQUEST = 'RENTAL_REQUESTS_REQUEST'; +export const UPDATE_RENTAL_REQUESTS = 'UPDATE_RENTAL_REQUESTS'; +export const CLEAR_RENTAL_REQUESTS = 'CLEAR_RENTAL_REQUESTS'; + +export const ADD_RENTAL_REQUEST = 'ADD_RENTAL_REQUEST'; +export const UPDATE_RENTAL_REQUEST = 'UPDATE_RENTAL_REQUEST'; +export const UPDATE_RENTAL_REQUEST_NOTES = 'UPDATE_RENTAL_REQUEST_NOTES'; +export const UPDATE_RENTAL_REQUEST_ROTATION_LIST = 'UPDATE_RENTAL_REQUEST_ROTATION_LIST'; + +// Time Entries +export const TIME_ENTRIES_REQUEST = 'TIME_ENTRIES_REQUEST'; +export const UPDATE_TIME_ENTRIES = 'UPDATE_TIME_ENTRIES'; +export const CLEAR_TIME_ENTRIES = 'CLEAR_TIME_ENTRIES'; + +// Hiring Responses +export const HIRING_RESPONSES_REQUEST = 'HIRING_RESPONSES_REQUEST'; +export const UPDATE_HIRING_RESPONSES = 'UPDATE_HIRING_RESPONSES'; +export const CLEAR_HIRING_RESPONSES = 'CLEAR_HIRING_RESPONSES'; + +// Owners' Coverage +export const OWNERS_COVERAGE_REQUEST = 'OWNERS_COVERAGE_REQUEST'; +export const UPDATE_OWNERS_COVERAGE = 'UPDATE_OWNERS_COVERAGE'; +export const CLEAR_OWNERS_COVERAGE = 'CLEAR_OWNERS_COVERAGE'; + +// Rental Agreements +export const UPDATE_RENTAL_AGREEMENT = 'UPDATE_RENTAL_AGREEMENT'; +// export const ADD_RENTAL_AGREEMENT = 'ADD_RENTAL_AGREEMENT'; +// export const GENERATE_ANOTHER_RENTAL_AGREEMENT = 'GENERATE_ANOTHER_RENTAL_AGREEMENT'; +export const RENTAL_AGREEMENT_TIME_RECORDS = 'RENTAL_AGREEMENT_TIME_RECORDS'; + +// AitReport +export const AIT_REPORT_REQUEST = 'AIT_REPORT_REQUEST'; +export const UPDATE_AIT_REPORT = 'UPDATE_AIT_REPORT'; +export const CLEAR_AIT_REPORT = 'CLEAR_AIT_REPORT'; + +// Rental Rates, Conditions +export const ADD_RENTAL_RATES = 'ADD_RENTAL_RATES'; +export const UPDATE_RENTAL_RATES = 'UPDATE_RENTAL_RATES'; +export const DELETE_RENTAL_RATE = 'DELETE_RENTAL_RATE'; +export const ADD_RENTAL_CONDITIONS = 'ADD_RENTAL_CONDITIONS'; +export const UPDATE_RENTAL_CONDITIONS = 'UPDATE_RENTAL_CONDITIONS'; +export const DELETE_RENTAL_CONDITION = 'DELETE_RENTAL_CONDITION'; + +// Version +export const UPDATE_VERSION = 'UPDATE_VERSION'; + +// History +export const UPDATE_EQUIPMENT_HISTORY = 'UPDATE_EQUIPMENT_HISTORY'; +export const UPDATE_OWNER_HISTORY = 'UPDATE_OWNER_HISTORY'; +export const UPDATE_PROJECT_HISTORY = 'UPDATE_PROJECT_HISTORY'; +export const UPDATE_RENTAL_REQUEST_HISTORY = 'UPDATE_RENTAL_REQUEST_HISTORY'; + +// Notes +export const DELETE_NOTE = 'DELETE_NOTE'; + +// Time Records +export const DELETE_TIME_RECORD = 'DELETE_TIME_RECORD'; + +// Session Modal +export const SHOW_SESSION_TIMEOUT_DIALOG = 'SHOW_SESSION_TIMEOUT_DIALOG'; +export const CLOSE_SESSION_TIMEOUT_DIALOG = 'CLOSE_SESSION_TIMEOUT_DIALOG'; + +// Businesses +export const UPDATE_BUSINESS = 'UPDATE_BUSINESS'; + +// Error Dialog +export const SHOW_ERROR_DIALOG = 'SHOW_ERROR_DIALOG'; +export const CLOSE_ERROR_DIALOG = 'CLOSE_ERROR_DIALOG'; diff --git a/client2/src/js/actions.js b/client2/src/js/actions.js new file mode 100644 index 000000000..aafe6af77 --- /dev/null +++ b/client2/src/js/actions.js @@ -0,0 +1,39 @@ +import { SHOW_ERROR_DIALOG, CLOSE_ERROR_DIALOG, REQUESTS_ERROR, CLOSE_SESSION_TIMEOUT_DIALOG } from './actionTypes'; + + +export function showErrorDialog(exception) { + return { + type: SHOW_ERROR_DIALOG, + message: exception.message || String(exception), + }; +} + +export function closeErrorDialog() { + return { + type: CLOSE_ERROR_DIALOG, + }; +} + +export function unhandledApiError(err) { + var errorMessage = err.message || String(err); + if (err.json) { + errorMessage = err.json.error.description; + } + + return { + type: REQUESTS_ERROR, + error: { + message: errorMessage, + method: err.method, + path: err.path, + status: err.status, + json: err.json, + }, + }; +} + +export function closeSessionTimeoutDialog() { + return { + type: CLOSE_SESSION_TIMEOUT_DIALOG, + }; +} diff --git a/client2/src/js/api.js b/client2/src/js/api.js new file mode 100644 index 000000000..40695e725 --- /dev/null +++ b/client2/src/js/api.js @@ -0,0 +1,3286 @@ +import * as Action from "./actionTypes"; +import * as Constant from "./constants"; +import * as History from "./history"; +import * as Log from "./history"; +import store from "./store"; + +import { ApiRequest } from "./utils/http"; +import { lastFirstName, firstLastName, concat } from "./utils/string"; +import { daysAgo, sortableDateTime, today } from "./utils/date"; + +import _ from "lodash"; +import Moment from "moment"; + +function normalize(response) { + return _.fromPairs(response.map((object) => [object.id, object])); +} + +//////////////////// +// Users +//////////////////// + +function parseUser(user) { + if (!user.district) { + user.district = { id: 0, name: "" }; + } + if (!user.userRoles) { + user.userRoles = []; + } + + user.name = lastFirstName(user.surname, user.givenName); + user.fullName = firstLastName(user.givenName, user.surname); + user.districtName = user.district.name; + + _.each(user.userRoles, (userRole) => { + userRole.roleId = userRole.role && userRole.role.id ? userRole.role.id : 0; + userRole.roleName = + userRole.role && userRole.role.name ? userRole.role.name : ""; + userRole.effectiveDateSort = sortableDateTime(user.effectiveDate); + userRole.expiryDateSort = sortableDateTime(user.expiryDate); + }); + + user.path = `${Constant.USERS_PATHNAME}/${user.id}`; + user.url = `#/${user.path}`; + user.historyEntity = History.makeHistoryEntity(Constant.HISTORY_USER, user); + + user.canEdit = true; + user.canDelete = true; +} + +export function getCurrentUser() { + return new ApiRequest("/users/current").get().then((response) => { + var user = response.data; + + // Add display fields + parseUser(user); + + // Get permissions + var permissions = []; + _.each(user.userRoles, (userRole) => { + _.each(userRole.role.rolePermissions, (rolePermission) => { + permissions.push(rolePermission.permission.code); + }); + }); + user.permissions = _.uniq(permissions); + + user.hasPermission = function (permission) { + return user.permissions.indexOf(permission) !== -1; + }; + + store.dispatch({ type: Action.UPDATE_CURRENT_USER, user: user }); + return user; + }); +} + +export function keepAlive() { + // endpoint to keep session active + return new ApiRequest("/users/current").get(null, { keepAlive: true }); +} + +export function searchUsers(params) { + store.dispatch({ type: Action.USERS_REQUEST }); + return new ApiRequest("/users/search").get(params).then((response) => { + var users = normalize(response.data); + + // Add display fields + _.map(users, (user) => { + parseUser(user); + }); + + store.dispatch({ type: Action.UPDATE_USERS, users: users }); + }); +} + +export function getUsers() { + return new ApiRequest("/users").get().then((response) => { + var users = normalize(response.data); + + // Add display fields + _.map(users, (user) => { + parseUser(user); + }); + + store.dispatch({ type: Action.UPDATE_USERS_LOOKUP, users: users }); + }); +} + +export function getUser(userId) { + return new ApiRequest(`/users/${userId}`).get().then((response) => { + var user = response.data; + + // Add display fields + parseUser(user); + + store.dispatch({ type: Action.UPDATE_USER, user: user }); + }); +} + +export function addUser(user) { + return new ApiRequest("/users").post(user).then((response) => { + var user = response.data; + + // Add display fields + parseUser(user); + + store.dispatch({ type: Action.ADD_USER, user: user }); + + return user; + }); +} + +export function updateUser(user) { + return new ApiRequest(`/users/${user.id}`).put(user).then((response) => { + var user = response.data; + + // Add display fields + parseUser(user); + + store.dispatch({ type: Action.UPDATE_USER, user: user }); + + return user; + }); +} + +export function deleteUser(user) { + return new ApiRequest(`/users/${user.id}/delete`).post().then((response) => { + var user = response.data; + + // Add display fields + parseUser(user); + + store.dispatch({ type: Action.DELETE_USER, user: user }); + }); +} + +export function addUserRole(userId, userRole) { + return new ApiRequest(`/users/${userId}/roles`).post(userRole).then(() => { + // After updating the user's role, refresh the user state. + return getUser(userId); + }); +} + +export function updateUserRoles(userId, userRoleArray) { + return new ApiRequest(`/users/${userId}/roles`) + .put(userRoleArray) + .then(() => { + // After updating the user's role, refresh the user state. + return getUser(userId); + }); +} + +export function getCurrentUserDistricts() { + return new ApiRequest("/userdistricts").get().then((response) => { + store.dispatch({ + type: Action.CURRENT_USER_DISTRICTS, + currentUserDistricts: response.data, + }); + return response; + }); +} + +export function getUserDistricts(userId) { + return new ApiRequest(`users/${userId}/districts`).get().then((response) => { + store.dispatch({ + type: Action.USER_DISTRICTS, + userDistricts: response.data, + }); + return response; + }); +} + +export function addUserDistrict(district) { + return new ApiRequest(`/userdistricts/${district.id}`) + .post(district) + .then((response) => { + store.dispatch({ + type: Action.USER_DISTRICTS, + userDistricts: response.data, + }); + return response; + }); +} + +export function editUserDistrict(district) { + return new ApiRequest(`/userdistricts/${district.id}`) + .post(district) + .then((response) => { + store.dispatch({ + type: Action.USER_DISTRICTS, + userDistricts: response.data, + }); + return response; + }); +} + +export function deleteUserDistrict(district) { + return new ApiRequest(`/userdistricts/${district.id}/delete`) + .post() + .then((response) => { + store.dispatch({ + type: Action.USER_DISTRICTS, + userDistricts: response.data, + }); + return response; + }); +} + +export function switchUserDistrict(districtId) { + return new ApiRequest(`/userdistricts/${districtId}/switch`).post(); +} + +export function getSearchSummaryCounts() { + return new ApiRequest("/counts").get().then((response) => { + store.dispatch({ + type: Action.UPDATE_SEARCH_SUMMARY_COUNTS, + searchSummaryCounts: response.data, + }); + return response; + }); +} + +//////////////////// +// Roles, Permissions +//////////////////// + +function parseRole(role) { + role.path = `${Constant.ROLES_PATHNAME}/${role.id}`; + role.url = `#/${role.path}`; + role.historyEntity = History.makeHistoryEntity(Constant.HISTORY_ROLE, role); + + role.canEdit = true; + role.canDelete = false; +} + +export function searchRoles(params) { + return new ApiRequest("/roles").get(params).then((response) => { + var roles = normalize(response.data); + + // Add display fields + _.map(roles, (role) => { + parseRole(role); + }); + + store.dispatch({ type: Action.UPDATE_ROLES, roles: roles }); + }); +} + +export function getRole(roleId) { + return new ApiRequest(`/roles/${roleId}`).get().then((response) => { + var role = response.data; + + // Add display fields + parseRole(role); + + store.dispatch({ type: Action.UPDATE_ROLE, role: role }); + }); +} + +export function addRole(role) { + return new ApiRequest("/roles").post(role).then((response) => { + var role = response.data; + + // Add display fields + parseRole(role); + + store.dispatch({ type: Action.ADD_ROLE, role: role }); + }); +} + +export function updateRole(role) { + return new ApiRequest(`/roles/${role.id}`).put(role).then((response) => { + var role = response.data; + + // Add display fields + parseRole(role); + + store.dispatch({ type: Action.UPDATE_ROLE, role: role }); + }); +} + +export function deleteRole(role) { + return new ApiRequest(`/roles/${role.id}/delete`).post().then((response) => { + var role = response.data; + + // Add display fields + parseRole(role); + + store.dispatch({ type: Action.DELETE_ROLE, role: role }); + }); +} + +export function getRolePermissions(roleId) { + return new ApiRequest(`/roles/${roleId}/permissions`) + .get() + .then((response) => { + var permissions = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_ROLE_PERMISSIONS, + rolePermissions: permissions, + }); + }); +} + +export function updateRolePermissions(roleId, permissionsArray) { + return new ApiRequest(`/roles/${roleId}/permissions`) + .put(permissionsArray) + .then(() => { + // After updating the role's permissions, refresh the permissions state. + return getRolePermissions(roleId); + }); +} + +//////////////////// +// Favourites +//////////////////// + +export function getFavourites() { + return new ApiRequest("/users/current/favourites").get().then((response) => { + var favourites = _.chain(response.data) + .groupBy("type") + .mapValues((type) => + _.chain(type) + .values() + .map((object) => [object.id, object]) + .fromPairs() + .value() + ) + .value(); + + store.dispatch({ type: Action.UPDATE_FAVOURITES, favourites: favourites }); + }); +} + +export function addFavourite(favourite) { + return new ApiRequest("/users/current/favourites") + .post(favourite) + .then((response) => { + store.dispatch({ type: Action.ADD_FAVOURITE, favourite: response.data }); + }); +} + +export function updateFavourite(favourite) { + return new ApiRequest("/users/current/favourites") + .put(favourite) + .then((response) => { + store.dispatch({ + type: Action.UPDATE_FAVOURITE, + favourite: response.data, + }); + }); +} + +export function deleteFavourite(favourite) { + return new ApiRequest(`/users/current/favourites/${favourite.id}/delete`) + .post() + .then((response) => { + store.dispatch({ + type: Action.DELETE_FAVOURITE, + favourite: response.data, + }); + }); +} + +export function logoffUser() { + return new ApiRequest("/users/current/logoff").get().then((response) => { + return response.error ? null : response.data.logoffUrl; + }); +} + +//////////////////// +// Equipment +//////////////////// +function getBlockDisplayName(blockNumber, numberOfBlocks, seniority) { + if (blockNumber === numberOfBlocks) { + return `Open - ${seniority}`; + } else if (blockNumber === 1) { + return `1 - ${seniority}`; + } else if (blockNumber === 2) { + return `2 - ${seniority}`; + } else if (seniority != null) { + return `Open - ${seniority}`; + } + return "Open"; +} + +function parseEquipment(equipment) { + if (!equipment.owner) { + equipment.owner = { id: 0, organizationName: "" }; + } + if (!equipment.districtEquipmentType) { + equipment.districtEquipmentType = { id: 0, districtEquipmentName: "" }; + } + if (!equipment.localArea) { + equipment.localArea = { id: 0, name: "" }; + } + if (!equipment.localArea.serviceArea) { + equipment.localArea.serviceArea = { id: 0, name: "" }; + } + if (!equipment.localArea.serviceArea.district) { + equipment.localArea.serviceArea.district = { id: 0, name: "" }; + } + if (!equipment.localArea.serviceArea.district.region) { + equipment.localArea.serviceArea.district.region = { id: 0, name: "" }; + } + if (!equipment.status) { + equipment.status = Constant.EQUIPMENT_STATUS_CODE_PENDING; + } + if (!equipment.equipmentAttachments) { + equipment.equipmentAttachments = []; + } + + equipment.isApproved = + equipment.status === Constant.EQUIPMENT_STATUS_CODE_APPROVED; + equipment.isNew = equipment.status === Constant.EQUIPMENT_STATUS_CODE_PENDING; + equipment.isArchived = + equipment.status === Constant.EQUIPMENT_STATUS_CODE_ARCHIVED; + equipment.isMaintenanceContractor = + equipment.owner.isMaintenanceContractor === true; + equipment.isDumpTruck = + (equipment.districtEquipmentType.equipmentType && + equipment.districtEquipmentType.equipmentType.isDumpTruck) || + false; + + equipment.ownerStatus = equipment.owner.status; + + // UI display fields + equipment.serialNumber = equipment.serialNumber || ""; + equipment.equipmentCode = equipment.equipmentCode || ""; + equipment.licencePlate = equipment.licencePlate || ""; + equipment.operator = equipment.operator || ""; // TODO Needs review from business + equipment.organizationName = equipment.owner.organizationName; + equipment.ownerPath = equipment.owner.id + ? `#/owners/${equipment.owner.id}` + : ""; + equipment.typeName = equipment.districtEquipmentType + ? equipment.districtEquipmentType.districtEquipmentName + : ""; + equipment.localAreaName = equipment.localArea.name; + equipment.districtName = equipment.localArea.serviceArea.district.name; + equipment.lastVerifiedDate = equipment.lastVerifiedDate || ""; + equipment.daysSinceVerified = daysAgo(equipment.lastVerifiedDate); + equipment.details = [ + equipment.make || "-", + equipment.model || "-", + equipment.size || "-", + equipment.year || "-", + ].join("/"); + + // Seniority data + equipment.serviceHoursThisYear = equipment.serviceHoursThisYear || 0; + equipment.serviceHoursLastYear = equipment.serviceHoursLastYear || 0; + equipment.serviceHoursTwoYearsAgo = equipment.serviceHoursTwoYearsAgo || 0; + equipment.serviceHoursThreeYearsAgo = + equipment.serviceHoursThreeYearsAgo || 0; + + equipment.isSeniorityOverridden = equipment.isSeniorityOverridden || false; + equipment.seniorityOverrideReason = equipment.seniorityOverrideReason || ""; + + // The number of years of active service of this piece of equipment at the time seniority is calculated - April 1 of the current fiscal year + equipment.yearsOfService = equipment.yearsOfService || 0; + equipment.receivedDate = equipment.receivedDate || ""; + equipment.approvedDate = equipment.approvedDate || ""; + // The max date of a time card for this fiscal year - can be null if there are none. + equipment.lastTimeRecordDateThisYear = + equipment.lastTimeRecordDateThisYear || ""; + // e.g. "Open-500" or "1-744" + equipment.seniorityText = getBlockDisplayName( + equipment.blockNumber, + equipment.numberOfBlocks, + equipment.seniority + ); + + equipment.currentYear = Moment().year(); + equipment.lastYear = equipment.currentYear - 1; + equipment.twoYearsAgo = equipment.currentYear - 2; + equipment.threeYearsAgo = equipment.currentYear - 3; + + // It is possible to have multiple instances of the same piece of equipment registered with HETS. + // However, the HETS clerks would like to know about it via this flag so they can deal with the duplicates. + equipment.hasDuplicates = equipment.hasDuplicates || false; + equipment.duplicateEquipment = equipment.duplicateEquipment || []; + + equipment.isHired = equipment.isHired || false; + // TODO Descriptive text for time entries. Needs to be added to backend + equipment.currentWorkDescription = equipment.currentWorkDescription || ""; + + equipment.path = `${Constant.EQUIPMENT_PATHNAME}/${equipment.id}`; + equipment.url = `#/${equipment.path}`; + equipment.name = `code ${equipment.equipmentCode}`; + equipment.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_EQUIPMENT, + equipment + ); + equipment.documentAdded = Log.equipmentDocumentAdded; + equipment.documentsAdded = Log.equipmentDocumentsAdded; + equipment.documentDeleted = Log.equipmentDocumentDeleted; + + equipment.getDocumentsPromise = getEquipmentDocuments; + equipment.uploadDocumentPath = `/equipment/${equipment.id}/attachments`; + + equipment.canView = true; + equipment.canEdit = true; + equipment.canDelete = false; // TODO Needs input from Business whether this is needed. +} + +function generateSortableEquipmentCode(equipment) { + return equipment.equipmentPrefix && equipment.equipmentNumber + ? `${equipment.equipmentPrefix}${_.padStart( + equipment.equipmentNumber, + 3, + "0" + )}` + : equipment.equipmentCode; +} + +export function searchEquipmentList(params) { + store.dispatch({ type: Action.EQUIPMENT_LIST_REQUEST }); + return new ApiRequest("/equipment/search").get(params).then((response) => { + var equipmentList = normalize(response.data); + + _.map(equipmentList, (equipment) => { + equipment.details = [ + equipment.make || "-", + equipment.model || "-", + equipment.size || "-", + equipment.year || "-", + ].join("/"); + equipment.sortableEquipmentCode = + generateSortableEquipmentCode(equipment); + }); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_LIST, + equipmentList: equipmentList, + }); + }); +} + +export function getEquipment(equipmentId) { + return new ApiRequest(`/equipment/${equipmentId}`).get().then((response) => { + var equipment = response.data; + + // Add display fields + parseEquipment(equipment); + + store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); + }); +} + +export function getEquipmentLite() { + const silent = store.getState().lookups.equipment.lite.loaded; + return new ApiRequest("/equipment/lite", { silent }) + .get() + .then((response) => { + var equipment = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_LITE_LOOKUP, + equipment: equipment, + }); + }); +} + +export function getEquipmentAgreementSummary() { + const silent = store.getState().lookups.equipment.ts.loaded; + return new ApiRequest("/equipment/agreementSummary", { silent }) + .get() + .then((response) => { + var equipment = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP, + equipment: equipment, + }); + }); +} + +export function getEquipmentTs() { + const silent = store.getState().lookups.equipment.ts.loaded; + return new ApiRequest("/equipment/liteTs", { silent }) + .get() + .then((response) => { + var equipment = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_TS_LOOKUP, + equipment: equipment, + }); + }); +} + +export function getEquipmentHires() { + const silent = store.getState().lookups.equipment.hires.loaded; + return new ApiRequest("/equipment/liteHires", { silent }) + .get() + .then((response) => { + var equipment = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_HIRES_LOOKUP, + equipment: equipment, + }); + }); +} + +export function addEquipment(equipment) { + return new ApiRequest("/equipment").post(equipment).then((response) => { + var equipment = response.data; + + // Add display fields + parseEquipment(equipment); + + store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); + + getEquipmentLite(); + getEquipmentTs(); + getEquipmentHires(); + + return equipment; + }); +} + +export function updateEquipment(equipment) { + return new ApiRequest(`/equipment/${equipment.id}`) + .put(equipment) + .then((response) => { + var equipment = response.data; + + // Add display fields + parseEquipment(equipment); + + store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); + + getEquipmentLite(); + getEquipmentTs(); + getEquipmentHires(); + }); +} + +export function addEquipmentHistory(equipmentId, history) { + return new ApiRequest(`/equipment/${equipmentId}/history`) + .post(history) + .then((response) => { + var history = normalize(response.data); + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_HISTORY, + history, + id: equipmentId, + }); + }); +} + +export function getEquipmentHistory(equipmentId, params) { + return new ApiRequest(`/equipment/${equipmentId}/history`) + .get(params) + .then((response) => { + var history = normalize(response.data); + + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_HISTORY, + history, + id: equipmentId, + }); + }); +} + +export function getEquipmentDocuments(equipmentId) { + return new ApiRequest(`/equipment/${equipmentId}/attachments`) + .get() + .then((response) => { + var documents = normalize(response.data); + + // Add display fields + _.map(documents, (document) => { + parseDocument(document); + }); + + store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); + }); +} + +// XXX: Looks like this is unused +// export function addEquipmentDocument(equipmentId, files) { +// return new ApiRequest(`/equipment/${ equipmentId }/attachments`).post(files); +// } + +export function getEquipmentNotes(equipmentId) { + return new ApiRequest(`/equipment/${equipmentId}/notes`) + .get() + .then((response) => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_NOTES, + notes: response.data, + }); + return response.data; + }); +} + +export function addEquipmentNote(equipmentId, note) { + return new ApiRequest(`/equipment/${equipmentId}/note`) + .post(note) + .then((response) => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_NOTES, + notes: response.data, + }); + return response.data; + }); +} + +export function equipmentDuplicateCheck(id, serialNumber) { + return new ApiRequest(`/equipment/${id}/duplicates/${serialNumber}`).get(); +} + +export function changeEquipmentStatus(status) { + return new ApiRequest(`/equipment/${status.id}/status`) + .put(status) + .then((response) => { + var equipment = response.data; + // Add display fields + parseEquipment(equipment); + store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); + return response; + }); +} + +export function getEquipmentRentalAgreements(equipmentId) { + return new ApiRequest(`/equipment/${equipmentId}/rentalAgreements`) + .get() + .then((response) => { + var rentalAgreements = normalize(response.data); + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_RENTAL_AGREEMENTS, + rentalAgreements: rentalAgreements, + }); + return rentalAgreements; + }); +} + +export function cloneEquipmentRentalAgreement(data) { + return new ApiRequest(`/equipment/${data.equipmentId}/rentalAgreementClone`) + .post(data) + .then((response) => { + var agreement = response.data; + // Add display fields + parseRentalAgreement(agreement); + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: agreement, + }); + return response; + }); +} + +export function equipmentSeniorityListDoc(localAreas, types, counterCopy) { + var params = { localareas: localAreas, types: types }; + if (counterCopy) { + params.counterCopy = counterCopy; + } + + return new ApiRequest("/equipment/seniorityListDoc") + .get(params, { responseType: Constant.RESPONSE_TYPE_BLOB }) + .then((response) => { + return response; + }); +} + +//////////////////// +// Physical Attachments +//////////////////// + +// Introduce later +// function parsePhysicalAttachment(attachment) { +// if (!attachment.type) { attachment.type = { id: 0, code: '', description: ''}; } + +// attachment.typeName = attachment.type.description; +// // TODO Add grace period logic to editing/deleting attachments +// attachment.canEdit = true; +// attachment.canDelete = true; +// } + +// XXX: Looks like this is unused +// export function getPhysicalAttachment(id) { +// return new ApiRequest(`/equipment/${id}/equipmentAttachments`).get().then(response => { +// store.dispatch({ type: Action.UPDATE_EQUIPMENT_ATTACHMENTS, physicalAttachments: response.data }); +// }); +// } + +// XXX: Looks like this is unused +// export function addPhysicalAttachment(attachment) { +// return new ApiRequest('/equipmentAttachments').post(attachment).then(response => { +// store.dispatch({ type: Action.ADD_EQUIPMENT_ATTACHMENT, physicalAttachment: response.data }); +// }); +// } + +export function addPhysicalAttachments(equipmentId, attachmentTypeNames) { + const attachments = attachmentTypeNames.map((typeName) => { + // "concurrencyControlNumber": 0, + return { + typeName, + description: "", + equipmentId, + equipment: { id: equipmentId }, + }; + }); + + return new ApiRequest("/equipmentAttachments/bulk") + .post(attachments) + .then((response) => { + store.dispatch({ + type: Action.ADD_EQUIPMENT_ATTACHMENTS, + physicalAttachments: response.data, + }); + }); +} + +export function updatePhysicalAttachment(attachment) { + return new ApiRequest(`/equipmentAttachments/${attachment.id}`) + .put(attachment) + .then((response) => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_ATTACHMENT, + physicalAttachment: response.data, + }); + }); +} + +export function deletePhysicalAttachment(attachmentId) { + return new ApiRequest(`/equipmentAttachments/${attachmentId}/delete`) + .post() + .then((response) => { + store.dispatch({ + type: Action.DELETE_EQUIPMENT_ATTACHMENT, + physicalAttachment: response.data, + }); + }); +} + +//////////////////// +// Owners +//////////////////// + +function parseOwner(owner) { + // Rename properties + owner.equipmentList = owner.equipment; + delete owner.equipment; + + owner.workSafeBCExpiryDate = owner.workSafeBcexpiryDate; + delete owner.workSafeBcexpiryDate; + + owner.workSafeBCPolicyNumber = owner.workSafeBcpolicyNumber; + delete owner.workSafeBcpolicyNumber; + + owner.cglEndDate = owner.cglendDate; + delete owner.cglendDate; + + if (!owner.localArea) { + owner.localArea = { id: 0, name: "" }; + } + if (!owner.localArea.serviceArea) { + owner.localArea.serviceArea = { id: 0, name: "" }; + } + if (!owner.localArea.serviceArea.district) { + owner.localArea.serviceArea.district = { id: 0, name: "" }; + } + if (!owner.localArea.serviceArea.district.region) { + owner.localArea.serviceArea.district.region = { id: 0, name: "" }; + } + if (!owner.contacts) { + owner.contacts = []; + } + if (!owner.documents) { + owner.documents = []; + } + if (!owner.equipmentList) { + owner.equipmentList = []; + } + + owner.organizationName = owner.organizationName || ""; + owner.ownerCode = owner.ownerCode || ""; + owner.doingBusinessAs = owner.doingBusinessAs || ""; + owner.registeredCompanyNumber = owner.registeredCompanyNumber || ""; + owner.meetsResidency = owner.meetsResidency || false; + owner.workSafeBCPolicyNumber = owner.workSafeBCPolicyNumber || ""; + owner.workSafeBCExpiryDate = owner.workSafeBCExpiryDate || ""; + owner.cglEndDate = owner.cglEndDate || ""; + owner.address1 = owner.address1 || ""; + owner.address2 = owner.address2 || ""; + owner.city = owner.city || ""; + owner.province = owner.province || ""; + owner.postalCode = owner.postalCode || ""; + owner.fullAddress = `${owner.address1} ${owner.address2} ${owner.city} ${owner.province} ${owner.postalCode}`; + owner.ownerName = + owner.givenName && owner.surname + ? `${owner.givenName} ${owner.surname}` + : ""; + + owner.path = `${Constant.OWNERS_PATHNAME}/${owner.id}`; + owner.url = `#/${owner.path}`; + owner.name = owner.organizationName; + owner.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_OWNER, + owner + ); + owner.documentAdded = Log.ownerDocumentAdded; + owner.documentsAdded = Log.ownerDocumentsAdded; + owner.documentDeleted = Log.ownerDocumentDeleted; + + // Add display fields for owner contacts + owner.contacts = owner.contacts.map((contact) => + parseContact(contact, owner) + ); + + _.map(owner.documents, (document) => { + parseDocument(document); + }); + _.map(owner.equipmentList, (equipment) => { + parseEquipment(equipment); + }); + + // TODO Owner status needs to be populated in sample data. Setting to Approved for the time being... + owner.status = owner.status || Constant.OWNER_STATUS_CODE_APPROVED; + + // UI display fields + owner.isMaintenanceContractor = owner.isMaintenanceContractor || false; + owner.isApproved = owner.status === Constant.OWNER_STATUS_CODE_APPROVED; + owner.primaryContactName = owner.primaryContact + ? firstLastName( + owner.primaryContact.givenName, + owner.primaryContact.surname + ) + : ""; + owner.localAreaName = owner.localArea.name; + owner.districtName = owner.localArea.serviceArea.district.name; + owner.numberOfEquipment = Object.keys(owner.equipmentList).length; + owner.numberOfPolicyDocuments = owner.numberOfPolicyDocuments || 0; // TODO + + owner.getDocumentsPromise = getOwnerDocuments; + owner.uploadDocumentPath = `/owners/${owner.id}/attachments`; + + owner.canView = true; + owner.canEdit = true; + owner.canDelete = false; // TODO Needs input from Business whether this is needed. +} + +export function searchOwners(params) { + store.dispatch({ type: Action.OWNERS_REQUEST }); + return new ApiRequest("/owners/search").get(params).then((response) => { + var owners = normalize(response.data); + store.dispatch({ type: Action.UPDATE_OWNERS, owners: owners }); + }); +} + +export function getOwner(ownerId) { + return new ApiRequest(`/owners/${ownerId}`).get().then((response) => { + var owner = response.data; + + // Add display fields + parseOwner(owner); + + store.dispatch({ type: Action.UPDATE_OWNER, owner }); + + return owner; + }); +} + +export function addOwner(owner) { + return new ApiRequest("/owners").post(owner).then((response) => { + var owner = response.data; + + // Add display fields + parseOwner(owner); + + store.dispatch({ type: Action.ADD_OWNER, owner }); + + return owner; + }); +} + +export function updateOwner(owner) { + store.dispatch({ type: Action.UPDATE_OWNER, owner }); + + // Omit `contacts` to ensure that the existing contacts don't mess up the PUT call + return new ApiRequest(`/owners/${owner.id}`) + .put(_.omit(owner, "contacts")) + .then((response) => { + var owner = response.data; + + // Add display fields + parseOwner(owner); + + store.dispatch({ type: Action.UPDATE_OWNER, owner }); + }); +} + +// XXX: Looks like this is unused +// export function deleteOwner(owner) { +// return new ApiRequest(`/owners/${ owner.id }/delete`).post().then(response => { +// var owner = response.data; + +// // Add display fields +// parseOwner(owner); + +// store.dispatch({ type: Action.DELETE_OWNER, owner }); +// }); +// } + +export function saveOwnerContact(owner, contact) { + const isNew = contact.id === 0; + + if (!isNew) { + // don't update if this is a new contact - add after post() completes + store.dispatch({ + type: Action.UPDATE_OWNER_CONTACT, + ownerId: owner.id, + contact, + }); + } + + return new ApiRequest(`/owners/${owner.id}/contacts/${contact.isPrimary}`) + .post(contact) + .then((response) => { + var updatedContact = response.data; + + // Add display fields + parseContact(updatedContact, owner); // owner's primary contact could be outdated + updatedContact.isPrimary = contact.isPrimary; + + if (isNew) { + // add newly created contact to Redux store's contacts + store.dispatch({ + type: Action.ADD_OWNER_CONTACT, + ownerId: owner.id, + contact: updatedContact, + }); + } else { + // Update Redux store's data with the server's data + store.dispatch({ + type: Action.UPDATE_OWNER_CONTACT, + ownerId: owner.id, + contact: updatedContact, + }); + } + + return updatedContact; + }); +} + +export function addOwnerHistory(ownerId, history) { + return new ApiRequest(`/owners/${ownerId}/history`) + .post(history) + .then((response) => { + var history = normalize(response.data); + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_OWNER_HISTORY, + history, + id: ownerId, + }); + }); +} + +export function getOwnerHistory(ownerId, params) { + return new ApiRequest(`/owners/${ownerId}/history`) + .get(params) + .then((response) => { + var history = normalize(response.data); + + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_OWNER_HISTORY, + history, + id: ownerId, + }); + }); +} + +export function getOwnerDocuments(ownerId) { + return new ApiRequest(`/owners/${ownerId}/attachments`) + .get() + .then((response) => { + var documents = normalize(response.data); + + // Add display fields + _.map(documents, (document) => { + parseDocument(document); + }); + + store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); + }); +} + +// XXX: Looks like this is unused +// export function addOwnerDocument(ownerId, files) { +// return new ApiRequest(`/owners/${ ownerId }/attachments`).post(files); +// } + +export function getOwnerEquipment(ownerId) { + return new ApiRequest(`/owners/${ownerId}/equipment`) + .get() + .then((response) => { + var equipmentList = normalize(response.data); + + _.map(equipmentList, (equipment) => { + equipment.details = [ + equipment.make || "-", + equipment.model || "-", + equipment.size || "-", + equipment.year || "-", + ].join("/"); + }); + + store.dispatch({ + type: Action.UPDATE_OWNER_EQUIPMENT, + equipment: equipmentList, + }); + }); +} + +export function updateOwnerEquipment(owner, equipmentArray) { + return new ApiRequest(`/owners/${owner.id}/equipment`) + .put(equipmentArray) + .then(() => {}); +} + +export function getOwnerNotes(ownerId) { + return new ApiRequest(`/owners/${ownerId}/notes`).get().then((response) => { + store.dispatch({ + type: Action.UPDATE_OWNER_NOTES, + ownerId, + notes: response.data, + }); + return response.data; + }); +} + +export function addOwnerNote(ownerId, note) { + store.dispatch({ type: Action.ADD_OWNER_NOTE, ownerId, note }); + return new ApiRequest(`/owners/${ownerId}/note`) + .post(note) + .then((response) => { + return response.data; + }); +} + +// XXX: Looks like this is unused +// export function getOwnersByDistrict(districtId) { +// return new ApiRequest(`/districts/${districtId}/owners`).get().then((response) => { +// var owners = normalize(response.data); +// // Add display fields +// _.map(owners, owner => { parseOwner(owner); }); +// store.dispatch({ type: Action.UPDATE_OWNERS_LOOKUP, owners: owners }); +// }); +// } + +export function changeOwnerStatus(status) { + return new ApiRequest(`/owners/${status.id}/status`) + .put(status) + .then((response) => { + var owner = response.data; + // Add display fields + parseOwner(owner); + store.dispatch({ type: Action.UPDATE_OWNER, owner: owner }); + return response; + }); +} + +export function getStatusLettersDoc(params) { + return new ApiRequest("owners/verificationDoc").post(params, { + responseType: Constant.RESPONSE_TYPE_BLOB, + }); +} + +export function getMailingLabelsDoc(params) { + return new ApiRequest("owners/mailingLabelsDoc").post(params, { + responseType: Constant.RESPONSE_TYPE_BLOB, + }); +} + +export function transferEquipment( + donorOwnerId, + recipientOwnerId, + equipment, + includeSeniority +) { + return new ApiRequest( + `owners/${donorOwnerId}/equipmentTransfer/${recipientOwnerId}/${includeSeniority}` + ) + .post(equipment) + .then((response) => { + getEquipmentLite(); + getEquipmentTs(); + getEquipmentHires(); + + return response; + }); +} + +//////////////////// +// Contacts +//////////////////// + +function parseContact(contact, parent) { + contact.name = firstLastName(contact.givenName, contact.surname); + contact.phone = contact.workPhoneNumber + ? `${contact.workPhoneNumber} (w)` + : contact.mobilePhoneNumber + ? `${contact.mobilePhoneNumber} (c)` + : ""; + + var parentPath = ""; + var primaryContactId = 0; + if (parent) { + parentPath = parent.path || ""; + primaryContactId = parent.primaryContact ? parent.primaryContact.id : 0; + } + + contact.isPrimary = contact.id === primaryContactId; + + contact.path = parentPath + ? `${parentPath}/${Constant.CONTACTS_PATHNAME}/${contact.id}` + : null; + contact.url = contact.path ? `#/${contact.path}` : null; + contact.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_CONTACT, + contact + ); + + contact.canEdit = true; + contact.canDelete = true; + + return contact; +} + +// XXX: Looks like this is unused +// export function getContacts() { +// return new ApiRequest('/contacts').get().then(response => { +// var contacts = normalize(response.data); + +// // Add display fields +// _.map(contacts, contact => { parseContact(contact); }); + +// store.dispatch({ type: Action.UPDATE_CONTACTS, contacts: contacts }); +// }); +// } + +// XXX: Looks like this is unused +// export function getContact(contactId) { +// return new ApiRequest(`/contacts/${ contactId }`).get().then(response => { +// var contact = response.data; + +// // Add display fields +// parseContact(contact); + +// store.dispatch({ type: Action.UPDATE_CONTACT, contact: contact }); +// }); +// } + +// XXX: Looks like this is unused +// export function addContact(parent, contact) { +// return new ApiRequest('/contacts').post(contact).then(response => { +// var contact = response.data; + +// // Add display fields +// parseContact(contact, parent); + +// store.dispatch({ type: Action.ADD_CONTACT, contact: contact }); +// }); +// } + +// export function updateContact(parent, contact) { +// return new ApiRequest(`/contacts/${ contact.id }`).put(contact).then(response => { +// var contact = response.data; + +// // Add display fields +// parseContact(contact, parent); + +// store.dispatch({ type: Action.UPDATE_CONTACT, contact: contact }); +// }); +// } + +export function deleteContact(contact) { + store.dispatch({ type: Action.DELETE_CONTACT, contact }); + return new ApiRequest(`/contacts/${contact.id}/delete`) + .post() + .then((response) => { + var contact = response.data; + + // Add display fields + parseContact(contact); + + store.dispatch({ type: Action.DELETE_CONTACT, contact }); + }); +} + +//////////////////// +// Documents +//////////////////// + +function getFileSizeString(fileSizeInBytes) { + var bytes = parseInt(fileSizeInBytes, 10) || 0; + var kbytes = bytes >= 1024 ? bytes / 1024 : 0; + var mbytes = kbytes >= 1024 ? kbytes / 1024 : 0; + var gbytes = mbytes >= 1024 ? mbytes / 1024 : 0; + + var ceiling10 = function (num) { + var adjusted = Math.ceil(num * 10) / 10; + return adjusted.toFixed(1); + }; + + return gbytes + ? `${ceiling10(gbytes)} GB` + : mbytes + ? `${ceiling10(mbytes)} MB` + : kbytes + ? `${Math.ceil(kbytes)} KB` + : `${bytes} bytes`; +} + +function parseDocument(document) { + document.fileSizeDisplay = getFileSizeString(document.fileSize); + document.timestampSort = sortableDateTime(document.lastUpdateTimestamp); + document.name = document.fileName; + + document.canDelete = true; + document.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_DOCUMENT, + document + ); +} + +export function deleteDocument(document) { + return new ApiRequest(`/attachments/${document.id}/delete`).post(); +} + +export function getDownloadDocumentURL(document) { + // Not an API call, per se, as it must be called from the browser window. + return `${window.location.origin}${window.location.pathname}api/attachments/${document.id}/download`; +} + +//////////////////// +// History +//////////////////// + +function parseHistory(history) { + history.timestampSort = sortableDateTime(history.lastUpdateTimestamp); +} + +//////////////////// +// Projects +//////////////////// + +function parseProject(project) { + if (!project.district) { + project.district = { id: 0, name: "" }; + } + if (!project.district.region) { + project.district.region = { id: 0, name: "" }; + } + if (!project.contacts) { + project.contacts = []; + } + if (!project.rentalRequests) { + project.rentalRequests = []; + } + if (!project.rentalAgreements) { + project.rentalAgreements = []; + } + + project.name = project.name || ""; + project.provincialProjectNumber = project.provincialProjectNumber || ""; + project.information = project.information || ""; + + project.path = `${Constant.PROJECTS_PATHNAME}/${project.id}`; + project.url = `#/${project.path}`; + project.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_PROJECT, + project + ); + project.documentAdded = Log.projectDocumentAdded; + project.documentsAdded = Log.projectDocumentsAdded; + project.documentDeleted = Log.projectDocumentDeleted; + + // Add display fields for contacts + project.contacts = project.contacts.map((contact) => + parseContact(contact, project) + ); + + // Add display fields for rental requests and rental agreements + _.map(project.rentalRequests, (obj) => { + parseRentalRequest(obj); + }); + _.map(project.rentalAgreements, (obj) => { + parseRentalAgreement(obj); + }); + + project.numberOfRequests = + project.numberOfRequests || Object.keys(project.rentalRequests).length; + project.numberOfHires = + project.numberOfHires || Object.keys(project.rentalAgreements).length; + + // UI display fields + project.label = `${project.provincialProjectNumber} - ${project.name}`; + project.status = project.status || Constant.PROJECT_STATUS_CODE_ACTIVE; + project.isActive = project.status === Constant.PROJECT_STATUS_CODE_ACTIVE; + project.districtName = project.district.name; + + project.primaryContactName = project.primaryContact + ? firstLastName( + project.primaryContact.givenName, + project.primaryContact.surname + ) + : ""; + project.primaryContactRole = project.primaryContact + ? project.primaryContact.role + : ""; + project.primaryContactEmail = project.primaryContact + ? project.primaryContact.emailAddress + : ""; + project.primaryContactPhone = project.primaryContact + ? project.primaryContact.workPhoneNumber || + project.primaryContact.mobilePhoneNumber || + "" + : ""; + + project.getDocumentsPromise = getProjectDocuments; + project.uploadDocumentPath = `/projects/${project.id}/attachments`; + + project.canView = true; + project.canEdit = true; + project.canDelete = false; // TODO Needs input from Business whether this is needed. +} + +function formatTimeRecords(timeRecords, rentalRequestId) { + let formattedTimeRecords = Object.keys(timeRecords).map((key) => { + let timeRecord = {}; + timeRecord.workedDate = timeRecords[key].date; + timeRecord.hours = timeRecords[key].hours; + timeRecord.timePeriod = "Week"; + timeRecord.rentalAgreement = { id: rentalRequestId }; + return timeRecord; + }); + return formattedTimeRecords; +} + +export function searchProjects(params) { + store.dispatch({ type: Action.PROJECTS_REQUEST }); + return new ApiRequest("/projects/search").get(params).then((response) => { + var projects = normalize(response.data); + + // Add display fields + _.map(projects, (project) => { + parseProject(project); + }); + + store.dispatch({ type: Action.UPDATE_PROJECTS, projects: projects }); + }); +} + +export function searchTimeEntries(params) { + store.dispatch({ type: Action.TIME_ENTRIES_REQUEST }); + return new ApiRequest("/timeRecords/search").get(params).then((response) => { + var timeEntries = normalize(response.data); + + _.map(timeEntries, (entry) => { + entry.localAreaLabel = `${entry.serviceAreaId} - ${entry.localAreaName}`; + entry.equipmentDetails = [ + entry.make || "-", + entry.model || "-", + entry.size || "-", + entry.year || "-", + ].join("/"); + entry.sortableEquipmentCode = generateSortableEquipmentCode(entry); + }); + + store.dispatch({ + type: Action.UPDATE_TIME_ENTRIES, + timeEntries: timeEntries, + }); + }); +} + +export function searchHiringReport(params) { + store.dispatch({ type: Action.HIRING_RESPONSES_REQUEST }); + return new ApiRequest("/rentalRequests/hireReport") + .get(params) + .then((response) => { + var hiringResponses = normalize(response.data); + + _.map(hiringResponses, (entry) => { + entry.localAreaLabel = `${entry.serviceAreaId} - ${entry.localAreaName}`; + entry.equipmentDetails = [ + entry.equipmentMake || "-", + entry.equipmentModel || "-", + entry.equipmentSize || "-", + entry.equipmentYear || "-", + ].join("/"); + entry.sortableEquipmentCode = generateSortableEquipmentCode(entry); + }); + + store.dispatch({ + type: Action.UPDATE_HIRING_RESPONSES, + hiringResponses: hiringResponses, + }); + }); +} + +export function searchOwnersCoverage(params) { + store.dispatch({ type: Action.OWNERS_COVERAGE_REQUEST }); + return new ApiRequest("/owners/wcbCglReport").get(params).then((response) => { + var ownersCoverage = normalize(response.data); + + _.map(ownersCoverage, (entry) => { + entry.localAreaLabel = `${entry.serviceAreaId} - ${entry.localAreaName}`; + }); + + store.dispatch({ + type: Action.UPDATE_OWNERS_COVERAGE, + ownersCoverage: ownersCoverage, + }); + }); +} + +export function getProjects() { + const silent = store.getState().lookups.projects.loaded; + return new ApiRequest("/projects", { silent }) + .get({ currentFiscal: false }) + .then((response) => { + var projects = normalize(response.data); + + // Add display fields + _.map(projects, (project) => { + parseProject(project); + }); + + store.dispatch({ + type: Action.UPDATE_PROJECTS_LOOKUP, + projects: projects, + }); + }); +} + +export function getProjectsAgreementSummary() { + const silent = store.getState().lookups.projectsAgreementSummary.loaded; + return new ApiRequest("/projects/agreementSummary", { silent }) + .get() + .then((response) => { + var projects = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP, + projects: projects, + }); + }); +} + +export function getProjectsCurrentFiscal() { + const silent = store.getState().lookups.projectsCurrentFiscal.loaded; + return new ApiRequest("/projects", { silent }) + .get({ currentFiscal: true }) + .then((response) => { + var projects = normalize(response.data); + + // Add display fields + _.map(projects, (project) => { + parseProject(project); + }); + + store.dispatch({ + type: Action.UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP, + projects: projects, + }); + }); +} + +export function getProject(projectId) { + return new ApiRequest(`/projects/${projectId}`).get().then((response) => { + var project = response.data; + + // Add display fields + parseProject(project); + + store.dispatch({ type: Action.UPDATE_PROJECT, project: project }); + + return project; + }); +} + +export function addProject(project) { + return new ApiRequest("/projects").post(project).then((response) => { + var project = response.data; + + // Add display fields + parseProject(project); + + store.dispatch({ type: Action.ADD_PROJECT, project: project }); + + return project; + }); +} + +export function updateProject(project) { + const projectData = _.omit( + project, + "notes", + "contacts", + "historyEntity", + "primaryContact", + "rentalAgreements", + "rentalRequests" + ); + projectData.projectId = project.id; + + return new ApiRequest(`/projects/${project.id}`) + .put(projectData) + .then((response) => { + var project = response.data; + + // Add display fields + parseProject(project); + + store.dispatch({ type: Action.UPDATE_PROJECT, project: project }); + }); +} + +// XXX: Looks like this is unused +// export function getProjectEquipment(projectId) { +// return new ApiRequest(`/projects/${projectId}/equipment`).get().then(response => { +// var projectEquipment = normalize(response.data); + +// store.dispatch({ type: Action.UPDATE_PROJECT_EQUIPMENT, projectEquipment: projectEquipment }); +// }); +// } + +// XXX: Looks like this is unused +// export function getProjectTimeRecords(projectId) { +// return new ApiRequest(`projects/${projectId}/timeRecords`).get().then(response => { +// var projectTimeRecords = normalize(response.data); + +// store.dispatch({ type: Action.UPDATE_PROJECT_TIME_RECORDS, projectTimeRecords: projectTimeRecords }); +// }); +// } + +// XXX: Looks like this is unused +// export function addProjectTimeRecords(projectId, rentalRequestId, timeRecords) { +// let formattedTimeRecords = formatTimeRecords(timeRecords, rentalRequestId); +// return new ApiRequest(`projects/${projectId}/timeRecords`).post(formattedTimeRecords).then(response => { +// var projectTimeRecords = normalize(response.data); + +// store.dispatch({ type: Action.UPDATE_PROJECT_TIME_RECORDS, projectTimeRecords: projectTimeRecords }); +// return projectTimeRecords; +// }); +// } + +export function saveProjectContact(project, contact) { + const isNew = contact.id === 0; + + if (!isNew) { + // don't update if this is a new contact - add after post() completes + store.dispatch({ + type: Action.UPDATE_PROJECT_CONTACT, + projectId: project.id, + contact, + }); + } + + return new ApiRequest(`/projects/${project.id}/contacts/${contact.isPrimary}`) + .post(contact) + .then((response) => { + var updatedContact = response.data; + + // Add display fields + parseContact(updatedContact, project); // project's primary contact could be outdated + updatedContact.isPrimary = contact.isPrimary; + + if (isNew) { + // add newly created contact to Redux store's contacts + store.dispatch({ + type: Action.ADD_PROJECT_CONTACT, + projectId: project.id, + contact: updatedContact, + }); + } else { + // Update Redux store's data with the server's data + store.dispatch({ + type: Action.UPDATE_PROJECT_CONTACT, + projectId: project.id, + contact: updatedContact, + }); + } + + return updatedContact; + }); +} + +export function addProjectHistory(projectId, history) { + return new ApiRequest(`/projects/${projectId}/history`) + .post(history) + .then((response) => { + var history = normalize(response.data); + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_PROJECT_HISTORY, + history, + id: projectId, + }); + }); +} + +export function getProjectHistory(projectId, params) { + return new ApiRequest(`/projects/${projectId}/history`) + .get(params) + .then((response) => { + var history = normalize(response.data); + + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_PROJECT_HISTORY, + history, + id: projectId, + }); + }); +} + +export function getProjectDocuments(projectId) { + return new ApiRequest(`/projects/${projectId}/attachments`) + .get() + .then((response) => { + var documents = normalize(response.data); + + // Add display fields + _.map(documents, (document) => { + parseDocument(document); + }); + + store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); + }); +} + +// XXX: Looks like this is unused +// export function addProjectDocument(projectId, files) { +// return new ApiRequest(`/projects/${ projectId }/attachments`).post(files); +// } + +export function getProjectNotes(projectId) { + return new ApiRequest(`/projects/${projectId}/notes`) + .get() + .then((response) => { + store.dispatch({ + type: Action.UPDATE_PROJECT_NOTES, + projectId, + notes: response.data, + }); + return response.data; + }); +} + +export function addProjectNote(projectId, note) { + store.dispatch({ type: Action.ADD_PROJECT_NOTE, projectId, note }); + return new ApiRequest(`/projects/${projectId}/note`).post(note); +} + +export function getProjectRentalAgreements(projectId) { + return new ApiRequest(`/projects/${projectId}/rentalAgreements`) + .get() + .then((response) => { + var rentalAgreements = normalize(response.data); + store.dispatch({ + type: Action.UPDATE_PROJECT_RENTAL_AGREEMENTS, + rentalAgreements: rentalAgreements, + }); + return rentalAgreements; + }); +} + +export function cloneProjectRentalAgreement(data) { + return new ApiRequest(`/projects/${data.projectId}/rentalAgreementClone`) + .post(data) + .then((response) => { + var agreement = response.data; + // Add display fields + parseRentalAgreement(agreement); + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: agreement, + }); + return response; + }); +} + +//////////////////// +// Rental Requests +//////////////////// + +function parseRentalRequest(rentalRequest) { + if (!rentalRequest.localArea) { + rentalRequest.localArea = { id: 0, name: "" }; + } + if (!rentalRequest.localArea.serviceArea) { + rentalRequest.localArea.serviceArea = { id: 0, name: "" }; + } + if (!rentalRequest.localArea.serviceArea.district) { + rentalRequest.localArea.serviceArea.district = { id: 0, name: "" }; + } + if (!rentalRequest.localArea.serviceArea.district.region) { + rentalRequest.localArea.serviceArea.district.region = { id: 0, name: "" }; + } + if (!rentalRequest.project) { + rentalRequest.project = { id: 0, name: "" }; + } + if (!rentalRequest.districtEquipmentType) { + rentalRequest.districtEquipmentType = { id: 0, districtEquipmentName: "" }; + } + if (!rentalRequest.primaryContact) { + rentalRequest.primaryContact = { id: 0, givenName: "", surname: "" }; + } + if (!rentalRequest.rentalRequestAttachments) { + rentalRequest.rentalRequestAttachments = []; + } + if (!rentalRequest.rentalRequestRotationList) { + rentalRequest.rentalRequestRotationList = []; + } + + // Add display fields for primary contact + parseContact(rentalRequest.primaryContact); + + // Add display fields for rotation list items + _.map(rentalRequest.rentalRequestRotationList, (listItem) => { + parseRentalRequestRotationList(listItem, rentalRequest); + }); + + rentalRequest.status = + rentalRequest.status || Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS; + rentalRequest.equipmentCount = rentalRequest.equipmentCount || 0; + rentalRequest.expectedHours = rentalRequest.expectedHours || 0; + rentalRequest.expectedStartDate = rentalRequest.expectedStartDate || ""; + rentalRequest.expectedEndDate = rentalRequest.expectedEndDate || ""; + + rentalRequest.projectId = rentalRequest.projectId || rentalRequest.project.id; + rentalRequest.projectName = + rentalRequest.projectName || rentalRequest.project.name; + rentalRequest.projectPath = rentalRequest.projectId + ? `/projects/${rentalRequest.projectId}` + : ""; + + // UI display fields + rentalRequest.isActive = + rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS; + rentalRequest.isCompleted = + rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED; + rentalRequest.isCancelled = + rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_CANCELLED; + rentalRequest.localAreaName = + rentalRequest.localAreaName || rentalRequest.localArea.name; + rentalRequest.equipmentTypeName = + rentalRequest.equipmentTypeName || + rentalRequest.districtEquipmentType.districtEquipmentName; + + // Primary contact for the rental request/project + rentalRequest.primaryContactName = rentalRequest.primaryContact + ? firstLastName( + rentalRequest.primaryContact.givenName, + rentalRequest.primaryContact.surname + ) + : ""; + rentalRequest.primaryContactEmail = rentalRequest.primaryContact + ? rentalRequest.primaryContact.emailAddress + : ""; + rentalRequest.primaryContactRole = rentalRequest.primaryContact + ? rentalRequest.primaryContact.role + : ""; + rentalRequest.primaryContactPhone = rentalRequest.primaryContact + ? rentalRequest.primaryContact.workPhoneNumber || + rentalRequest.primaryContact.mobilePhoneNumber || + "" + : ""; + + rentalRequest.projectPrimaryContactName = rentalRequest.project.primaryContact + ? firstLastName( + rentalRequest.project.primaryContact.givenName, + rentalRequest.project.primaryContact.surname + ) + : ""; + rentalRequest.projectPrimaryContactEmail = rentalRequest.project + .primaryContact + ? rentalRequest.project.primaryContact.emailAddress + : ""; + rentalRequest.projectPrimaryContactRole = rentalRequest.project.primaryContact + ? rentalRequest.project.primaryContact.role + : ""; + rentalRequest.projectPrimaryContactPhone = rentalRequest.project + .primaryContact + ? rentalRequest.project.primaryContact.workPhoneNumber || + rentalRequest.project.primaryContact.mobilePhoneNumber || + "" + : ""; + // Flag element as a rental request. + // Rental requests and rentals are merged and shown in a single list on Project Details screen + rentalRequest.isRentalRequest = true; + + rentalRequest.path = `${Constant.RENTAL_REQUESTS_PATHNAME}/${rentalRequest.id}`; + rentalRequest.url = `#/${rentalRequest.path}`; + rentalRequest.name = "TBD"; + rentalRequest.historyEntity = History.makeHistoryEntity( + Constant.HISTORY_REQUEST, + rentalRequest + ); + rentalRequest.documentAdded = Log.rentalRequestDocumentAdded; + rentalRequest.documentsAdded = Log.rentalRequestDocumentsAdded; + rentalRequest.documentDeleted = Log.rentalRequestDocumentDeleted; + + rentalRequest.getDocumentsPromise = getRentalRequestDocuments; + rentalRequest.uploadDocumentPath = `/rentalrequests/${rentalRequest.id}/attachments`; + + rentalRequest.canView = true; + rentalRequest.canEdit = true; + // HETS-894: view-only requests and requests that have yet to be acted on can be deleted + rentalRequest.canDelete = + rentalRequest.projectId === 0 || rentalRequest.yesCount === 0; +} + +export function searchRentalRequests(params) { + store.dispatch({ type: Action.RENTAL_REQUESTS_REQUEST }); + return new ApiRequest("/rentalrequests/search") + .get(params) + .then((response) => { + var rentalRequests = normalize(response.data); + + // Add display fields + _.map(rentalRequests, (req) => { + parseRentalRequest(req); + }); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUESTS, + rentalRequests: rentalRequests, + }); + }); +} + +export function getRentalRequest(id) { + return new ApiRequest(`/rentalrequests/${id}`).get().then((response) => { + var rentalRequest = response.data; + // Add display fields + parseRentalRequest(rentalRequest); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST, + rentalRequest, + rentalRequestId: id, + }); + + return rentalRequest; + }); +} + +export function addRentalRequest(rentalRequest, viewOnly) { + var path = viewOnly ? "/rentalrequests/viewOnly" : "/rentalrequests"; + + return new ApiRequest(path).post(rentalRequest).then((response) => { + var rentalRequest = response.data; + // Add display fields + parseRentalRequest(rentalRequest); + store.dispatch({ + type: Action.ADD_RENTAL_REQUEST, + rentalRequest, + rentalRequestId: rentalRequest.id, + }); + + getEquipmentHires(); + + return rentalRequest; + }); +} + +export function updateRentalRequest(rentalRequest) { + // remove properties that interfere with deserialization + const rentalRequestId = rentalRequest.id; + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST, + rentalRequest, + rentalRequestId, + }); + + return new ApiRequest(`/rentalrequests/${rentalRequest.id}`) + .put(_.omit(rentalRequest, "primaryContact")) + .then((response) => { + var rentalRequest = response.data; + // Add display fields + parseRentalRequest(rentalRequest); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST, + rentalRequest, + rentalRequestId, + }); + }); +} + +export function addRentalRequestHistory(requestId, history) { + return new ApiRequest(`/rentalrequests/${requestId}/history`) + .post(history) + .then((response) => { + var history = normalize(response.data); + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_HISTORY, + history, + id: requestId, + }); + }); +} + +export function getRentalRequestHistory(requestId, params) { + return new ApiRequest(`/rentalrequests/${requestId}/history`) + .get(params) + .then((response) => { + var history = normalize(response.data); + + // Add display fields + _.map(history, (history) => { + parseHistory(history); + }); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_HISTORY, + history, + id: requestId, + }); + }); +} + +export function getRentalRequestDocuments(rentalRequestId) { + return new ApiRequest(`/rentalrequests/${rentalRequestId}/attachments`) + .get() + .then((response) => { + var documents = normalize(response.data); + + // Add display fields + _.map(documents, (document) => { + parseDocument(document); + }); + + store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); + }); +} + +// XXX: Looks like this is unused +// export function addRentalRequestDocument(rentalRequestId, files) { +// return new ApiRequest(`/rentalrequests/${ rentalRequestId }/attachments`).post(files); +// } + +export function getRentalRequestNotes(rentalRequestId) { + return new ApiRequest(`/rentalrequests/${rentalRequestId}/notes`) + .get() + .then((response) => { + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_NOTES, + notes: response.data, + rentalRequestId, + }); + return response.data; + }); +} + +export function addRentalRequestNote(rentalRequestId, note) { + return new ApiRequest(`/rentalRequests/${rentalRequestId}/note`) + .post(note) + .then((response) => { + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_NOTES, + notes: response.data, + rentalRequestId, + }); + return response.data; + }); +} + +export function cancelRentalRequest(rentalRequestId) { + return new ApiRequest(`rentalrequests/${rentalRequestId}/cancel`) + .get() + .then(() => { + getEquipmentHires(); + }); +} + +//////////////////// +// Rental Request Rotation List +//////////////////// + +function getSeniorityDisplayName( + blockNumber, + numberOfBlocks, + seniority, + numberInBlock +) { + if (blockNumber === numberOfBlocks) { + return `Open-${seniority && seniority.toFixed(3)} (${numberInBlock})`; + } else if (blockNumber === 1) { + return `1-${seniority && seniority.toFixed(3)} (${numberInBlock})`; + } else if (blockNumber === 2) { + return `2-${seniority && seniority.toFixed(3)} (${numberInBlock})`; + } + return `Open-${seniority && seniority.toFixed(3)} (${numberInBlock})`; +} + +function parseRentalRequestRotationList(rotationListItem, rentalRequest = {}) { + if (!rotationListItem.rentalRequest) { + rotationListItem.rentalRequest = _.extend( + { id: 0 }, + _.pick(rentalRequest, "id") + ); + } + if (!rotationListItem.equipment) { + rotationListItem.equipment = { id: 0, equipmentCode: "" }; + } + if (!rotationListItem.equipment.districtEquipmentType) { + rotationListItem.equipment.districtEquipmentType = { + id: 0, + districtEquipmentName: "", + }; + } + if (!rotationListItem.equipment.owner) { + rotationListItem.equipment.owner = { id: 0, organizationName: "" }; + } + + // The rental agreement (if any) created for an accepted hire offer. + rotationListItem.rentalAgreement = rotationListItem.rentalAgreement || null; + + // The sort order of the piece of equipment on the rotaton list at the time the request was created. + // This is the order the equipment will be offered the available work. + rotationListItem.rotationListSortOrder = + rotationListItem.rotationListSortOrder || 0; + + rotationListItem.isForceHire = rotationListItem.isForceHire || false; + rotationListItem.wasAsked = rotationListItem.wasAsked || false; + rotationListItem.askedDateTime = rotationListItem.askedDateTime || ""; + rotationListItem.offerResponseDatetime = + rotationListItem.offerResponseDatetime || ""; + rotationListItem.offerResponse = rotationListItem.offerResponse || ""; + rotationListItem.offerRefusalReason = + rotationListItem.offerRefusalReason || ""; + rotationListItem.offerResponseNote = rotationListItem.offerResponseNote || ""; + rotationListItem.note = rotationListItem.note || ""; + + var equipment = rotationListItem.equipment; + + // UI display fields + rotationListItem.isHired = rotationListItem.isHired || false; + rotationListItem.seniority = getSeniorityDisplayName( + equipment.blockNumber, + equipment.numberOfBlocks, + equipment.seniority, + equipment.numberInBlock + ); + rotationListItem.serviceHoursThisYear = + rotationListItem.serviceHoursThisYear || + equipment.serviceHoursThisYear || + 0; // TODO calculated field from the server + rotationListItem.equipmentId = equipment.id; + rotationListItem.equipmentCode = equipment.equipmentCode; + + // String format: "{year} {make}/{model}/{serialNumber}/{size}" - e.g. "1991 Bobcat/KOM450/442K00547/Medium" + rotationListItem.equipmentDetails = concat( + equipment.year, + concat( + equipment.make, + concat( + equipment.model, + concat(equipment.serialNumber, equipment.size, "/"), + "/" + ), + "/" + ), + " " + ); + + // Primary contact for the owner of the piece of equipment + rotationListItem.contact = + rotationListItem.contact || + (equipment.owner ? equipment.owner.primaryContact : null); + rotationListItem.contactName = rotationListItem.contact + ? firstLastName( + rotationListItem.contact.givenName, + rotationListItem.contact.surname + ) + : ""; + rotationListItem.contactEmail = rotationListItem.contact + ? rotationListItem.contact.emailAddress + : ""; + rotationListItem.contactPhone = rotationListItem.contact + ? rotationListItem.contact.workPhoneNumber || + rotationListItem.contact.mobilePhoneNumber || + "" + : ""; + + // TODO Status TBD + rotationListItem.status = "N/A"; +} + +function parseRotationListItem(item, numberOfBlocks) { + item.equipment = item.equipment || {}; + item.equipment = { + ...item.equipment, + historyEntity: History.makeHistoryEntity(Constant.HISTORY_EQUIPMENT, { + ...item.equipment, + name: item.equipment.equipmentCode, + path: `${Constant.EQUIPMENT_PATHNAME}/${item.equipment.id}`, + url: `#/${Constant.EQUIPMENT_PATHNAME}/${item.equipment.id}`, + }), + }; + + item.displayFields = {}; + item.displayFields.equipmentDetails = concat( + item.equipment.year, + concat( + item.equipment.make, + concat( + item.equipment.model, + concat(item.equipment.serialNumber, item.equipment.size, "/"), + "/" + ), + "/" + ), + " " + ); + item.displayFields.seniority = getSeniorityDisplayName( + item.equipment.blockNumber, + numberOfBlocks, + item.equipment.seniority, + item.equipment.numberInBlock + ); + + var primaryContact = + item.equipment.owner && item.equipment.owner.primaryContact; + item.displayFields.primaryContactName = primaryContact + ? firstLastName(primaryContact.givenName, primaryContact.surname) + : ""; +} + +export function getRentalRequestRotationList(id) { + return new ApiRequest(`/rentalrequests/${id}/rotationList`) + .get() + .then((response) => { + const rentalRequest = response.data; + const rotationList = rentalRequest.rentalRequestRotationList; + + rotationList.map((item) => + parseRotationListItem(item, rentalRequest.numberOfBlocks) + ); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST, + rotationList, + rentalRequestId: id, + }); + }); +} + +export function updateRentalRequestRotationList( + rentalRequestRotationList, + rentalRequest +) { + const rentalRequestId = rentalRequest.id; + return new ApiRequest( + `/rentalrequests/${rentalRequestId}/rentalRequestRotationList` + ) + .put(rentalRequestRotationList) + .then((response) => { + var rotationList = response.data.rentalRequestRotationList; + + rotationList.map((item) => + parseRotationListItem(item, rentalRequest.numberOfBlocks) + ); + + store.dispatch({ + type: Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST, + rotationList, + rentalRequestId, + }); + + getEquipmentTs(); + getEquipmentHires(); + }); +} + +//////////////////// +// Rental Agreements +//////////////////// + +function parseRentalAgreement(agreement) { + if (!agreement.district) { + agreement.district = { id: 0, name: "" }; + } + if (!agreement.equipment) { + agreement.equipment = { id: 0, equipmentCode: "" }; + } + if (!agreement.equipment.owner) { + agreement.equipment.owner = { id: 0, organizationName: "" }; + } + if (!agreement.equipment.districtEquipmentType) { + agreement.equipment.districtEquipmentType = { + id: 0, + districtEquipmentName: "", + }; + } + if (!agreement.equipment.equipmentAttachments) { + agreement.equipment.equipmentAttachments = []; + } + if (!agreement.equipment.localArea) { + agreement.equipment.localArea = { id: 0, name: "" }; + } + if (!agreement.equipment.localArea.serviceArea) { + agreement.equipment.localArea.serviceArea = { id: 0, name: "" }; + } + if (!agreement.equipment.localArea.serviceArea.district) { + agreement.equipment.localArea.serviceArea.district = { id: 0, name: "" }; + } + if (!agreement.equipment.localArea.serviceArea.district.region) { + agreement.equipment.localArea.serviceArea.district.region = { + id: 0, + name: "", + }; + } + if (!agreement.project) { + agreement.project = { id: 0, name: "" }; + } + if (!agreement.rentalAgreementRates) { + agreement.rentalAgreementRates = []; + } + if (!agreement.rentalAgreementConditions) { + agreement.rentalAgreementConditions = []; + } + if (!agreement.timeRecords) { + agreement.timeRecords = []; + } + + agreement.path = `${Constant.RENTAL_AGREEMENTS_PATHNAME}/${agreement.id}`; + agreement.url = `#/${agreement.path}`; + + agreement.number = agreement.number || ""; + agreement.note = agreement.note || ""; + agreement.datedOn = agreement.datedOn || today(); + agreement.equipmentRate = agreement.equipmentRate || 0.0; + agreement.ratePeriod = agreement.ratePeriod || ""; // e.g. hourly, daily, etc. + agreement.rateComment = agreement.rateComment || ""; + + agreement.estimateStartWork = agreement.estimateStartWork || ""; + agreement.estimateHours = agreement.estimateHours || 0; + + agreement.rentalAgreementRates.forEach((obj) => + parseRentalRate(obj, agreement) + ); + agreement.rentalAgreementConditions.forEach((obj) => + parseRentalCondition(obj, agreement) + ); + + agreement.equipment = { + ...agreement.equipment, + historyEntity: History.makeHistoryEntity(Constant.HISTORY_EQUIPMENT, { + ...agreement.equipment, + name: agreement.equipment.equipmentCode, + path: `${Constant.EQUIPMENT_PATHNAME}/${agreement.equipment.id}`, + url: `#/${Constant.EQUIPMENT_PATHNAME}/${agreement.equipment.id}`, + }), + }; + + // UI display fields + agreement.status = + agreement.status || Constant.RENTAL_AGREEMENT_STATUS_CODE_ACTIVE; // TODO + agreement.isActive = + agreement.status === Constant.RENTAL_AGREEMENT_STATUS_CODE_ACTIVE; + agreement.isCompleted = + agreement.status === Constant.RENTAL_AGREEMENT_STATUS_CODE_COMPLETED; + agreement.equipmentId = agreement.equipment.id; + agreement.equipmentCode = agreement.equipment.equipmentCode; + agreement.equipmentMake = agreement.equipment.make; + agreement.equipmentModel = agreement.equipment.model; + agreement.equipmentSize = agreement.equipment.size; + agreement.equipmentTypeName = + agreement.equipment.districtEquipmentType.districtEquipmentName; + agreement.ownerId = agreement.equipment.owner.id || 0; + agreement.ownerName = agreement.equipment.owner.organizationName || ""; + agreement.workSafeBCPolicyNumber = + agreement.equipment.owner.workSafeBCPolicyNumber || ""; + agreement.pointOfHire = agreement.equipment.localArea.name || ""; + + agreement.projectId = agreement.projectId || agreement.project.id; + agreement.projectName = agreement.projectName || agreement.project.name; + + agreement.projectPath = agreement.projectId + ? `${Constant.PROJECTS_PATHNAME}/${agreement.projectId}` + : ""; + agreement.projectUrl = agreement.projectPath + ? `#/${agreement.projectPath}` + : ""; + + agreement.canEdit = true; + + // Flag element as a rental agreement + // Rental requests and rentals are merged and shown in a single list on Project Details screen + agreement.isRentalAgreement = true; + + // TODO HETS-115 Server needs to send this + agreement.lastTimeRecord = agreement.lastTimeRecord || ""; +} + +// reverse the transformations applied by the parse function +function convertRentalAgreement(agreement) { + return { + ...agreement, + rentalAgreementConditions: _.values(agreement.rentalAgreementConditions), + rentalAgreementRates: _.values(agreement.rentalAgreementRates), + overtimeRates: _.values(agreement.overtimeRates), + equipmentId: agreement.equipmentId || null, + projectId: agreement.projectId || null, + }; +} + +export function getRentalAgreementSummaryLite() { + return new ApiRequest("/rentalagreements/summaryLite") + .get() + .then((response) => { + var agreements = response.data; + + store.dispatch({ + type: Action.UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP, + agreements, + }); + }); +} + +export function getRentalAgreement(id) { + return new ApiRequest(`/rentalagreements/${id}`).get().then((response) => { + var agreement = response.data; + + // Add display fields + parseRentalAgreement(agreement); + + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: agreement, + }); + }); +} + +export function getLatestRentalAgreement(equipmentId, projectId) { + return new ApiRequest(`/rentalagreements/latest/${projectId}/${equipmentId}`) + .get() + .then((response) => { + var agreement = response.data; + + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: agreement, + }); + + return agreement; + }); +} + +// XXX: Looks like this is unused +// export function addRentalAgreement(agreement) { +// return new ApiRequest('/rentalagreements').post(agreement).then(response => { +// var agreement = response.data; + +// // Add display fields +// parseRentalAgreement(agreement); + +// store.dispatch({ type: Action.ADD_RENTAL_AGREEMENT, rentalAgreement: agreement }); +// }); +// } + +export function updateRentalAgreement(agreement) { + var preparedAgreement = convertRentalAgreement(agreement); + + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: preparedAgreement, + }); + + return new ApiRequest(`/rentalagreements/${agreement.id}`) + .put(preparedAgreement) + .then((response) => { + var agreement = response.data; + + // Add display fields + parseRentalAgreement(agreement); + + store.dispatch({ + type: Action.UPDATE_RENTAL_AGREEMENT, + rentalAgreement: agreement, + }); + }); +} + +export function getRentalAgreementTimeRecords(rentalAgreementId) { + return new ApiRequest(`rentalagreements/${rentalAgreementId}/timeRecords`) + .get() + .then((response) => { + var rentalAgreementTimeRecords = response.data; + + store.dispatch({ + type: Action.RENTAL_AGREEMENT_TIME_RECORDS, + rentalAgreementTimeRecords: rentalAgreementTimeRecords, + }); + }); +} + +export function addRentalAgreementTimeRecords(rentalRequestId, timeRecords) { + let formattedTimeRecords = formatTimeRecords(timeRecords, rentalRequestId); + return new ApiRequest(`rentalagreements/${rentalRequestId}/timeRecords`) + .post(formattedTimeRecords) + .then((response) => { + var rentalAgreementTimeRecords = normalize(response.data.timeRecords); + + store.dispatch({ + type: Action.RENTAL_AGREEMENT_TIME_RECORDS, + rentalAgreementTimeRecords: rentalAgreementTimeRecords, + }); + return rentalAgreementTimeRecords; + }); +} + +export function releaseRentalAgreement(rentalAgreementId) { + return new ApiRequest(`rentalagreements/${rentalAgreementId}/release`) + .post() + .then((response) => { + return response; + }); +} + +export function generateRentalAgreementDocument(rentalAgreementId) { + return new ApiRequest(`rentalagreements/${rentalAgreementId}/doc`).get(null, { + ignoreResponse: true, + }); +} + +export function searchAitReport(params) { + store.dispatch({ type: Action.AIT_REPORT_REQUEST }); + return new ApiRequest("/rentalAgreements/aitReport") + .get(params) + .then((response) => { + var aitResponses = normalize(response.data); + store.dispatch({ + type: Action.UPDATE_AIT_REPORT, + aitResponses: aitResponses, + }); + }); +} + +//////////////////// +// Rental Rates +//////////////////// + +function parseRentalRate(rentalRate, parent = {}) { + // Pick only the properties that we need + if (!rentalRate.rentalAgreement) { + rentalRate.rentalAgreement = _.extend( + { id: 0, equipmentRate: 0 }, + _.pick(parent, "id", "number", "path", "equipmentRate") + ); + } + if (!rentalRate.timeRecords) { + rentalRate.timeRecords = []; + } + + rentalRate.path = rentalRate.rentalAgreement.path + ? `${rentalRate.rentalAgreement.path}/${Constant.RENTAL_RATES_PATHNAME}/${rentalRate.id}` + : null; + rentalRate.url = rentalRate.path ? `#/${rentalRate.path}` : null; + + rentalRate.rate = rentalRate.rate || 0.0; + rentalRate.percentOfEquipmentRate = rentalRate.percentOfEquipmentRate || 0; + rentalRate.ratePeriod = + rentalRate.ratePeriod || rentalRate.ratePeriodType.ratePeriodTypeCode; + rentalRate.comment = rentalRate.comment || ""; + + // UI display fields + rentalRate.rentalAgreementId = rentalRate.rentalAgreement.id; + rentalRate.rentalAgreementNumber = rentalRate.rentalAgreement.number; + + rentalRate.canEdit = true; + rentalRate.canDelete = true; +} + +// XXX: Looks like this is unused +// export function getRentalRate(id) { +// return new ApiRequest(`/rentalagreementrates/${ id }`).get().then(response => { +// var rentalRate = response.data; + +// // Add display fields +// parseRentalRate(rentalRate); + +// store.dispatch({ type: Action.UPDATE_RENTAL_RATE, rentalRate: rentalRate }); +// }); +// } + +// export function addRentalRate(rentalRate) { +// return new ApiRequest('/rentalagreementrates').post({ ...rentalRate, rentalAgreement: { id: rentalRate.rentalAgreement.id } }).then(response => { +// var rentalRate = response.data; + +// // Add display fields +// parseRentalRate(rentalRate); + +// store.dispatch({ type: Action.ADD_RENTAL_RATE, rentalRate }); +// }); +// } + +export function addRentalRates(rentalAgreementId, rentalRates) { + store.dispatch({ + type: Action.ADD_RENTAL_RATES, + rentalRates, + rentalAgreementId, + }); + + return new ApiRequest(`rentalagreements/${rentalAgreementId}/rateRecords`) + .post(rentalRates) + .then((response) => { + const data = _.find(response.data, { rentalAgreementId }); + var rentalRates = data.rentalAgreement.rentalAgreementRates; + + // Add display fields + rentalRates.forEach((rentalRate) => + parseRentalRate(rentalRate, data.rentalAgreement) + ); + + store.dispatch({ + type: Action.UPDATE_RENTAL_RATES, + rentalRates, + rentalAgreementId, + }); + + return rentalRates; + }); +} + +export function updateRentalRate(rentalRate) { + const rentalAgreementId = rentalRate.rentalAgreement.id; + store.dispatch({ + type: Action.UPDATE_RENTAL_RATES, + rentalRates: [rentalRate], + rentalAgreementId, + }); + + return new ApiRequest(`/rentalagreementrates/${rentalRate.id}`) + .put(rentalRate) + .then((response) => { + var rentalRate = response.data; + + // Add display fields + parseRentalRate(rentalRate); + + store.dispatch({ + type: Action.UPDATE_RENTAL_RATES, + rentalRates: [rentalRate], + rentalAgreementId, + }); + + return rentalRate; + }); +} + +export function deleteRentalRate(rentalRate) { + const rentalAgreementId = rentalRate.rentalAgreement.id; + store.dispatch({ + type: Action.DELETE_RENTAL_RATE, + rentalRate, + rentalAgreementId, + }); + + return new ApiRequest(`/rentalagreementrates/${rentalRate.id}/delete`) + .post() + .then((response) => { + const rentalRate = response.data; + + // Add display fields + parseRentalRate(rentalRate); + + store.dispatch({ + type: Action.DELETE_RENTAL_RATE, + rentalRate, + rentalAgreementId, + }); + + return rentalRate; + }); +} + +//////////////////// +// Rental Conditions +//////////////////// + +function parseRentalCondition(rentalCondition, parent = {}) { + // Pick only the properties that we need + if (!rentalCondition.rentalAgreement) { + rentalCondition.rentalAgreement = _.extend( + { id: 0 }, + _.pick(parent, "id", "number", "path") + ); + } + + rentalCondition.conditionName = rentalCondition.conditionName || ""; + rentalCondition.comment = rentalCondition.comment || ""; + + // UI display fields + rentalCondition.rentalAgreementId = rentalCondition.rentalAgreement.id; + rentalCondition.rentalAgreementNumber = + rentalCondition.rentalAgreement.number; + rentalCondition.path = rentalCondition.rentalAgreement.path + ? `${rentalCondition.rentalAgreement.path}/${Constant.RENTAL_CONDITIONS_PATHNAME}/${rentalCondition.id}` + : null; + rentalCondition.url = rentalCondition.path + ? `#/${rentalCondition.path}` + : null; + + rentalCondition.canEdit = true; + rentalCondition.canDelete = true; +} + +// XXX: Looks like this is unused +// export function getRentalCondition(id) { +// return new ApiRequest(`/rentalagreementconditions/${ id }`).get().then(response => { +// var rentalCondition = response.data; + +// // Add display fields +// parseRentalCondition(rentalCondition); + +// store.dispatch({ type: Action.UPDATE_RENTAL_CONDITION, rentalCondition: rentalCondition }); +// }); +// } + +// XXX: Looks like this is unused +// export function addRentalCondition(rentalCondition) { +// return new ApiRequest('/rentalagreementconditions').post({ ...rentalCondition, rentalAgreement: { id: rentalCondition.rentalAgreement.id } }).then(response => { +// var rentalCondition = response.data; + +// // Add display fields +// parseRentalCondition(rentalCondition); + +// store.dispatch({ type: Action.ADD_RENTAL_CONDITION, rentalCondition: rentalCondition }); +// }); +// } + +export function addRentalConditions(rentalAgreementId, rentalConditions) { + store.dispatch({ + type: Action.ADD_RENTAL_CONDITIONS, + rentalConditions, + rentalAgreementId, + }); + + return new ApiRequest( + `rentalagreements/${rentalAgreementId}/conditionRecords` + ) + .post(rentalConditions) + .then((response) => { + const data = _.find(response.data, { rentalAgreementId }); + var rentalConditions = data.rentalAgreement.rentalAgreementConditions; + + // Add display fields + rentalConditions.forEach((rentalCondition) => + parseRentalCondition(rentalCondition, data.rentalAgreement) + ); + + store.dispatch({ + type: Action.UPDATE_RENTAL_CONDITIONS, + rentalConditions, + rentalAgreementId, + }); + + return rentalConditions; + }); +} + +export function updateRentalCondition(rentalCondition) { + const rentalAgreementId = rentalCondition.rentalAgreement.id; + store.dispatch({ + type: Action.UPDATE_RENTAL_CONDITIONS, + rentalConditions: [rentalCondition], + rentalAgreementId, + }); + + return new ApiRequest(`/rentalagreementconditions/${rentalCondition.id}`) + .put(rentalCondition) + .then((response) => { + var rentalCondition = response.data; + + // Add display fields + parseRentalCondition(rentalCondition); + + store.dispatch({ + type: Action.UPDATE_RENTAL_CONDITIONS, + rentalConditions: [rentalCondition], + rentalAgreementId, + }); + + return rentalCondition; + }); +} + +export function deleteRentalCondition(rentalCondition) { + const rentalAgreementId = rentalCondition.rentalAgreement.id; + store.dispatch({ + type: Action.DELETE_RENTAL_CONDITION, + rentalCondition, + rentalAgreementId, + }); + + return new ApiRequest( + `/rentalagreementconditions/${rentalCondition.id}/delete` + ) + .post() + .then((response) => { + var rentalCondition = response.data; + + // Add display fields + parseRentalCondition(rentalCondition); + + store.dispatch({ + type: Action.DELETE_RENTAL_CONDITION, + rentalCondition, + rentalAgreementId, + }); + + return rentalCondition; + }); +} + +export function deleteCondition(id) { + return new ApiRequest(`/conditiontypes/${id}/delete`) + .post() + .then((response) => { + return response; + }); +} + +export function addCondition(condition) { + return new ApiRequest("conditiontypes/0").post(condition).then((response) => { + return response; + }); +} + +export function updateCondition(condition) { + return new ApiRequest(`conditiontypes/${condition.id}`) + .post(condition) + .then((response) => { + return response; + }); +} + +//////////////////// +// Business +//////////////////// + +export function getBusiness() { + return new ApiRequest("/business").get().then((response) => { + var business = response.data; + + if (!_.isObject(business)) { + business = {}; + } + + _.map(business.owners, (owner) => { + parseOwner(owner); + }); + store.dispatch({ type: Action.UPDATE_BUSINESS, business: business }); + }); +} + +export function getOwnerForBusiness(ownerId) { + return new ApiRequest(`/business/owner/${ownerId}`).get().then((response) => { + var owner = response.data; + + parseOwner(owner); + store.dispatch({ type: Action.UPDATE_OWNER, owner: owner }); + }); +} + +export function validateOwner(secretKey, postalCode) { + return new ApiRequest("/business/validateOwner") + .get({ sharedKey: secretKey, postalCode: postalCode }) + .then((response) => { + var business = response.data; + parseOwner(business.linkedOwner); + store.dispatch({ type: Action.UPDATE_BUSINESS, business: business }); + }); +} + +//////////////////// +// Rollovers +//////////////////// + +function parseRolloverStatus(status) { + status.rolloverInactive = status.progressPercentage == null; + status.rolloverActive = + status.progressPercentage != null && + status.progressPercentage >= 0 && + status.progressPercentage < 100; + status.rolloverComplete = status.progressPercentage === 100; +} + +export function getRolloverStatus(districtId) { + return new ApiRequest(`/districts/${districtId}/rolloverStatus`) + .get(null, { silent: true }) + .then((response) => { + var status = response.data; + parseRolloverStatus(status); + store.dispatch({ + type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, + status: status, + }); + }); +} + +export function initiateRollover(districtId) { + return new ApiRequest(`/districts/${districtId}/annualRollover`) + .get() + .then((response) => { + var status = response; + parseRolloverStatus(status); + store.dispatch({ + type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, + status: status, + }); + }); +} + +export function dismissRolloverMessage(districtId) { + return new ApiRequest(`/districts/${districtId}/dismissRolloverMessage`) + .post() + .then((response) => { + var status = response.data; + parseRolloverStatus(status); + store.dispatch({ + type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, + status: status, + }); + }); +} + +//////////////////// +// Look-ups +//////////////////// + +// XXX: Looks like this is unused +// export function getCities() { +// return new ApiRequest('/cities').get().then(response => { +// var cities = normalize(response.data); + +// store.dispatch({ type: Action.UPDATE_CITIES_LOOKUP, cities: cities }); +// }); +// } + +export function getDistricts() { + return new ApiRequest("/districts").get().then((response) => { + var districts = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_DISTRICTS_LOOKUP, + districts: districts, + }); + }); +} + +export function getRegions() { + return new ApiRequest("/regions").get().then((response) => { + var regions = normalize(response.data); + + store.dispatch({ type: Action.UPDATE_REGIONS_LOOKUP, regions: regions }); + }); +} + +export function getLocalAreas(id) { + return new ApiRequest(`/districts/${id}/localAreas`) + .get() + .then((response) => { + var localAreas = normalize(response.data); + _.map( + localAreas, + (area) => (area.name = `${area.serviceAreaId} - ${area.name}`) + ); + + store.dispatch({ + type: Action.UPDATE_LOCAL_AREAS_LOOKUP, + localAreas: localAreas, + }); + }); +} + +export function getServiceAreas() { + return new ApiRequest("/serviceareas").get().then((response) => { + var serviceAreas = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_SERVICE_AREAS_LOOKUP, + serviceAreas: serviceAreas, + }); + }); +} + +export function getEquipmentTypes() { + const silent = store.getState().lookups.equipmentTypes.loaded; + return new ApiRequest("/equipmenttypes", { silent }) + .get() + .then((response) => { + var equipmentTypes = _.mapValues(normalize(response.data), (x) => { + x.blueBookSectionAndName = `${x.blueBookSection} - ${x.name}`; + return x; + }); + + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_TYPES_LOOKUP, + equipmentTypes, + }); + }); +} + +export function getDistrictEquipmentTypes() { + const silent = store.getState().lookups.districtEquipmentTypes.loaded; + return new ApiRequest("/districtequipmenttypes", { silent }) + .get() + .then((response) => { + var districtEquipmentTypes = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP, + districtEquipmentTypes: districtEquipmentTypes, + }); + }); +} + +export function getDistrictEquipmentTypesAgreementSummary() { + const silent = + store.getState().lookups.districtEquipmentTypesAgreementSummary.loaded; + return new ApiRequest("/districtequipmenttypes/agreementSummary", { silent }) + .get() + .then((response) => { + var districtEquipmentTypes = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP, + districtEquipmentTypes, + }); + }); +} + +export function getFiscalYears(districtId) { + return new ApiRequest(`/districts/${districtId}/fiscalYears`) + .get() + .then((response) => { + store.dispatch({ + type: Action.UPDATE_FISCAL_YEARS_LOOKUP, + fiscalYears: response.data, + }); + }); +} + +export function getOwnersLite() { + const silent = store.getState().lookups.owners.lite.loaded; + return new ApiRequest("/owners/lite", { silent }).get().then((response) => { + var owners = normalize(response.data); + store.dispatch({ type: Action.UPDATE_OWNERS_LITE_LOOKUP, owners: owners }); + }); +} + +export function getOwnersLiteHires() { + const silent = store.getState().lookups.owners.hires.loaded; + return new ApiRequest("/owners/liteHires", { silent }) + .get() + .then((response) => { + var owners = normalize(response.data); + store.dispatch({ + type: Action.UPDATE_OWNERS_LITE_HIRES_LOOKUP, + owners: owners, + }); + }); +} + +export function getOwnersLiteTs() { + const silent = store.getState().lookups.owners.ts.loaded; + return new ApiRequest("/owners/liteTs", { silent }).get().then((response) => { + var owners = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_OWNERS_LITE_TS_LOOKUP, + owners: owners, + }); + }); +} + +export function addDistrictEquipmentType(equipment) { + return new ApiRequest(`/districtequipmenttypes/${equipment.id}`) + .post(equipment) + .then((response) => { + return response; + }); +} + +export function updateDistrictEquipmentType(equipment) { + return new ApiRequest(`/districtequipmenttypes/${equipment.id}`) + .post(equipment) + .then((response) => { + return response; + }); +} + +export function deleteDistrictEquipmentType(equipment) { + return new ApiRequest(`/districtequipmenttypes/${equipment.id}/delete`) + .post() + .then((response) => { + return response; + }); +} + +export function getRoles() { + return new ApiRequest("/roles").get().then((response) => { + var roles = normalize(response.data); + + store.dispatch({ type: Action.UPDATE_ROLES_LOOKUP, roles: roles }); + }); +} + +export function getPermissions() { + return new ApiRequest("/permissions").get().then((response) => { + var permissions = normalize(response.data); + + store.dispatch({ + type: Action.UPDATE_PERMISSIONS_LOOKUP, + permissions: permissions, + }); + }); +} + +// XXX: Looks like this is unused +// export function getProvincialRateTypes() { +// return new ApiRequest('/provincialratetypes').get().then(response => { +// var rateTypeOther = { +// id: 10000, +// rateType: 'OTHER', +// description: Constant.NON_STANDARD_CONDITION, +// rate: null, +// isPercentRate: false, +// isRateEditable: true, +// isIncludedInTotal: false, +// isInTotalEditable: true, +// }; +// var provincialRateTypes = [ ...response.data, rateTypeOther ]; + +// store.dispatch({ type: Action.UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP, provincialRateTypes: provincialRateTypes }); +// }); +// } + +export function getOvertimeRateTypes() { + return new ApiRequest("/provincialratetypes/overtime") + .get() + .then((response) => { + store.dispatch({ + type: Action.UPDATE_OVERTIME_RATE_TYPES_LOOKUP, + overtimeRateTypes: response.data, + }); + }); +} + +export function updateOvertimeRateType(rate) { + return new ApiRequest(`/provincialratetypes/${rate.id}`) + .put(rate) + .then((response) => { + return response; + }); +} + +export function getRentalConditions() { + store.dispatch({ type: Action.RENTAL_CONDITIONS_LOOKUP_REQUEST }); + return new ApiRequest("/conditiontypes").get().then((response) => { + var rentalConditions = response.data; + + store.dispatch({ + type: Action.UPDATE_RENTAL_CONDITIONS_LOOKUP, + rentalConditions: rentalConditions, + }); + }); +} + +//////////////////// +// Version +//////////////////// + +export function getVersion() { + return new ApiRequest("/version").get().then((response) => { + store.dispatch({ type: Action.UPDATE_VERSION, version: response }); + }); +} + +//////////////////// +// Notes +//////////////////// + +export function deleteNote(id) { + store.dispatch({ type: Action.DELETE_NOTE, noteId: id }); + return new ApiRequest(`/notes/${id}/delete`).post().then((response) => { + return response.data; + }); +} + +export function updateNote(note) { + return new ApiRequest(`/notes/${note.id}`).put(note).then((response) => { + return response.data; + }); +} + +//////////////////// +// Set User +//////////////////// + +export function setDevUser(user) { + return new ApiRequest(`/authentication/dev/token/${user}`) + .get() + .then((response) => { + return response; + }); +} + +//////////////////// +// Time Records +//////////////////// + +export function deleteTimeRecord(timeRecordId) { + return new ApiRequest(`/timerecords/${timeRecordId}/delete`) + .post() + .then((response) => { + store.dispatch({ + type: Action.DELETE_TIME_RECORD, + timeRecord: response.data, + }); + }); +} diff --git a/client2/src/js/components/Authorize.jsx b/client2/src/js/components/Authorize.jsx new file mode 100644 index 000000000..3aae79811 --- /dev/null +++ b/client2/src/js/components/Authorize.jsx @@ -0,0 +1,29 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import * as Constant from '../constants'; + +class Authorize extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + children: PropTypes.node, + }; + + render() { + var authorized = this.props.currentUser.hasPermission(Constant.PERMISSION_WRITE_ACCESS); + + if (!authorized) { + return <>; + } else { + return this.props.children; + } + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + }; +} + +export default connect(mapStateToProps)(Authorize); diff --git a/client2/src/js/components/BadgeLabel.jsx b/client2/src/js/components/BadgeLabel.jsx new file mode 100644 index 000000000..d2beb93c9 --- /dev/null +++ b/client2/src/js/components/BadgeLabel.jsx @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Label } from 'react-bootstrap'; + + +class BadgeLabel extends React.Component { + static propTypes = { + bsClass: PropTypes.string, + bsStyle: PropTypes.string, + className: PropTypes.string, + children: PropTypes.node, + }; + + render() { + return ; + } +} + + +export default BadgeLabel; diff --git a/client2/src/js/components/CheckboxControl.jsx b/client2/src/js/components/CheckboxControl.jsx new file mode 100644 index 000000000..a5ac68bea --- /dev/null +++ b/client2/src/js/components/CheckboxControl.jsx @@ -0,0 +1,37 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Checkbox } from 'react-bootstrap'; +import _ from 'lodash'; + + +class CheckboxControl extends React.Component { + static propTypes = { + type: PropTypes.string, + updateState: PropTypes.func, + onChange: PropTypes.func, + children: PropTypes.node, + }; + + changed = (e) => { + // On change listener + if (this.props.onChange) { + this.props.onChange(e); + } + + // Update state + if (this.props.updateState && e.target.id) { + // Use e.target.id insted of this.props.id because it comes from the controlId. + this.props.updateState({ [e.target.id]: e.target.checked }); + } + }; + + render() { + var props = _.omit(this.props, 'updateState'); + + return + { this.props.children } + ; + } +} + +export default CheckboxControl; diff --git a/client2/src/js/components/ColDisplay.jsx b/client2/src/js/components/ColDisplay.jsx new file mode 100644 index 000000000..6b957362e --- /dev/null +++ b/client2/src/js/components/ColDisplay.jsx @@ -0,0 +1,30 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Row, Col } from 'react-bootstrap'; +import _ from 'lodash'; + + +class ColDisplay extends React.Component { + static propTypes = { + label: PropTypes.node, + children: PropTypes.node, + labelProps: PropTypes.object, + fieldProps: PropTypes.object, + }; + + render() { + var props = _.omit(this.props, 'label', 'labelProps', 'fieldProps'); + + return + + { this.props.label } + + + { this.props.children } + + ; + } +} + + +export default ColDisplay; diff --git a/client2/src/js/components/Confirm.jsx b/client2/src/js/components/Confirm.jsx new file mode 100644 index 000000000..56bf69019 --- /dev/null +++ b/client2/src/js/components/Confirm.jsx @@ -0,0 +1,42 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Popover, ButtonGroup, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + + +class Confirm extends React.Component { + static propTypes = { + onConfirm: PropTypes.func.isRequired, + onCancel: PropTypes.func, + hide: PropTypes.func, + children: PropTypes.node, + title: PropTypes.string, + }; + + confirmed = () => { + this.props.onConfirm(); + this.props.hide(); + }; + + canceled = () => { + if (this.props.onCancel) { this.props.onCancel(); } + this.props.hide(); + }; + + render() { + var props = _.omit(this.props, 'onConfirm', 'onCancel', 'hide', 'children'); + + return + { this.props.children } +
+ + + + +
+
; + } +} + + +export default Confirm; diff --git a/client2/src/js/components/Countdown.jsx b/client2/src/js/components/Countdown.jsx new file mode 100644 index 000000000..5cdc7b65c --- /dev/null +++ b/client2/src/js/components/Countdown.jsx @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + + +class Countdown extends React.Component { + static propTypes = { + time: PropTypes.number, + onEnd: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + timeLeft: props.time, + minutes: parseInt(props.time / 60, 10), + seconds: parseInt(props.time % 60, 10) < 10 ? '0' + parseInt(props.time % 60, 10) : parseInt(props.time % 60, 10), + fired: false, + }; + } + + componentDidMount() { + this.startTimer(); + } + + componentWillUnmount() { + clearInterval(this.state.interval); + } + + startTimer = () => { + var timeLeft = this.state.timeLeft; + var interval = setInterval(function () { + var minutes = parseInt(timeLeft / 60, 10); + var seconds = parseInt(timeLeft % 60, 10); + + seconds = seconds < 10 ? '0' + seconds : seconds; + + this.setState({ minutes, seconds }); + + if (--timeLeft < 0 && !this.state.fired) { + this.props.onEnd(); + this.setState({ fired: true }); + } + }.bind(this), 1000); + this.setState({ interval }); + }; + + render() { + return ( + + { this.state.minutes > 0 && `${this.state.minutes}m`} {this.state.seconds}s + + ); + } +} + + +export default Countdown; diff --git a/client2/src/js/components/DateControl.jsx b/client2/src/js/components/DateControl.jsx new file mode 100644 index 000000000..2574196f9 --- /dev/null +++ b/client2/src/js/components/DateControl.jsx @@ -0,0 +1,106 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { ControlLabel, InputGroup, Button, Glyphicon } from "react-bootstrap"; +import _ from "lodash"; +import Moment from "moment"; +import DateTime from "react-datetime"; + +class DateControl extends React.Component { + static propTypes = { + id: PropTypes.string.isRequired, + date: PropTypes.string, + format: PropTypes.string, + className: PropTypes.string, + label: PropTypes.string, + onChange: PropTypes.func, + updateState: PropTypes.func, + placeholder: PropTypes.string, + title: PropTypes.string, + disabled: PropTypes.bool, + isValidDate: PropTypes.func, + }; + + clicked = () => { + if (!this.props.disabled) { + this.input.focus(); + } + }; + + dateChanged = (date) => { + // ignore invalid dates + if (_.isString(date) || !date || !date.isValid()) { + return; + } + + var dateString = date.format(this.props.format || "YYYY-MM-DD"); + this.notifyValueChanged(dateString); + }; + + dateBlurred = (date) => { + // when focus leaves input, if date is invalid, reset value to empty string + if (_.isString(date) || !date || !date.isValid()) { + this.notifyValueChanged(""); + } + }; + + notifyValueChanged = (dateString) => { + // On change listener + if (this.props.onChange) { + this.props.onChange(dateString, this.props.id); + } + + // Update state + if (this.props.updateState) { + this.props.updateState({ + [this.props.id]: dateString, + }); + } + }; + + render() { + var date = Moment.utc(this.props.date); + var format = this.props.format || "YYYY-MM-DD"; + + var placeholder = this.props.placeholder || "yyyy-mm-dd"; + var disabled = this.props.disabled; + + return ( +
+ {(() => { + // Inline label + if (this.props.label) { + return {this.props.label}; + } + })()} + + { + this.input = input; + }, + }} + isValidDate={this.props.isValidDate} + /> + + + + +
+ ); + } +} + +export default DateControl; diff --git a/client2/src/js/components/DeleteButton.jsx b/client2/src/js/components/DeleteButton.jsx new file mode 100644 index 000000000..f8251e987 --- /dev/null +++ b/client2/src/js/components/DeleteButton.jsx @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import Confirm from '../components/Confirm.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; + + +class DeleteButton extends React.Component { + static propTypes = { + onConfirm: PropTypes.func.isRequired, + name: PropTypes.string, + hide: PropTypes.bool, + }; + + render() { + var props = _.omit(this.props, 'onConfirm', 'hide', 'name'); + + return }> + + ; + } +} + + +export default DeleteButton; diff --git a/client2/src/js/components/DropdownControl.jsx b/client2/src/js/components/DropdownControl.jsx new file mode 100644 index 000000000..97f41f36c --- /dev/null +++ b/client2/src/js/components/DropdownControl.jsx @@ -0,0 +1,200 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { Dropdown, MenuItem, Popover, OverlayTrigger } from "react-bootstrap"; +import _ from "lodash"; + +class DropdownControl extends React.Component { + static propTypes = { + // This is used to update state + id: PropTypes.string.isRequired, + + // This can be an array of strings or objects. If the latter, will use id/name by default. + items: PropTypes.array.isRequired, + + // If present, then items is an array of objects with ids + selectedId: PropTypes.any, + + // If present. then items is an array of strings + title: PropTypes.string, + + // Assumes item field is 'name' unless specified here. + fieldName: PropTypes.string, + + // Displayed when there's no selection + placeholder: PropTypes.string, + + // If blankLine is supplied, include an "empty" line at the top; + // If it has a string value, use that in place of blank. + blankLine: PropTypes.any, + + className: PropTypes.string, + disabled: PropTypes.bool, + onSelect: PropTypes.func, + updateState: PropTypes.func, + staticTitle: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + simple: _.has(props, "title"), + + selectedId: props.selectedId || "", + title: this.buildTitle(props.title), + fieldName: props.fieldName || "name", + open: false, + }; + } + + componentDidMount() { + if (!this.state.simple) { + // Have to wait until state is ready before initializing title. + this.setState({ + title: this.buildTitle(this.state.selectedId, this.props.items), + }); + } + } + + componentWillReceiveProps(nextProps) { + if (!_.isEqual(nextProps.items, this.props.items)) { + var items = nextProps.items || []; + this.setState({ + items: items, + title: this.buildTitle( + this.state.simple ? this.state.title : this.state.selectedId, + items + ), + }); + } else if (nextProps.selectedId !== this.props.selectedId) { + this.setState({ + selectedId: nextProps.selectedId, + title: this.buildTitle(nextProps.selectedId, this.props.items), + }); + } else if (!_.isEqual(nextProps.title, this.props.title)) { + this.setState({ title: this.buildTitle(nextProps.title) }); + } + } + + buildTitle = (keyEvent, items) => { + if (keyEvent) { + if (!items || this.state.simple) { + return keyEvent; + } else { + var selected = _.find(items, { id: keyEvent }); + if (selected) { + return selected[this.state.fieldName].toString(); + } + } + } + return this.props.placeholder || "Select item"; + }; + + itemSelected = (keyEvent) => { + this.toggle(false); + + if (!this.props.staticTitle) { + this.setState({ + selectedId: keyEvent || "", + title: this.buildTitle(keyEvent, this.props.items), + }); + } + + var selected = this.state.simple + ? keyEvent + : _.find(this.props.items, { id: keyEvent }); + + // Send selected item to change listener + if (this.props.onSelect) { + this.props.onSelect(selected, this.props.id); + } + + // Update state with selected key + if (this.props.updateState) { + this.props.updateState({ + [this.props.id]: keyEvent, + }); + } + }; + + toggle = (open) => { + this.setState({ open: open }); + }; + + render() { + var props = _.omit( + this.props, + "updateState", + "onSelect", + "items", + "selectedId", + "blankLine", + "fieldName", + "placeholder", + "staticTitle" + ); + + return ( + + + + {this.props.items.length > 0 && ( +
    + {this.props.blankLine && ( + + {typeof this.props.blankLine === "string" + ? this.props.blankLine + : " "} + + )} + {_.map(this.props.items, (item) => { + var menuItem = ( + + {this.state.simple ? item : item[this.state.fieldName]} + + ); + // Check for hover items + if (!this.state.simple && item.hoverText) { + return ( + + {item.hoverText} + + } + > + {menuItem} + + ); + } + return menuItem; + })} +
+ )} +
+
+ ); + } +} + +export default DropdownControl; diff --git a/client2/src/js/components/EditButton.jsx b/client2/src/js/components/EditButton.jsx new file mode 100644 index 000000000..f43af8e7f --- /dev/null +++ b/client2/src/js/components/EditButton.jsx @@ -0,0 +1,29 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button, Glyphicon } from 'react-bootstrap'; +import { LinkContainer } from 'react-router-bootstrap'; +import _ from 'lodash'; + + +class EditButton extends React.Component { + static propTypes = { + pathname: PropTypes.string, + onClick: PropTypes.func, + view: PropTypes.bool, + name: PropTypes.string, + hide: PropTypes.bool, + }; + + render() { + var props = _.omit(this.props, 'view', 'name', 'hide', 'pathname'); + + var button = ; + + return this.props.pathname ? { button } : button; + } +} + + +export default EditButton; diff --git a/client2/src/js/components/Favourites.jsx b/client2/src/js/components/Favourites.jsx new file mode 100644 index 000000000..cd45c0c61 --- /dev/null +++ b/client2/src/js/components/Favourites.jsx @@ -0,0 +1,225 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Alert, Dropdown, ButtonToolbar, Button } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import { Col, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../api'; + +import CheckboxControl from '../components/CheckboxControl.jsx'; +import DeleteButton from '../components/DeleteButton.jsx'; +import EditButton from '../components/EditButton.jsx'; +import FormDialog from '../components/FormDialog.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import RootCloseMenu from './RootCloseMenu.jsx'; + +import { isBlank } from '../utils/string'; + + +class EditFavouritesDialog extends React.Component { + static propTypes = { + favourite: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + name: props.favourite.name || '', + isDefault: props.favourite.isDefault || false, + nameError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.name !== this.props.favourite.name) { return true; } + if (this.state.isDefault !== this.props.favourite.isDefault) { return true; } + + return false; + }; + + isValid = () => { + if (isBlank(this.state.name)) { + this.setState({ nameError: 'Name is required' }); + return false; + } + return true; + }; + + onSubmit = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({isSaving: true}); + + const favourite = { + ...this.props.favourite, + name: this.state.name, + isDefault: this.state.isDefault, + }; + + const promise = favourite.id ? Api.updateFavourite(favourite) : Api.addFavourite(favourite); + promise.finally(() => { + this.setState({ isSaving: false }); + }); + + this.props.onSave(favourite); + } + + this.props.onClose(); + } + }; + + render() { + const { isSaving, name, nameError, isDefault } = this.state; + const { show, onClose } = this.props; + + return ( + + + Name * + + {nameError} + + + Default + + + ); + } +} + +class Favourites extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + title: PropTypes.string, + type: PropTypes.string.isRequired, + favourites: PropTypes.object.isRequired, + data: PropTypes.object.isRequired, + onSelect: PropTypes.func.isRequired, + pullRight: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + favouriteToEdit: {}, + showEditDialog: false, + open: false, + }; + } + + addFavourite = () => { + this.editFavourite({ + type: this.props.type, + name: '', + isDefault: false, + value: JSON.stringify(this.props.data), + }); + }; + + editFavourite = (favourite) => { + this.setState({ favouriteToEdit: favourite }); + this.openDialog(); + }; + + favoriteSaved = (favourite) => { + // Make sure there's only one default + if (favourite.isDefault) { + var oldDefault = _.find(this.props.favourites, f => f.isDefault); + if (oldDefault && (favourite.id !== oldDefault.id)) { + Api.updateFavourite({ + ...oldDefault, + isDefault: false, + }); + } + } + + this.closeDialog(); + }; + + deleteFavourite = (favourite) => { + Api.deleteFavourite(favourite); + }; + + selectFavourite = (favourite) => { + this.toggle(false); + this.props.onSelect(favourite); + }; + + openDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeDialog = () => { + this.setState({ showEditDialog: false }); + }; + + toggle = (open) => { + this.setState({ open: open }); + }; + + render() { + var title = this.props.title || 'Favourites'; + var className = `favourites ${ this.props.className || '' } ${ this.props.pullRight ? 'pull-right' : '' }`; + + return + { title } + +
+ +
+ {(() => { + if (Object.keys(this.props.favourites).length === 0) { return No favourites; } + + return
    + { + _.map(this.props.favourites, (favourite) => { + return
  • + + { favourite.isDefault ? : '' } + + + { favourite.name } + + + + + + + +
  • ; + }) + } +
; + })()} +
+ { this.state.showEditDialog ? + : null + } +
; + } +} + + +export default Favourites; diff --git a/client2/src/js/components/FileAttachDialog.jsx b/client2/src/js/components/FileAttachDialog.jsx new file mode 100644 index 000000000..5030de092 --- /dev/null +++ b/client2/src/js/components/FileAttachDialog.jsx @@ -0,0 +1,84 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button, Glyphicon } from 'react-bootstrap'; + +import ModalDialog from './ModalDialog.jsx'; +import FilePicker from './FilePicker.jsx'; +import FileUpload from './FileUpload.jsx'; + + +class FileAttachDialog extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + parentName: PropTypes.string, + uploadPath: PropTypes.string, + show: PropTypes.bool.isRequired, + onClose: PropTypes.func.isRequired, + onUpload: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + files: [], + }; + } + + filesPicked = (files) => { + var existingFiles = this.state.files.slice(); + existingFiles.push.apply(existingFiles, files); + this.setState({ files: existingFiles }); + }; + + removeFile = (file) => { + var pos = this.state.files.indexOf(file); + var files = this.state.files.slice(); + files.splice(pos, 1); + this.setState({ files: files }); + }; + + filesUploaded = (result) => { + if (!(result instanceof Error)) { + this.setState({ files: [] }); + if (this.props.onUpload) { + this.props.onUpload(); + } + } + }; + + render() { + var fileList; + if (this.state.files.length > 0) { + fileList =
    { + this.state.files.map((file, i) => { + return
  1. + { file.name } + +
  2. ; + }) + } +
; + } + + var footer = + + + ; + + var titleAttr = `Attach files${ this.props.parentName ? ` to ${ this.props.parentName }` : '' }`; + + return { titleAttr } } onClose={ this.props.onClose } footer={ footer } + > + { fileList } +

+
+ Select one or more files{ this.props.parentName ? ` to attach to ${ this.props.parentName }` : null } +

+
; + } +} + +export default FileAttachDialog; diff --git a/client2/src/js/components/FilePicker.jsx b/client2/src/js/components/FilePicker.jsx new file mode 100644 index 000000000..e2bfb4dd6 --- /dev/null +++ b/client2/src/js/components/FilePicker.jsx @@ -0,0 +1,37 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Glyphicon } from 'react-bootstrap'; + + +class FilePicker extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + label: PropTypes.string, + mimeTypes: PropTypes.array, + onFilesSelected: PropTypes.func, + }; + + filesPicked = (e) => { + this.props.onFilesSelected(e.target.files); + }; + + render() { + var classNames = [ 'file-picker' ]; + + if(this.props.className) { + classNames.push(this.props.className); + } + + return + + ; + } +} + +export default FilePicker; diff --git a/client2/src/js/components/FileUpload.jsx b/client2/src/js/components/FileUpload.jsx new file mode 100644 index 000000000..f4f811c24 --- /dev/null +++ b/client2/src/js/components/FileUpload.jsx @@ -0,0 +1,105 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button, Glyphicon, OverlayTrigger, Tooltip, ProgressBar } from 'react-bootstrap'; + +import { request, buildApiPath } from '../utils/http'; +import { plural } from '../utils/string'; + + +const FILE_UPLOAD_PATH = '/test-file-upload'; + + +class FileUpload extends React.Component { + static displayName = 'FileUpload'; + + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + label: PropTypes.string, + files: PropTypes.array, + path: PropTypes.string, + onUploadProgress: PropTypes.func, + onUploadFinished: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + uploadInProgress: false, + percentUploaded: null, + fileUploadError: null, + }; + } + + uploadFiles = () => { + this.setState({ uploadInProgress: true, percentUploaded: 0 }); + + var options = { + method: 'POST', + files: this.props.files, + onUploadProgress: (percentComplete) => { + var percent = Math.round(percentComplete); + this.setState({ percentUploaded: percent }); + if (this.props.onUploadProgress) { + this.props.onUploadProgress(percent); + } + }, + }; + + this.uploadPromise = request(buildApiPath(this.props.path || FILE_UPLOAD_PATH), options).then(() => { + this.setState({ uploadInProgress: false, percentUploaded: null }); + if (this.props.onUploadFinished) { this.props.onUploadFinished(true); } + }, (err) => { + this.setState({ uploadInProgress: false, fileUploadError: err }); + if (this.props.onUploadFinished) { this.props.onUploadFinished(err); } + }); + }; + + reset = () => { + this.setState({ uploadInProgress: false, percentUploaded: null, fileUploadError: null }); + }; + + render() { + var classNames = [ 'file-upload', 'clearfix' ]; + + if(this.props.className) { + classNames.push(this.props.className); + } + + if(this.state.fileUploadError) { + classNames.push('file-upload-error'); + } + + var files = this.props.files || []; + var fileUploadButton, uploadProgressBar; + var error; + if (!this.state.fileUploadError) { + var uploadText = `Upload ${ files.length } ${ plural(files.length, 'File', 'Files') }`; + if (!this.state.uploadInProgress) { + var uploadTooltip = { uploadText }; + var notReady = files.length === 0; + + fileUploadButton = + + ; + } else { + uploadProgressBar = ; + } + } else { + error = { String(this.state.fileUploadError) } }> +

Upload Error

+
; + } + + return
+ { fileUploadButton } + { uploadProgressBar } + { error } +
; + } +} + +export default FileUpload; diff --git a/client2/src/js/components/FilterDropdown.jsx b/client2/src/js/components/FilterDropdown.jsx new file mode 100644 index 000000000..2f580057b --- /dev/null +++ b/client2/src/js/components/FilterDropdown.jsx @@ -0,0 +1,187 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; +import { Well, Dropdown, FormControl, MenuItem, OverlayTrigger, Tooltip } from 'react-bootstrap'; +import _ from 'lodash'; + +import RootCloseMenu from './RootCloseMenu.jsx'; + + +class FilterDropdown extends React.Component { + static propTypes = { + id: PropTypes.string.isRequired, + items: PropTypes.array.isRequired, + selectedId: PropTypes.number, + className: PropTypes.string, + // Assumes the 'name' field unless specified here. + fieldName: PropTypes.string, + placeholder: PropTypes.string, + // If blankLine is supplied, include an "empty" line at the top; + // If it has a string value, use that in place of blank. + blankLine: PropTypes.any, + disabled: PropTypes.bool, + disabledTooltip: PropTypes.node, + onSelect: PropTypes.func, + updateState: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + selectedId: props.selectedId || 0, + title: '', + filterTerm: '', + fieldName: props.fieldName || 'name', + open: false, + }; + } + + componentDidMount() { + // Have to wait until state is ready before initializing title. + var title = this.buildTitle(this.props.items, this.state.selectedId); + this.setState({ title: title }); + } + + componentDidUpdate(prevProps, prevState) { + if (!_.isEqual(this.props.items, prevProps.items)) { + var items = this.props.items || []; + var id = this.props.selectedId === undefined ? prevState.selectedId : this.props.selectedId; + this.setState({ + items: items, + title: this.buildTitle(items, id), + }); + } else if (this.props.selectedId !== prevProps.selectedId) { + this.setState({ + selectedId: this.props.selectedId, + title: this.buildTitle(prevProps.items, this.props.selectedId), + }); + } + } + + buildTitle = (items, selectedId) => { + if (selectedId) { + var selected = _.find(items, { id: selectedId }); + if (selected) { + return selected[this.state.fieldName].toString(); + } + } + return this.props.placeholder || 'Select item'; + }; + + itemSelected = (selectedId) => { + this.toggle(false); + + this.setState({ + selectedId: selectedId || '', + title: this.buildTitle(this.props.items, selectedId), + }); + + this.sendSelected(selectedId); + }; + + sendSelected = (selectedId) => { + var selected = _.find(this.props.items, { id: selectedId }); + + // Send selected item to change listener + if (this.props.onSelect) { + this.props.onSelect(selected, this.props.id); + } + + // Update state with selected Id + if (this.props.updateState) { + this.props.updateState({ + [this.props.id]: selectedId, + }); + } + }; + + toggle = (open) => { + this.setState({ + open: open, + filterTerm: '', + }, () => { + if (open) { + this.input.focus(); + this.input.value = ''; + } + }); + }; + + filter = (e) => { + this.setState({ + filterTerm: e.target.value.toLowerCase().trim(), + }); + }; + + keyDown = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + } + }; + + filterItems = () => { + const { items } = this.props; + + if (this.state.filterTerm.length > 0) { + return _.filter(items, item => { + return item[this.state.fieldName].toLowerCase().indexOf(this.state.filterTerm) !== -1; + }); + } + + return items; + }; + + render() { + const { id, className, disabled, blankLine, disabledTooltip } = this.props; + + const items = this.filterItems(); + + const dropdown = ( + + + + + { this.input = ref; }} onKeyDown={this.keyDown}/> + + { items.length > 0 && ( +
    + { blankLine && this.state.filterTerm.length === 0 && + + { typeof blankLine === 'string' ? blankLine : ' ' } + + } + { + _.map(items, item => { + return + { item[this.state.fieldName] } + ; + }) + } +
+ )} +
+
+ ); + + if (disabled && disabledTooltip) { + const tooltip = { disabledTooltip }; + + return ( + + {dropdown} + + ); + } + + return dropdown; + } +} + +export default FilterDropdown; diff --git a/client2/src/js/components/Form.jsx b/client2/src/js/components/Form.jsx new file mode 100644 index 000000000..669e1c46c --- /dev/null +++ b/client2/src/js/components/Form.jsx @@ -0,0 +1,27 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Form as BootstrapForm } from 'react-bootstrap'; + + +const Form = (props) => { + const { children, onSubmit, ...rest } = props; + + function formSubmited(e) { + e.preventDefault(); + + if (onSubmit) { onSubmit(e); } + } + + return ( + + { children } + + ); +}; + +Form.propTypes = { + children: PropTypes.node, + onSubmit: PropTypes.func, +}; + +export default Form; diff --git a/client2/src/js/components/FormDialog.jsx b/client2/src/js/components/FormDialog.jsx new file mode 100644 index 000000000..9a7bf9ff6 --- /dev/null +++ b/client2/src/js/components/FormDialog.jsx @@ -0,0 +1,84 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; +import { Modal, Button } from 'react-bootstrap'; + +import Form from './Form.jsx'; +import Spinner from './Spinner.jsx'; +import Authorize from './Authorize.jsx'; + + +class FormDialog extends React.Component { + static propTypes = { + show: PropTypes.bool.isRequired, + title: PropTypes.node, + id: PropTypes.string, + className: PropTypes.string, + bsSize: PropTypes.string, + isReadOnly: PropTypes.bool, + isSaving: PropTypes.bool, + onClose: PropTypes.func.isRequired, + onSubmit: PropTypes.func, + saveButtonLabel: PropTypes.string, + closeButtonLabel: PropTypes.string, + children: PropTypes.node, + }; + + closeDialog = () => { + this.props.onClose(); + }; + + formSubmitted = () => { + const { isSaving, onSubmit } = this.props; + + if (!isSaving) { + onSubmit(); + } + }; + + renderBody = () => { + const { children, saveButtonLabel, closeButtonLabel, isReadOnly, isSaving } = this.props; + + return ( +
+ + {children} + + + + {!isReadOnly && ( + + + + )} + +
+ ); + }; + + render() { + const { id, className, title, show, bsSize } = this.props; + + return ( + + + {title && ( + {title} + )} + + {show && this.renderBody()} + + ); + } +} + +export default FormDialog; diff --git a/client2/src/js/components/FormInputControl.jsx b/client2/src/js/components/FormInputControl.jsx new file mode 100644 index 000000000..6da82c681 --- /dev/null +++ b/client2/src/js/components/FormInputControl.jsx @@ -0,0 +1,76 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormControl } from 'react-bootstrap'; +import _ from 'lodash'; + + +class FormInputControl extends React.Component { + static propTypes = { + type: PropTypes.string, + updateState: PropTypes.func, + inputRef: PropTypes.func, + autoFocus: PropTypes.bool, + autoComplete: PropTypes.string, + onChange: PropTypes.func, + children: PropTypes.node, + }; + + componentDidMount() { + if (this.props.autoFocus) { + this.input.focus(); + } + } + + changed = (e) => { + const { type, updateState, onChange } = this.props; + + // On change listener + if (onChange) { onChange(e); } + + if (updateState && e.target.id) { + // Use e.target.id insted of this.props.id because it comes from the controlId. + var value = e.target.value; + if (type === 'number' ) { + value = parseInt(value, 10); + if (_.isNaN(value)) { + value = ''; + } + } + if (type === 'float' ) { + value = parseFloat(value); + if (_.isNaN(value)) { + value = ''; + } + } + + // Update state + updateState({ [e.target.id]: value }); + } + }; + + refChanged = (ref) => { + this.input = ref; + if (this.props.inputRef) { this.props.inputRef(ref); } + } + + render() { + const { type, autoComplete, children } = this.props; + // XXX: eslint doesn't like `const { type, autoComplete, children, ...rest } = this.props;` + // using lodash omit for now + const rest = _.omit(this.props, 'type', 'autoComplete', 'children', 'updateState'); + + return ( + + {children} + + ); + } +} + +export default FormInputControl; diff --git a/client2/src/js/components/History.jsx b/client2/src/js/components/History.jsx new file mode 100644 index 000000000..17e525a42 --- /dev/null +++ b/client2/src/js/components/History.jsx @@ -0,0 +1,155 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Action from '../actionTypes'; +import * as Constant from '../constants'; +import * as History from '../history'; +import store from '../store'; + +import SortTable from './SortTable.jsx'; +import Spinner from './Spinner.jsx'; + +import { makeGetHistorySelector } from '../selectors/history-selectors.js'; + +import { formatDateTimeUTCToLocal } from '../utils/date'; +import { sortDir } from '../utils/array'; + + +// API limit: how many to fetch first time +const API_LIMIT = 10; + +class HistoryComponent extends React.Component { + static propTypes = { + historyEntity: PropTypes.object.isRequired, + refresh: PropTypes.bool.isRequired, + + // Used when displayed in a dialog + onClose: PropTypes.func, + + history: PropTypes.object, + users: PropTypes.object, + ui: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: !this.props.history, + fetchingMore: false, + + canShowMore: false, + + ui : { + sortField: props.ui.sortField || 'timestampSort', + sortDesc: props.ui.sortDesc !== false, + }, + }; + } + + componentWillReceiveProps(nextProps) { + if (nextProps.refresh && !this.props.refresh) { + this.fetch(true); + } + } + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_HISTORY_UI, history: this.state.ui }); + if (callback) { callback(); } + }); + }; + + fetch = (first) => { + // Easy mode: show 10 the first time and let the user load all of them with the + // "Show More" button. Can adapt for paginated / offset&limit calls if necessary. + + if (first) { + if (this.props.history) { + // if old data exists, update it in the background without displaying a loading spinner + this.setState({ loading: false }); + } else { + // if no data exists, display spinner while it loads + this.setState({ loading: true }); + } + } + + return History.get(this.props.historyEntity, 0, first ? API_LIMIT : null).finally(() => { + this.setState({ + loading: false, + canShowMore: first && Object.keys(this.props.history).length >= API_LIMIT, + }); + }); + }; + + showMore = () => { + this.setState({ fetchingMore: true }); + this.fetch().finally(() => { + this.setState({ fetchingMore: false }); + }); + }; + + render() { + const { loading, fetchingMore } = this.state; + + return ( +
+ {(() => { + if (loading) { return
; } + + if (Object.keys(this.props.history).length === 0) { return No history; } + + var history = _.orderBy(this.props.history, [this.state.ui.sortField], sortDir(this.state.ui.sortDesc)); + + var headers = [ + { field: 'timestampSort', title: 'Timestamp' }, + { field: 'userName', title: 'User' }, + { field: 'event', noSort: true, title: 'Event' }, + { field: 'showMore', title: 'Show More', style: { textAlign: 'right' }, + node: fetchingMore? : ( + + ), + }, + ]; + return + { + history.map((history) => { + const event = History.renderEvent(history.historyText, this.props.onClose); + const formattedTimestamp = formatDateTimeUTCToLocal(history.lastUpdateTimestamp, Constant.DATE_TIME_LOG); + + return + { formattedTimestamp } + { history.lastUpdateUserid } + { event } + ; + }).concat(fetchingMore ? [ + + + , + ] : []) + } + ; + })()} +
+ ); + } +} + +const makeMapStateToProps = () => { + const getHistorySelector = makeGetHistorySelector(); + const mapStateToProps = (state, props) => { + return { + history: getHistorySelector(state, props), + users: state.lookups.users, + ui: state.ui.history, + }; + }; + return mapStateToProps; +}; + +export default connect(makeMapStateToProps)(HistoryComponent); diff --git a/client2/src/js/components/LinkControl.jsx b/client2/src/js/components/LinkControl.jsx new file mode 100644 index 000000000..48f14d259 --- /dev/null +++ b/client2/src/js/components/LinkControl.jsx @@ -0,0 +1,68 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormControl, InputGroup, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + + +class LinkControl extends React.Component { + static propTypes = { + // url(value) returns a URL, default is value. + url: PropTypes.func, + value: PropTypes.string, + id: PropTypes.string, + label: PropTypes.string, + title: PropTypes.string, + className: PropTypes.string, + updateState: PropTypes.func, + onChange: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + url: this.getUrl(props.value), + }; + } + + getUrl = (value) => { + return this.props.url ? this.props.url(value) : value; + }; + + changed = (e) => { + // On change listener + if (this.props.onChange) { + this.props.onChange(e); + } + + // Update state + if (this.props.updateState && e.target.id) { + // Use e.target.id insted of this.props.id because it comes from the controlId. + this.props.updateState({ [e.target.id]: e.target.value }); + } + + // Update href + this.setState({ + url: this.getUrl(e.target.value), + }); + }; + + render() { + var props = _.omit(this.props, 'updateState', 'url', 'id'); + + return
+ {(() => { + // Inline label + if (this.props.label) { return { this.props.label }; } + })()} + + + + + + +
; + } +} + +export default LinkControl; diff --git a/client2/src/js/components/Mailto.jsx b/client2/src/js/components/Mailto.jsx new file mode 100644 index 000000000..0f5e541ab --- /dev/null +++ b/client2/src/js/components/Mailto.jsx @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +export const toSearchString = (searchParams = {}) => { + return Object.keys(searchParams).map(key => + `${key}=${encodeURIComponent(searchParams[key])}` + ).join('&'); +}; + +export const createMailtoLink = (email, headers) => { + let link = `mailto:${email}`; + if (headers) { + link += `?${toSearchString(headers)}`; + } + return link; +}; + +/** + * A react component to create and display a mailto link. + */ +class Mailto extends React.Component { + static propTypes = { + children: PropTypes.node.isRequired, + email: PropTypes.string.isRequired, + headers: PropTypes.object, + }; + + render() { + const { email, headers, children, ...others } = this.props; + return + { children } + ; + } +} + +export default Mailto; diff --git a/client2/src/js/components/ModalDialog.jsx b/client2/src/js/components/ModalDialog.jsx new file mode 100644 index 000000000..4dc424ed9 --- /dev/null +++ b/client2/src/js/components/ModalDialog.jsx @@ -0,0 +1,39 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Modal } from 'react-bootstrap'; +import _ from 'lodash'; + + +class ModalDialog extends React.Component { + static propTypes = { + title: PropTypes.node, + footer: PropTypes.node, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired, + children: PropTypes.node, + }; + + render() { + var props = _.omit(this.props, 'title', 'footer', 'onClose'); + + return + + { this.props.title && + + { this.props.title } + + } + + + { this.props.children } + + { this.props.footer && + + { this.props.footer } + + } + ; + } +} + +export default ModalDialog; diff --git a/client2/src/js/components/MultiDropdown.jsx b/client2/src/js/components/MultiDropdown.jsx new file mode 100644 index 000000000..aa336c559 --- /dev/null +++ b/client2/src/js/components/MultiDropdown.jsx @@ -0,0 +1,182 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Well, Dropdown, FormControl, Checkbox } from 'react-bootstrap'; +import RootCloseMenu from './RootCloseMenu.jsx'; +import _ from 'lodash'; + + +const MAX_ITEMS_FOR_TITLE = 3; + + +class MultiDropdown extends React.Component { + static propTypes = { + items: PropTypes.array.isRequired, + placeholder: PropTypes.string, + id: PropTypes.string.isRequired, + className: PropTypes.string, + fieldName: PropTypes.string, + selectedIds: PropTypes.array, + onChange: PropTypes.func, + updateState: PropTypes.func, + showMaxItems: PropTypes.number, + disabled: PropTypes.bool, + }; + + constructor(props) { + super(props); + + var selectedIds = props.selectedIds || []; + var items = props.items || []; + var fieldName = props.fieldName || 'name'; + + this.state = { + selectedIds: selectedIds, + title: '', + filterTerm: '', + maxItemsForTitle: props.showMaxItems || MAX_ITEMS_FOR_TITLE, + allSelected: selectedIds.length === items.length && selectedIds.length > 0, + fieldName: fieldName, + open: false, + }; + } + + componentDidMount() { + // Have to wait until state is ready before initializing title. + var title = this.buildTitle(this.props.items, this.state.selectedIds); + this.setState({ title: title }); + } + + componentWillReceiveProps(nextProps) { + if (!_.isEqual(nextProps.items, this.props.items)) { + var items = nextProps.items || []; + this.setState({ + items: items, + title: this.buildTitle(items, this.state.selectedIds), + }); + } + if (!_.isEqual(nextProps.selectedIds, this.props.selectedIds)) { + this.setState({ + selectedIds: nextProps.selectedIds, + title: this.buildTitle(this.props.items, nextProps.selectedIds), + }); + } + } + + buildTitle = (items, selectedIds) => { + var num = selectedIds.length; + + if (items.length === 0 || num === 0) { + return this.props.placeholder || 'Select items'; + } else if (num === items.length) { + return 'All selected'; + } else if (num > this.state.maxItemsForTitle) { + return `(${num}) selected`; + } else { + return _.map(_.pickBy(items, item => selectedIds.includes(item.id)), this.state.fieldName).join(', '); + } + }; + + itemSelected = (e) => { + var id = parseInt(e.target.value, 10); + var selectedIds = this.state.selectedIds.slice(); + + if(e.target.checked) { + selectedIds.push(id); + } else { + _.pull(selectedIds, id); + } + + this.setState({ + selectedIds: selectedIds, + title: this.buildTitle(this.props.items, selectedIds), + allSelected: selectedIds.length === this.props.items.length && selectedIds.length > 0, + }); + + this.sendSelected(selectedIds); + }; + + selectAll = (e) => { + var selectedIds = e.target.checked ? _.map(this.props.items, 'id') : []; + + this.setState({ + selectedIds: selectedIds, + allSelected: e.target.checked, + title: this.buildTitle(this.props.items, selectedIds), + }); + + this.sendSelected(selectedIds); + }; + + sendSelected = (selectedIds) => { + var selected = this.props.items.filter(item => selectedIds.includes(item.id)); + + // Send selected items to change listener + if (this.props.onChange) { + this.props.onChange(selected, this.props.id); + } + + // Update state with selected Ids + if (this.props.updateState) { + this.props.updateState({ + [this.props.id]: selectedIds, + }); + } + }; + + toggle = (open) => { + this.setState({ open: open }, () => { + if (open) { + this.input.focus(); + } + }); + }; + + filter = (e) => { + this.setState({ + filterTerm: e.target.value.toLowerCase().trim(), + }); + }; + + keyDown = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + } + }; + + render() { + var items = this.props.items; + + if (this.state.filterTerm.length > 0) { + items = _.filter(items, item => { + return item[this.state.fieldName].toLowerCase().indexOf(this.state.filterTerm) !== -1; + }); + } + + return + + + + { this.input = ref; }} autoComplete="off" onKeyDown={this.keyDown}/> + Select All + + { items.length > 0 && +
    + { + _.map(items, item => { + return
  • + + { item[this.state.fieldName] } + +
  • ; + }) + } +
+ } +
+
; + } +} + +export default MultiDropdown; diff --git a/client2/src/js/components/OverlayTrigger.jsx b/client2/src/js/components/OverlayTrigger.jsx new file mode 100644 index 000000000..abb5615cb --- /dev/null +++ b/client2/src/js/components/OverlayTrigger.jsx @@ -0,0 +1,29 @@ +import React, { cloneElement } from 'react'; +import { Overlay, OverlayTrigger } from 'react-bootstrap'; + +// This is a SUPER hacky way to get around the fact that the standard (as of 0.29.5) React Bootstrap +// doesn't have any way of allowing the overlay to close itself. Adding hide prop +// to the `cloneElement` call that just calls the hide method on the default OverlayTrigger causes +// the overlay to be closed. + +class CloseableOverlayTrigger extends OverlayTrigger { + makeOverlay(overlay, props) { + overlay = cloneElement(this.props.overlay, { + // All this overriding just for this one property! + hide: this.handleHide, + }); + + return ( + + {overlay} + + ); + } +} + +export default CloseableOverlayTrigger; diff --git a/client2/src/js/components/PageOrientation.jsx b/client2/src/js/components/PageOrientation.jsx new file mode 100644 index 000000000..3e692a40a --- /dev/null +++ b/client2/src/js/components/PageOrientation.jsx @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + + +class PageOrientation extends React.Component { + static propTypes = { + type: PropTypes.string.isRequired, + }; + + render() { + var size = 'portrait'; + if (this.props.type === 'landscape') { + size = 'landscape'; + } + + return ; + } +} + +export default PageOrientation; diff --git a/client2/src/js/components/PrintButton.jsx b/client2/src/js/components/PrintButton.jsx new file mode 100644 index 000000000..2d4bb6716 --- /dev/null +++ b/client2/src/js/components/PrintButton.jsx @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; +import { Glyphicon } from 'react-bootstrap'; + +import TooltipButton from './TooltipButton.jsx'; + + +class PrintButton extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + title: PropTypes.string, + disabled: PropTypes.bool, + disabledTooltip: PropTypes.node, + children: PropTypes.node, + }; + + print = () => { + window.print(); + }; + + render() { + const { id, className, disabled, disabledTooltip, children } = this.props; + + return ( + + + {children} + + ); + } +} + +PrintButton.defaultProps = { + disabledTooltip: 'Please perform a search to print', +}; + + +export default PrintButton; diff --git a/client2/src/js/components/ReturnButton.jsx b/client2/src/js/components/ReturnButton.jsx new file mode 100644 index 000000000..974970183 --- /dev/null +++ b/client2/src/js/components/ReturnButton.jsx @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; +import { browserHistory } from 'react-router'; +import { Button, Glyphicon } from 'react-bootstrap'; + + +class ReturnButton extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + title: PropTypes.string, + }; + + render() { + const { id, className, title } = this.props; + + return ( + + ); + } +} + + +export default ReturnButton; diff --git a/client2/src/js/components/RootCloseMenu.jsx b/client2/src/js/components/RootCloseMenu.jsx new file mode 100644 index 000000000..242b61695 --- /dev/null +++ b/client2/src/js/components/RootCloseMenu.jsx @@ -0,0 +1,24 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { RootCloseWrapper } from 'react-overlays'; + + +class RootCloseMenu extends React.Component { + static propTypes = { + open: PropTypes.bool, + pullRight: PropTypes.bool, + onClose: PropTypes.func, + children: PropTypes.node, + }; + + render() { + return +
+ { this.props.children } +
+
; + } +} + + +export default RootCloseMenu; diff --git a/client2/src/js/components/SearchControl.jsx b/client2/src/js/components/SearchControl.jsx new file mode 100644 index 000000000..4b241ac88 --- /dev/null +++ b/client2/src/js/components/SearchControl.jsx @@ -0,0 +1,78 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { InputGroup } from 'react-bootstrap'; +import _ from 'lodash'; + +import DropdownControl from '../components/DropdownControl.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; + +import { notBlank } from '../utils/string'; + + +class SearchControl extends React.Component { + static propTypes = { + // This is an array of objects { id, name } + items: PropTypes.array.isRequired, + + search: PropTypes.object.isRequired, + updateState: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + key: props.search.key || '', + text: props.search.text || '', + params: props.search.params || null, + }; + } + + componentDidMount() { + this.updated({ + params: this.getParams(), + }); + } + + getParams = () => { + var params = null; + + if (notBlank(this.state.key) && notBlank(this.state.text)) { + params = {}; + params[this.state.key] = this.state.text; + } + + return params; + }; + + updated = (state) => { + if (state.text) { + state.text = state.text.trim(); + } + // update state + this.setState(state, () => { + // then update params + this.setState({ + params: this.getParams(), + }, () => { + // then update parent state + this.props.updateState(this.state); + }); + }); + }; + + render() { + var props = _.omit(this.props, 'updateState', 'search', 'items'); + + return
+ + + + +
; + } +} + +export default SearchControl; diff --git a/client2/src/js/components/SortTable.jsx b/client2/src/js/components/SortTable.jsx new file mode 100644 index 000000000..e00fbf9a1 --- /dev/null +++ b/client2/src/js/components/SortTable.jsx @@ -0,0 +1,85 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Table, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import Spinner from '../components/Spinner.jsx'; + + +class SortTable extends React.Component { + static propTypes = { + // Array of objects with key, title, style, children fields + headers: PropTypes.array.isRequired, + // This should be a from a state.ui object + sortField: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.array, + ]).isRequired, + // This should be a from a state.ui object + sortDesc: PropTypes.bool.isRequired, + onSort: PropTypes.func.isRequired, + id: PropTypes.string, + isRefreshing: PropTypes.bool, + children: PropTypes.node, + }; + + sort = (field) => { + this.props.onSort({ + sortField: field, + sortDesc: !this.props.sortDesc, + }); + }; + + preventSelection = (e) => { + e.preventDefault(); + }; + + renderTableHeader = () => { + const {headers, sortField, sortDesc} = this.props; + + return headers.map((header) => { + const key = Array.isArray(header.field) ? header.field.join('-') : header.field; + if (header.node) { + return {header.node}; + } + + var sortGlyph = ''; + if (_.isEqual(sortField, header.field)) { + sortGlyph =  ; + } + + return ( + this.sort(header.field) } + className={ header.class } + style={{ ...header.style, cursor: header.noSort ? 'default' : 'pointer' }}> + { header.title }{ sortGlyph } + + ); + }); + }; + + render() { + const {id, isRefreshing, children} = this.props; + + return ( +
+ {isRefreshing &&
} + + + + {this.renderTableHeader()} + + + + {children} + +
+
+ ); + } +} + +export default SortTable; diff --git a/client2/src/js/components/Spinner.jsx b/client2/src/js/components/Spinner.jsx new file mode 100644 index 000000000..5c9d97bcc --- /dev/null +++ b/client2/src/js/components/Spinner.jsx @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import _ from 'lodash'; + + +const Spinner = (params) => { + var styles = _.extend({}, _.pick(params, 'width', 'height')); + + var hide = ''; + + if(params.show !== undefined) { + hide = params.show ? '' : 'hide'; + } + + if(params.size !== undefined) { + styles.width = +params.size || 16; + styles.height = +params.size || 16; + } + + var spinner = ; + if(params.centre) { + return
{spinner}
; + } else { + return spinner; + } +}; + +Spinner.propTypes = { + width: PropTypes.number, + height: PropTypes.number, + show: PropTypes.bool, + centre: PropTypes.bool, +}; + +export default Spinner; diff --git a/client2/src/js/components/StatusDropdown.jsx b/client2/src/js/components/StatusDropdown.jsx new file mode 100644 index 000000000..d3ca91cc2 --- /dev/null +++ b/client2/src/js/components/StatusDropdown.jsx @@ -0,0 +1,77 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {DropdownButton, MenuItem } from 'react-bootstrap'; + +import * as Constant from '../constants'; + +import TooltipButton from './TooltipButton.jsx'; + + +class StatusDropdown extends React.Component { + static propTypes = { + id: PropTypes.string, + className: PropTypes.string, + status: PropTypes.string.isRequired, + statuses: PropTypes.array.isRequired, + disabled: PropTypes.bool, + disabledTooltip: PropTypes.node, + onSelect: PropTypes.func.isRequired, + }; + + computeBsStyle = () => { + switch(this.props.status) { + case Constant.EQUIPMENT_STATUS_CODE_APPROVED: + case Constant.OWNER_STATUS_CODE_APPROVED: + case Constant.PROJECT_STATUS_CODE_ACTIVE: + return 'success'; + case Constant.EQUIPMENT_STATUS_CODE_PENDING: + case Constant.OWNER_STATUS_CODE_PENDING: + case Constant.PROJECT_STATUS_CODE_COMPLETED: + return 'danger'; + default: + return 'default'; + } + }; + + render() { + const { + id, + className, + status, + statuses, + disabled, + disabledTooltip, + } = this.props; + + const bsStyle = this.computeBsStyle(); + const title = status || ''; + + if (disabled) { + return ( + + {title} + + ); + } else { + return ( + + {statuses.map((item) => { + return {item}; + })} + + ); + } + } +} + + +export default StatusDropdown; diff --git a/client2/src/js/components/TableControl.jsx b/client2/src/js/components/TableControl.jsx new file mode 100644 index 000000000..0cc02115d --- /dev/null +++ b/client2/src/js/components/TableControl.jsx @@ -0,0 +1,35 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Table } from 'react-bootstrap'; +import _ from 'lodash'; + + +class TableControl extends React.Component { + static propTypes = { + // Array of objects with key, title, style, children fields + headers: PropTypes.array.isRequired, + id: PropTypes.string, + children: PropTypes.node, + }; + + render() { + return
+ + + + { + _.map(this.props.headers, (header) => { + return ; + }) + } + + + + { this.props.children } + +
{ header.node ? header.node : header.title }
+
; + } +} + +export default TableControl; diff --git a/client2/src/js/components/TooltipButton.jsx b/client2/src/js/components/TooltipButton.jsx new file mode 100644 index 000000000..fc0a1a575 --- /dev/null +++ b/client2/src/js/components/TooltipButton.jsx @@ -0,0 +1,49 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap'; + + +// simplifies adding tooltips for enabled and disabled buttons +class TooltipButton extends React.Component { + static propTypes = { + disabled: PropTypes.bool, + children: PropTypes.node, + enabledTooltip: PropTypes.node, + disabledTooltip: PropTypes.node, + onClick: PropTypes.func, + className: PropTypes.string, + style: PropTypes.object, + bsSize: PropTypes.string, + bsStyle: PropTypes.string, + }; + + static defaultProps = { + style: {}, + }; + + render() { + var buttonStyle = this.props.disabled ? {...this.props.style, pointerEvents : 'none' } : this.props.style; + + var button = ( + + ); + + var tooltipContent = this.props.disabled ? this.props.disabledTooltip : this.props.enabledTooltip; + if (tooltipContent) { + return ( + { tooltipContent } }> +
+ { button } +
+
+ ); + } else { + return button; + } + } +} + + +export default TooltipButton; diff --git a/client2/src/js/components/Unimplemented.jsx b/client2/src/js/components/Unimplemented.jsx new file mode 100644 index 000000000..0bebf4f41 --- /dev/null +++ b/client2/src/js/components/Unimplemented.jsx @@ -0,0 +1,21 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { OverlayTrigger, Tooltip } from 'react-bootstrap'; + + +class Unimplemented extends React.Component { + static propTypes = { + children: PropTypes.node, + }; + + render() { + return This feature has not been released yet. + }> + { this.props.children } + ; + } +} + + +export default Unimplemented; diff --git a/client2/src/js/components/Watermark.jsx b/client2/src/js/components/Watermark.jsx new file mode 100644 index 000000000..1a432f4ad --- /dev/null +++ b/client2/src/js/components/Watermark.jsx @@ -0,0 +1,24 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +class Watermark extends React.Component { + static propTypes = { + enable: PropTypes.bool, + }; + + render() { + if (this.props.enable) { + return ( +
+ View Only +
+ Not for Hiring +
+ ); + } else { + return <>; + } + } +} + +export default Watermark; diff --git a/client2/src/js/components/ui/AddButtonContainer.jsx b/client2/src/js/components/ui/AddButtonContainer.jsx new file mode 100644 index 000000000..7d89a5bca --- /dev/null +++ b/client2/src/js/components/ui/AddButtonContainer.jsx @@ -0,0 +1,20 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + + +class AddButtonContainer extends React.Component { + static propTypes = { + children: PropTypes.node, + }; + + render() { + return ( +
+ { this.props.children } +
+ ); + } +} + + +export default AddButtonContainer; diff --git a/client2/src/js/components/ui/PageHeader.jsx b/client2/src/js/components/ui/PageHeader.jsx new file mode 100644 index 000000000..a53419114 --- /dev/null +++ b/client2/src/js/components/ui/PageHeader.jsx @@ -0,0 +1,29 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; + + +class PageHeader extends React.Component { + static propTypes = { + title: PropTypes.node, + subTitle: PropTypes.node, + id: PropTypes.string, + className: PropTypes.string, + children: PropTypes.node, + }; + + render() { + const { title, subTitle,id, className, children } = this.props; + + return ( +

+ {title} + {subTitle ? ': ' : ''}{subTitle && { subTitle }} + {children} +

+ ); + } +} + + +export default PageHeader; diff --git a/client2/src/js/components/ui/SearchBar.jsx b/client2/src/js/components/ui/SearchBar.jsx new file mode 100644 index 000000000..76ddb1f40 --- /dev/null +++ b/client2/src/js/components/ui/SearchBar.jsx @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Well } from 'react-bootstrap'; + + +class SearchBar extends React.Component { + static propTypes = { + children: PropTypes.node, + id: PropTypes.string, + }; + + render() { + return ( + + { this.props.children } + + ); + } +} + + +export default SearchBar; diff --git a/client2/src/js/components/ui/SubHeader.jsx b/client2/src/js/components/ui/SubHeader.jsx new file mode 100644 index 000000000..fa8c92784 --- /dev/null +++ b/client2/src/js/components/ui/SubHeader.jsx @@ -0,0 +1,66 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import classNames from 'classnames'; +import { Glyphicon } from 'react-bootstrap'; + +import TooltipButton from '../TooltipButton.jsx'; + + +class SubHeader extends React.Component { + static propTypes = { + title: PropTypes.string, + id: PropTypes.string, + className: PropTypes.string, + editButtonTitle: PropTypes.string, + editButtonDisabled: PropTypes.bool, + editButtonDisabledTooltip: PropTypes.node, + editIcon: PropTypes.string, + onEditClicked: PropTypes.func, + children: PropTypes.node, + }; + + render() { + const { + title, + id, + className, + editButtonTitle, + editButtonDisabled, + editButtonDisabledTooltip, + editIcon, + children, + onEditClicked, + } = this.props; + + var editButton = children; + if (onEditClicked && !children) { + editButton = ( + + + + ); + } + + return ( +

+ {title} + + {editButton} + +

+ ); + } +} + + +SubHeader.defaultProps = { + editIcon: 'pencil', +}; + + +export default SubHeader; diff --git a/client2/src/js/constants.js b/client2/src/js/constants.js new file mode 100644 index 000000000..a4f161aff --- /dev/null +++ b/client2/src/js/constants.js @@ -0,0 +1,147 @@ +// Paths +export const HOME_PATHNAME = "home"; +export const OWNERS_PATHNAME = "owners"; +export const EQUIPMENT_PATHNAME = "equipment"; +export const PROJECTS_PATHNAME = "projects"; +export const CONTACTS_PATHNAME = "contacts"; +export const RENTAL_REQUESTS_PATHNAME = "rental-requests"; +export const RENTAL_AGREEMENTS_PATHNAME = "rental-agreements"; +export const OVERTIME_RATES_PATHNAME = "overtime-rates"; +export const USERS_PATHNAME = "users"; +export const ROLES_PATHNAME = "roles"; +export const ROLLOVER_PATHNAME = "roll-over"; +export const DISTRICT_ADMIN_PATHNAME = "district-admin"; +export const SENIORITY_LIST_PATHNAME = "reports/seniority-list"; +export const STATUS_LETTERS_REPORT_PATHNAME = "reports/status-letters"; +export const HIRING_REPORT_PATHNAME = "reports/owners-equipment-reason"; +export const OWNERS_COVERAGE_PATHNAME = "reports/wcb-cgl-coverage"; +export const TIME_ENTRY_PATHNAME = "time-entry"; +export const VERSION_PATHNAME = "version"; +export const BUSINESS_PORTAL_PATHNAME = "/business"; +export const BUSINESS_DETAILS_PATHNAME = "/business/details"; +export const AIT_REPORT_PATHNAME = "reports/rental-agreement-summary"; +//temporary fix to fix import error RENTAL_CONDITIONS_PATHNAME and RENTAL_RATES_PATHNAME. +export const RENTAL_CONDITIONS_PATHNAME = "temporaryfix"; +export const RENTAL_RATES_PATHNAME = "temporaryfix"; + +// Permissions +export const PERMISSION_LOGIN = "Login"; +export const PERMISSION_BUSINESS_LOGIN = "BusinessLogin"; +export const PERMISSION_ADMIN = "Admin"; +export const PERMISSION_USER_MANAGEMENT = "UserManagement"; +export const PERMISSION_ROLES_AND_PERMISSIONS = "RolesAndPermissions"; +export const PERMISSION_IMPORT_DATA = "ImportData"; +export const PERMISSION_CODE_TABLE_MANAGEMENT = "CodeTableManagement"; +export const PERMISSION_DISTRICT_CODE_TABLE_MANAGEMENT = + "DistrictCodeTableManagement"; +export const PERMISSION_DISTRICT_ROLLOVER = "DistrictRollover"; +export const PERMISSION_VERSION = "Version"; +export const PERMISSION_WRITE_ACCESS = "WriteAccess"; + +// Roles +export const ADMINISTRATOR_ROLE = "4-HETS System Administrator"; + +// Equipments +export const EQUIPMENT_DAYS_SINCE_VERIFIED_WARNING = 270; +export const EQUIPMENT_DAYS_SINCE_VERIFIED_CRITICAL = 365; + +export const EQUIPMENT_STATUS_CODE_PENDING = "Unapproved"; +export const EQUIPMENT_STATUS_CODE_APPROVED = "Approved"; +export const EQUIPMENT_STATUS_CODE_ARCHIVED = "Archived"; + +// Owners +export const OWNER_STATUS_CODE_PENDING = "Unapproved"; +export const OWNER_STATUS_CODE_APPROVED = "Approved"; +export const OWNER_STATUS_CODE_ARCHIVED = "Archived"; + +// Projects +export const PROJECT_STATUS_CODE_ACTIVE = "Active"; +export const PROJECT_STATUS_CODE_COMPLETED = "Completed"; + +// Rental Requests +export const RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS = "In Progress"; +export const RENTAL_REQUEST_STATUS_CODE_COMPLETED = "Complete"; +export const RENTAL_REQUEST_STATUS_CODE_CANCELLED = "Cancelled"; + +// Hiring Refusal Reasons +export const HIRING_REFUSAL_EQUIPMENT_NOT_AVAILABLE = "Equipment Not Available"; +export const HIRING_REFUSAL_EQUIPMENT_NOT_SUITABLE = "Equipment Not Suitable"; +export const HIRING_REFUSAL_NO_RESPONSE = "No Response"; +export const HIRING_REFUSAL_MAXIMUM_HOURS_REACHED = "Maximum Hours Reached"; +export const HIRING_REFUSAL_MAINTENANCE_CONTRACTOR = "Maintenance Contractor"; +export const HIRING_REFUSAL_OTHER = "Other (Reason to be mentioned in note)"; + +// Rental Agreements +export const RENTAL_AGREEMENT_STATUS_CODE_ACTIVE = "Active"; +export const RENTAL_AGREEMENT_STATUS_CODE_COMPLETED = "Completed"; +export const RENTAL_RATE_PERIOD_HOURLY = "Hr"; +export const RENTAL_RATE_PERIOD_DAILY = "Daily"; +export const RENTAL_RATE_PERIOD_WEEKLY = "Weekly"; +export const RENTAL_RATE_PERIOD_MONTHLY = "Monthly"; +export const RENTAL_RATE_PERIOD_NEGOTIATED = "Negotiated"; +export const RENTAL_RATE_PERIOD_SET = "Set"; + +// Users +export const USER_STATUS_ACTIVE = "Active"; +export const USER_STATUS_ARCHIVED = "Archived"; + +// Date Formats +export const DATE_FULL_MONTH_DAY_YEAR = "MMMM D, YYYY"; +export const DATE_SHORT_MONTH_DAY_YEAR = "MMM D, YYYY"; +export const DATE_YEAR_SHORT_MONTH_DAY = "YYYY-MMM-DD"; +export const DATE_ISO_8601 = "YYYY-MM-DD"; + +export const DATE_ZULU = "YYYY-MM-DDThh:mm:ss[Z]"; + +export const DATE_TIME_ISO_8601 = "YYYY-MM-DDTHH:mm:ss"; +export const DATE_TIME_READABLE = "MMMM D, YYYY [at] h:mm:ss A"; +export const DATE_TIME_LOG = "YYYY/MM/DD HH:mm:ss"; +export const DATE_TIME_FILENAME = "YYYY-MM-DD-HHmmss"; + +// RegEx +export const EMAIL_REGEX = /\S+@\S+\.\S+/; +export const NANP_REGEX = + /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/; +export const MONEY_REGEX = /^\d+(\.\d\d?)?$/; +export const POSTAL_CODE_REGEX = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/; + +// Conditions +export const NON_STANDARD_CONDITION = "Other"; + +// ResponseTypes + +export const RESPONSE_TYPE_BLOB = "blob"; + +// Cloning +export const BY_PROJECT = "By Project"; +export const BY_EQUIPMENT = "By Equipment"; + +export var headerHeight = 0; +export function setHeaderHeight(num) { + headerHeight = num; +} + +// History +export const HISTORY_OWNER = "Owner"; +export const HISTORY_PROJECT = "Project"; +export const HISTORY_EQUIPMENT = "Equipment"; +export const HISTORY_REQUEST = "Request"; +export const HISTORY_USER = "User"; +export const HISTORY_ROLE = "Role"; +export const HISTORY_CONTACT = "Contact"; +export const HISTORY_DOCUMENT = "Document"; + +// Session +export const SESSION_TIMEOUT = 7200000; // 120 minutes +export const SESSION_KEEP_ALIVE_INTERVAL = 600000; // 10 minutes + +// Max Field Lengths +export const MAX_LENGTH_CGL_COMPANY_NAME = 150; +export const MAX_LENGTH_NOTE_TEXT = 2048; +export const MAX_LENGTH_PHONE_NUMBER = 20; +export const MAX_LENGTH_RENTAL_AGREEMENT_NOTE = 150; +export const MAX_LENGTH_STATUS_COMMENT = 255; + +// Max File Sizes +export const MAX_ATTACHMENT_FILE_SIZE = 5242880; // 5 MB +export const MAX_ATTACHMENT_FILE_SIZE_READABLE = "5 MB"; diff --git a/client2/src/js/history.js b/client2/src/js/history.js new file mode 100644 index 000000000..4cbbcf0ab --- /dev/null +++ b/client2/src/js/history.js @@ -0,0 +1,430 @@ +import React from "react"; + +import * as Api from "./api"; +import * as Constant from "./constants"; + +// History Events +export const OWNER_ADDED = "Owner %e was added."; +export const OWNER_MODIFIED = "Owner %e was modified."; +export const OWNER_MODIFIED_STATUS = + 'Owner %e status changed to "%e". Comment: %e'; +export const OWNER_MODIFIED_NAME = "Owner %e is now %e"; +export const OWNER_EQUIPMENT_ADDED = "Owner %e added equipment %e."; +export const OWNER_EQUIPMENT_VERIFIED = "Owner %e verified equipment %e."; +export const OWNER_MODIFIED_POLICY = "Owner %e modified policy."; +export const OWNER_DOCUMENT_ADDED = "Owner %e added document %e."; +export const OWNER_DOCUMENTS_ADDED = "Owner %e added documents."; +export const OWNER_DOCUMENT_DELETED = "Owner %e removed document %e."; +export const OWNER_CONTACT_ADDED = "Owner %e added contact %e."; +export const OWNER_CONTACT_UPDATED = "Owner %e modified contact %e."; +export const OWNER_CONTACT_DELETED = "Owner %e removed contact %e."; + +export const PROJECT_ADDED = "Project %e was added."; +export const PROJECT_MODIFIED = "Project %e was modified."; +export const PROJECT_MODIFIED_STATUS = "Project %e status changed to %e."; +export const PROJECT_MODIFIED_NAME = "Project %e is now %e"; +export const PROJECT_EQUIPMENT_ADDED = "Project %e added equipment %e."; +export const PROJECT_CONTACT_ADDED = "Project %e added contact %e."; +export const PROJECT_CONTACT_UPDATED = "Project %e modified contact %e."; +export const PROJECT_CONTACT_DELETED = "Project %e removed contact %e."; +export const PROJECT_DOCUMENT_ADDED = "Project %e added document %e."; +export const PROJECT_DOCUMENTS_ADDED = "Project %e added documents."; +export const PROJECT_DOCUMENT_DELETED = "Project %e removed document %e."; +export const PROJECT_EQUIPMENT_RELEASED = "Project %e released equipment %e."; +export const PROJECT_RENTAL_REQUEST_ADDED = + "Project %e added rental request %e."; + +export const USER_ADDED = "User %e was added."; +export const USER_MODIFIED = "User %e was modified."; +export const USER_DELETED = "User %e was deleted."; + +export const EQUIPMENT_ADDED = "Equipment %e was added."; +export const EQUIPMENT_MODIFIED = "Equipment %e was modified."; +export const EQUIPMENT_STATUS_MODIFIED = + 'Equipment %e status changed to "%e". Comment: %e'; +export const EQUIPMENT_SENIORITY_MODIFIED = + "Equipment %e seniority was modified."; +export const EQUIPMENT_DOCUMENT_ADDED = "Equipment %e added document %e."; +export const EQUIPMENT_DOCUMENTS_ADDED = "Equipment %e added documents."; +export const EQUIPMENT_DOCUMENT_DELETED = "Equipment %e removed document %e."; +export const EQUIPMENT_ATTACHMENT_ADDED = "Equipment %e added attachment %e."; +export const EQUIPMENT_ATTACHMENT_UPDATED = + "Equipment %e modified attachment %e."; +export const EQUIPMENT_ATTACHMENT_DELETED = + "Equipment %e removed attachment %e."; + +export const RENTAL_REQUEST_ADDED = "Rental request %e was added."; +export const RENTAL_REQUEST_MODIFIED = "Rental request was modified."; +export const RENTAL_REQUEST_DOCUMENT_ADDED = + "Rental request %e added document %e."; +export const RENTAL_REQUEST_DOCUMENTS_ADDED = + "Rental request %e added documents."; +export const RENTAL_REQUEST_DOCUMENT_DELETED = + "Rental request %e removed document %e."; +export const RENTAL_REQUEST_EQUIPMENT_HIRED = + "Rental request %e equipment %e was given a response of %e."; + +// Helper to create an entity object +export function makeHistoryEntity(type, entity) { + return { + type: type, + id: entity.id, + description: entity.name, + path: entity.path, + url: entity.url, + }; +} + +// Log a history event +export function log(historyEntity, event, ...entities) { + // prepend the 'parent' entity + entities.unshift(historyEntity); + + // Build the history text + var historyText = JSON.stringify({ + // The event text, with entity placeholders + text: event, + // The array of entities + entities: entities, + }); + + // Choose the correct API call. + var addHistoryPromise = null; + + switch (historyEntity.type) { + case Constant.HISTORY_OWNER: + addHistoryPromise = Api.addOwnerHistory; + break; + + case Constant.HISTORY_PROJECT: + addHistoryPromise = Api.addProjectHistory; + break; + + case Constant.HISTORY_EQUIPMENT: + addHistoryPromise = Api.addEquipmentHistory; + break; + + case Constant.HISTORY_REQUEST: + addHistoryPromise = Api.addRentalRequestHistory; + break; + + case Constant.HISTORY_USER: + case Constant.HISTORY_ROLE: + break; + default: + break; + } + + if (addHistoryPromise) { + return addHistoryPromise(historyEntity.id, { + historyText: historyText, + }); + } + + return null; +} + +function buildLink(entity, closeFunc) { + // Return a link if the entity has a path; just the description otherwise. + return entity.path ? ( + + {entity.description} + + ) : ( + {entity.description} + ); +} + +export function renderEvent(historyText, closeFunc) { + try { + // Unwrap the JSONed event + var event = JSON.parse(historyText); + + // Parse the text and return it inside a
, replacing field placeholders with linked content. + var tokens = event.text.split("%e"); + return ( +
+ {tokens.map((token, index) => { + return ( + + {token} + {index < tokens.length - 1 + ? buildLink(event.entities[index], closeFunc || null) + : null} + + ); + })} +
+ ); + } catch (err) { + // Not JSON so just push out what's in there. + return {historyText}; + } +} + +export function get(historyEntity, offset, limit) { + // If not showing all, then just fetch the first 10 entries + var params = { + offset: offset || 0, + limit: limit || null, + }; + + switch (historyEntity.type) { + case Constant.HISTORY_OWNER: + return Api.getOwnerHistory(historyEntity.id, params); + + case Constant.HISTORY_PROJECT: + return Api.getProjectHistory(historyEntity.id, params); + + case Constant.HISTORY_EQUIPMENT: + return Api.getEquipmentHistory(historyEntity.id, params); + + case Constant.HISTORY_REQUEST: + return Api.getRentalRequestHistory(historyEntity.id, params); + + case Constant.HISTORY_USER: + case Constant.HISTORY_ROLE: + break; + default: + break; + } + + return null; +} + +// Logging +export function ownerAdded(owner) { + return log(owner.historyEntity, OWNER_ADDED); +} + +export function ownerModified(owner) { + return log(owner.historyEntity, OWNER_MODIFIED); +} + +export function ownerModifiedStatus(owner, status, statusComment) { + return log( + owner.historyEntity, + OWNER_MODIFIED_STATUS, + { description: status }, + { description: statusComment } + ); +} + +export function ownerContactAdded(owner, contact) { + return log(owner.historyEntity, OWNER_CONTACT_ADDED, contact.historyEntity); +} + +export function ownerContactUpdated(owner, contact) { + return log(owner.historyEntity, OWNER_CONTACT_UPDATED, contact.historyEntity); +} + +export function ownerContactDeleted(owner, contact) { + return log(owner.historyEntity, OWNER_CONTACT_DELETED, contact.historyEntity); +} + +export function ownerModifiedPolicy(owner) { + return log(owner.historyEntity, OWNER_MODIFIED_POLICY); +} + +export function ownerEquipmentAdded(owner, equipment) { + return log( + owner.historyEntity, + OWNER_EQUIPMENT_ADDED, + equipment.historyEntity + ); +} + +export function ownerEquipmentVerified(owner, equipment) { + return log( + owner.historyEntity, + OWNER_EQUIPMENT_VERIFIED, + equipment.historyEntity + ); +} + +export function ownerDocumentAdded(owner, document) { + return log(owner.historyEntity, OWNER_DOCUMENT_ADDED, { + description: document, + }); +} + +export function ownerDocumentsAdded(owner) { + return log(owner.historyEntity, OWNER_DOCUMENTS_ADDED); +} + +export function ownerDocumentDeleted(owner, document) { + return log( + owner.historyEntity, + OWNER_DOCUMENT_DELETED, + document.historyEntity + ); +} + +export function projectAdded(project) { + return log(project.historyEntity, PROJECT_ADDED); +} + +export function projectModified(project) { + return log(project.historyEntity, PROJECT_MODIFIED); +} + +export function projectModifiedStatus(project) { + return log(project.historyEntity, PROJECT_MODIFIED_STATUS, { + description: project.status, + }); +} + +export function projectContactAdded(project, contact) { + return log( + project.historyEntity, + PROJECT_CONTACT_ADDED, + contact.historyEntity + ); +} + +export function projectContactUpdated(project, contact) { + return log( + project.historyEntity, + PROJECT_CONTACT_UPDATED, + contact.historyEntity + ); +} + +export function projectContactDeleted(project, contact) { + return log( + project.historyEntity, + PROJECT_CONTACT_DELETED, + contact.historyEntity + ); +} + +export function projectDocumentAdded(project, document) { + return log(project.historyEntity, PROJECT_DOCUMENT_ADDED, { + description: document, + }); +} + +export function projectDocumentsAdded(project) { + return log(project.historyEntity, PROJECT_DOCUMENTS_ADDED); +} + +export function projectDocumentDeleted(project, document) { + return log( + project.historyEntity, + PROJECT_DOCUMENT_DELETED, + document.historyEntity + ); +} + +export function projectEquipmentReleased(project, equipment) { + return log( + project.historyEntity, + PROJECT_EQUIPMENT_RELEASED, + equipment.historyEntity + ); +} + +export function projectRentalRequestAdded(project, rentalRequest) { + return log( + project.historyEntity, + PROJECT_RENTAL_REQUEST_ADDED, + rentalRequest.historyEntity + ); +} + +export function equipmentAdded(equipment) { + return log(equipment.historyEntity, EQUIPMENT_ADDED); +} + +export function equipmentModified(equipment) { + return log(equipment.historyEntity, EQUIPMENT_MODIFIED); +} + +export function equipmentSeniorityModified(equipment) { + return log(equipment.historyEntity, EQUIPMENT_SENIORITY_MODIFIED); +} + +export function equipmentStatusModified(equipment, status, statusComment) { + return log( + equipment.historyEntity, + EQUIPMENT_STATUS_MODIFIED, + { description: status }, + { description: statusComment } + ); +} + +export function equipmentDocumentAdded(equipment, document) { + return log(equipment.historyEntity, EQUIPMENT_DOCUMENT_ADDED, { + description: document, + }); +} + +export function equipmentDocumentsAdded(equipment) { + return log(equipment.historyEntity, EQUIPMENT_DOCUMENTS_ADDED); +} + +export function equipmentDocumentDeleted(equipment, document) { + return log( + equipment.historyEntity, + EQUIPMENT_DOCUMENT_DELETED, + document.historyEntity + ); +} + +export function equipmentAttachmentAdded(equipment, attachment) { + return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_ADDED, { + description: attachment, + }); +} + +export function equipmentAttachmentUpdated(equipment, attachment) { + return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_UPDATED, { + description: attachment, + }); +} + +export function equipmentAttachmentDeleted(equipment, attachment) { + return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_DELETED, { + description: attachment, + }); +} + +export function rentalRequestAdded(rentalRequest) { + return log(rentalRequest.historyEntity, RENTAL_REQUEST_ADDED); +} + +export function rentalRequestModified(rentalRequest) { + return log(rentalRequest.historyEntity, RENTAL_REQUEST_MODIFIED); +} + +export function rentalRequestDocumentAdded(rentalRequest, document) { + return log(rentalRequest.historyEntity, RENTAL_REQUEST_DOCUMENT_ADDED, { + description: document, + }); +} + +export function rentalRequestDocumentsAdded(rentalRequest) { + return log(rentalRequest.historyEntity, RENTAL_REQUEST_DOCUMENTS_ADDED); +} + +export function rentalRequestDocumentDeleted(rentalRequest, document) { + return log( + rentalRequest.historyEntity, + RENTAL_REQUEST_DOCUMENT_DELETED, + document.historyEntity + ); +} + +export function rentalRequestEquipmentHired( + rentalRequest, + equipment, + offerResponse +) { + console.log(equipment); + return log( + rentalRequest.historyEntity, + RENTAL_REQUEST_EQUIPMENT_HIRED, + equipment.historyEntity, + { description: offerResponse } + ); +} diff --git a/client2/src/js/init.js b/client2/src/js/init.js new file mode 100644 index 000000000..debc247cc --- /dev/null +++ b/client2/src/js/init.js @@ -0,0 +1,115 @@ +/* global module */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import Promise from 'bluebird'; + +Promise.config({ + cancellation: true, + warnings: { + wForgottenReturn: false, + }, +}); + +import App from './App.jsx'; +import * as Api from './api'; +import { ApiError } from './utils/http'; + +var initializationEl = document.querySelector('#initialization'); +var progressBarEl = initializationEl.querySelector('.progress-bar'); +var progress = +progressBarEl.getAttribute('aria-valuenow'); + +function incrementProgressBar(gotoPercent) { + progress = Math.min(gotoPercent || (progress + 20), 100); // cap to 100% + progressBarEl.style.width = `${progress}%`; + progressBarEl.setAttribute('aria-valuenow', progress); + progressBarEl.querySelector('span').textContent = `${progress}% Complete`; +} + +if (module.hot) { + // NOTE: this is a terrible hack to work around react-router v3's warning about changing routes + // because of Webpack HMR. See: + // https://github.com/gaearon/react-hot-loader/issues/298#issuecomment-236510239 for more + // information. + // This can be removed once HETS-1169 is completed. + + const orgError = console.error; // eslint-disable-line no-console + console.error = (...args) => { // eslint-disable-line no-console + const routeChangeWarning = args && args.length === 1 && typeof args[0] === 'string' && args[0].indexOf('You cannot change ;') > -1; + if (!routeChangeWarning) { + // Log the error as normally + orgError.apply(console, args); + } + }; +} + +export default function startApp() { + if (process.env.NODE_ENV === 'development' && process.env.DEV_USER) { //eslint-disable-line + return Api.setDevUser(process.env.DEV_USER).finally(() => { //eslint-disable-line + initializeApp(); + }); + } + + return initializeApp(); +} + +function initializeApp() { + incrementProgressBar(5); + + Api.getCurrentUser().then(user => { + incrementProgressBar(33); + + return getLookups(user).then(() => { + incrementProgressBar(100); + + initializationEl.addEventListener('transitionend', () => { + const appElement = document.querySelector('#app'); + + ReactDOM.render(, appElement); + initializationEl.classList.add('done'); + initializationEl.addEventListener('transitionend', () => { + initializationEl.parentNode.removeChild(initializationEl); + }); + }); + }); + }).catch(err => { + showError(err); + }); +} + +function getLookups(user) { + if (user.businessUser) { + return Promise.resolve(); + } else { + var districtId = user.district.id; + return Promise.all([ + Api.getDistricts(), + Api.getRegions(), + Api.getServiceAreas(), + Api.getLocalAreas(districtId), + Api.getFiscalYears(districtId), + Api.getPermissions(), + Api.getCurrentUserDistricts(), + Api.getFavourites(), + ]); + } +} + +function showError(err) { + progressBarEl.classList.add('progress-bar-danger'); + progressBarEl.classList.remove('active'); + console.error(err); + var errorMessage = String(err); + if (err instanceof ApiError) { + errorMessage = err.message; + } + + ReactDOM.render(( +
+

Error loading application

+

{errorMessage}

+
+ ), document.getElementById('init-error')); +} + +window.onload = startApp; diff --git a/client2/src/js/reducers/all.js b/client2/src/js/reducers/all.js new file mode 100644 index 000000000..641951f2c --- /dev/null +++ b/client2/src/js/reducers/all.js @@ -0,0 +1,18 @@ +import { combineReducers } from 'redux'; + +import uiReducer from './ui'; +import userReducer from './user'; +import searchReducer from './search'; +import modelsReducer from './models'; +import lookupsReducer from './lookups'; +import versionReducer from './version'; + + +export default combineReducers({ + ui : uiReducer, + user : userReducer, + search : searchReducer, + models : modelsReducer, + lookups : lookupsReducer, + version : versionReducer, +}); diff --git a/client2/src/js/reducers/lookups.js b/client2/src/js/reducers/lookups.js new file mode 100644 index 000000000..1a94ff7ed --- /dev/null +++ b/client2/src/js/reducers/lookups.js @@ -0,0 +1,277 @@ +import _ from "lodash"; + +import * as Action from "../actionTypes"; + +const DEFAULT_LOOKUPS = { + // cities: {}, + districts: {}, + regions: {}, + serviceAreas: {}, + localAreas: {}, + equipmentTypes: { + data: {}, + loaded: false, + }, + equipment: { + lite: { + data: {}, + loaded: false, + }, + agreementSummary: { + data: {}, + loaded: false, + }, + ts: { + data: {}, + loaded: false, + }, + hires: { + data: {}, + loaded: false, + }, + }, + districtEquipmentTypes: { + data: {}, + loaded: false, + }, + districtEquipmentTypesAgreementSummary: { + data: {}, + loaded: false, + }, + fiscalYears: {}, + permissions: {}, + rentalConditions: { + data: [], + loaded: false, + loading: false, + }, + // provincialRateTypes: [], + overtimeRateTypes: [], + // owners: { + // data: {}, + // loading: false, + // }, + owners: { + lite: { + data: {}, + loaded: false, + }, + ts: { + data: {}, + loaded: false, + }, + hires: { + data: {}, + loaded: false, + }, + }, + roles: {}, + projects: { + data: {}, + loaded: false, + }, + projectsCurrentFiscal: { + data: {}, + loaded: false, + }, + projectsAgreementSummary: { + data: {}, + loaded: false, + }, + agreementSummaryLite: { + data: {}, + loaded: false, + }, + users: {}, + rolloverStatus: {}, + searchSummaryCounts: {}, +}; + +export default function lookupsReducer(state = DEFAULT_LOOKUPS, action) { + switch (action.type) { + // Loaded once at init time, as they do not change very often, and + // certainly not within the app. + + // XXX: Looks like this is unused + // case Action.UPDATE_CITIES_LOOKUP: + // return { ...state, cities: action.cities }; + + case Action.UPDATE_DISTRICTS_LOOKUP: + return { ...state, districts: action.districts }; + + case Action.UPDATE_REGIONS_LOOKUP: + return { ...state, regions: action.regions }; + + case Action.UPDATE_SERVICE_AREAS_LOOKUP: + return { ...state, serviceAreas: action.serviceAreas }; + + case Action.UPDATE_LOCAL_AREAS_LOOKUP: + return { ...state, localAreas: action.localAreas }; + + case Action.UPDATE_EQUIPMENT_TYPES_LOOKUP: + return { + ...state, + equipmentTypes: { data: action.equipmentTypes, loaded: true }, + }; + + case Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP: + return { + ...state, + districtEquipmentTypes: { + data: action.districtEquipmentTypes, + loaded: true, + }, + }; + + case Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP: + return { + ...state, + districtEquipmentTypesAgreementSummary: { + data: action.districtEquipmentTypes, + loaded: true, + }, + }; + + case Action.UPDATE_FISCAL_YEARS_LOOKUP: + return { ...state, fiscalYears: action.fiscalYears }; + + case Action.UPDATE_PERMISSIONS_LOOKUP: + return { ...state, permissions: action.permissions }; + + case Action.UPDATE_ROLLOVER_STATUS_LOOKUP: + return { ...state, rolloverStatus: action.status }; + + // Not typical lookups, because they can change within the app, so + // ensure they're loaded/updated as needed. + // XXX: Looks like this is unused + // case Action.OWNERS_LOOKUP_REQUEST: + // return { ...state, owners: { ...state.owners, loading: true } }; + + // XXX: Looks like this is unused + // case Action.UPDATE_OWNERS_LOOKUP: + // return { ...state, owners: { data: action.owners, loading: false } }; + + case Action.UPDATE_OWNERS_LITE_LOOKUP: + return { + ...state, + owners: { + ...state.owners, + lite: { data: action.owners, loaded: true }, + }, + }; + + case Action.UPDATE_OWNERS_LITE_HIRES_LOOKUP: + return { + ...state, + owners: { + ...state.owners, + hires: { data: action.owners, loaded: true }, + }, + }; + + case Action.UPDATE_OWNERS_LITE_TS_LOOKUP: + return { + ...state, + owners: { ...state.owners, ts: { data: action.owners, loaded: true } }, + }; + + case Action.UPDATE_EQUIPMENT_LITE_LOOKUP: + return { + ...state, + equipment: { + ...state.equipment, + lite: { data: action.equipment, loaded: true }, + }, + }; + + case Action.UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP: + return { + ...state, + equipment: { + ...state.equipment, + agreementSummary: { data: action.equipment, loaded: true }, + }, + }; + + case Action.UPDATE_EQUIPMENT_TS_LOOKUP: + return { + ...state, + equipment: { + ...state.equipment, + ts: { data: action.equipment, loaded: true }, + }, + }; + + case Action.UPDATE_EQUIPMENT_HIRES_LOOKUP: + return { + ...state, + equipment: { + ...state.equipment, + hires: { data: action.equipment, loaded: true }, + }, + }; + + case Action.UPDATE_ROLES_LOOKUP: + return { ...state, roles: action.roles }; + + case Action.UPDATE_PROJECTS_LOOKUP: + return { + ...state, + projects: { ...state.projects, data: action.projects, loaded: true }, + }; + + case Action.UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP: + return { + ...state, + projectsAgreementSummary: { data: action.projects, loaded: true }, + }; + + case Action.UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP: + return { + ...state, + projectsCurrentFiscal: { + ...state.projectsCurrentFiscal, + data: _.sortBy(action.projects, "name"), + loaded: true, + }, + }; + + case Action.UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP: + return { + ...state, + agreementSummaryLite: { data: action.agreements, loaded: true }, + }; + + case Action.UPDATE_USERS_LOOKUP: + return { ...state, users: action.users }; + + case Action.UPDATE_RENTAL_CONDITIONS_LOOKUP: + return { + ...state, + rentalConditions: { + data: action.rentalConditions, + loading: false, + loaded: true, + }, + }; + + case Action.RENTAL_CONDITIONS_LOOKUP_REQUEST: + return { + ...state, + rentalConditions: { ...state.rentalConditions, loading: true }, + }; + + // XXX: Looks like this is unused + // case Action.UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP: + // return { ...state, provincialRateTypes: action.provincialRateTypes }; + + case Action.UPDATE_OVERTIME_RATE_TYPES_LOOKUP: + return { ...state, overtimeRateTypes: action.overtimeRateTypes }; + + case Action.UPDATE_SEARCH_SUMMARY_COUNTS: + return { ...state, searchSummaryCounts: action.searchSummaryCounts }; + + default: + return state; + } +} diff --git a/client2/src/js/reducers/models.js b/client2/src/js/reducers/models.js new file mode 100644 index 000000000..21f8e65c9 --- /dev/null +++ b/client2/src/js/reducers/models.js @@ -0,0 +1,807 @@ +import _ from "lodash"; +import produce from "immer"; + +import * as Action from "../actionTypes"; +import { findAndUpdate } from "../utils/array"; + +const DEFAULT_MODELS = { + users: { + data: {}, + loading: false, + loaded: false, + }, + user: {}, + userDistricts: { + data: {}, + loading: false, + }, + currentUserDistricts: { + data: {}, + loading: false, + }, + + favourites: { + equipment: {}, + hiringReport: {}, + owner: {}, + ownersCoverage: {}, + project: {}, + rentalRequests: {}, + timeEntry: {}, + user: {}, + aitReport: {}, + }, + + equipmentList: { + data: {}, + loading: false, + loaded: false, + }, + equipment: {}, + equipmentSeniorityHistory: {}, + equipmentNotes: [], + equipmentAttachments: {}, + equipmentHistory: {}, + equipmentRentalAgreements: { + data: {}, + }, + + owners: { + data: {}, + loading: false, + loaded: false, + }, + owner: {}, + ownerEquipment: { + data: {}, + loading: false, + loaded: false, + }, + ownerAttachments: {}, + ownerHistory: {}, + + projects: { + data: {}, + loading: false, + loaded: false, + }, + project: {}, + // projectEquipment: { + // data: {}, + // loading: false, + // success: false, + // }, + // projectTimeRecords: { + // data: {}, + // loading: false, + // success: false, + // }, + // projectNotes: {}, + // projectAttachments: {}, + // projectHistory: {}, + projectRentalAgreements: { + data: {}, + }, + + rentalRequests: { + data: {}, + loading: false, + loaded: false, + }, + rentalRequest: {}, + // rentalRequestNotes: {}, + // rentalRequestAttachments: {}, + // rentalRequestHistory: {}, + // rentalRequestRotationList: { + // data: {}, + // loading: false, + // success: false, + // }, + + rentalAgreement: {}, + rentalAgreementTimeRecords: {}, + // rentalRate: {}, + rentalCondition: {}, + rentalConditions: {}, + + timeEntries: { + data: {}, + loading: false, + loaded: false, + }, + + hiringResponses: { + data: {}, + loading: false, + loaded: false, + }, + + ownersCoverage: { + data: {}, + loading: false, + loaded: false, + }, + + aitResponses: { + data: {}, + loading: false, + loaded: false, + }, + + roles: {}, + role: {}, + rolePermissions: {}, + + // XXX: Looks like this is unused + // contacts: {}, + // contact: {}, + + documents: {}, + document: {}, + + history: { + equipment: {}, + owner: {}, + project: {}, + rentalRequest: {}, + }, + + timeRecord: { + data: {}, + }, + + business: null, +}; + +export default function modelsReducer(state = DEFAULT_MODELS, action) { + switch (action.type) { + // Users + case Action.USERS_REQUEST: + return { + ...state, + users: { ...state.users, loading: true, loaded: false }, + }; + + case Action.UPDATE_USERS: + return { + ...state, + users: { data: action.users, loading: false, loaded: true }, + }; + + case Action.CLEAR_USERS: + return { ...state, users: { data: {}, loading: false, loaded: false } }; + + case Action.UPDATE_USER: + return { ...state, user: action.user }; + + case Action.ADD_USER: + return { ...state, user: action.user }; + + case Action.DELETE_USER: + return { ...state, user: action.user }; + + case Action.USER_DISTRICTS: + return { + ...state, + userDistricts: { data: action.userDistricts, loading: false }, + }; + + case Action.CURRENT_USER_DISTRICTS: + return { + ...state, + currentUserDistricts: { + data: action.currentUserDistricts, + loading: false, + }, + }; + + // Favourites + case Action.UPDATE_FAVOURITES: + return { + ...state, + favourites: { ...state.favourites, ...action.favourites }, + }; + + case Action.ADD_FAVOURITE: + case Action.UPDATE_FAVOURITE: + return { + ...state, + favourites: { + ...state.favourites, + [action.favourite.type]: { + ...state.favourites[action.favourite.type], + [action.favourite.id]: action.favourite, + }, + }, + }; + + case Action.DELETE_FAVOURITE: + return { + ...state, + favourites: { + ...state.favourites, + [action.favourite.type]: _.omit( + state.favourites[action.favourite.type], + [action.favourite.id] + ), + }, + }; + + // Contacts + + // XXX: Looks like this is unused + // case Action.ADD_CONTACT: + // return { ...state, contact: action.contact }; + + // XXX: Looks like this is unused + // case Action.UPDATE_CONTACT: + // return { ...state, contact: action.contact }; + + case Action.DELETE_CONTACT: + return produce(state, (draftState) => { + const contact = action.contact; + const contactId = contact.id; + + const existingOwner = draftState.owner[contact.ownerId]; + if (existingOwner) { + const updatedList = existingOwner.contacts.filter( + (contact) => contact.id !== contactId + ); + existingOwner.contacts = updatedList; + } + + const existingProject = draftState.project[contact.projectId]; + if (existingProject) { + const updatedList = existingProject.contacts.filter( + (contact) => contact.id !== contactId + ); + existingProject.contacts = updatedList; + } + }); + + // Documents + case Action.UPDATE_DOCUMENTS: + return { ...state, documents: action.documents }; + + case Action.ADD_DOCUMENT: + return { ...state, document: action.document }; + + case Action.UPDATE_DOCUMENT: + return { ...state, document: action.document }; + + case Action.DELETE_DOCUMENT: + return { ...state, document: action.document }; + + // Equipment + case Action.EQUIPMENT_LIST_REQUEST: + return { + ...state, + equipmentList: { ...state.equipmentList, loading: true, loaded: false }, + }; + + case Action.UPDATE_EQUIPMENT_LIST: + return { + ...state, + equipmentList: { + data: action.equipmentList, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_EQUIPMENT_LIST: + return { + ...state, + equipmentList: { data: {}, loading: false, loaded: false }, + }; + + case Action.ADD_EQUIPMENT: + case Action.UPDATE_EQUIPMENT: + return produce(state, (draftState) => { + draftState.equipment[action.equipment.id] = action.equipment; + }); + + case Action.UPDATE_EQUIPMENT_NOTES: + return { ...state, equipmentNotes: action.notes }; + + case Action.UPDATE_EQUIPMENT_RENTAL_AGREEMENTS: + return { + ...state, + equipmentRentalAgreements: { data: action.rentalAgreements }, + }; + + // Owners + case Action.OWNERS_REQUEST: + return { + ...state, + owners: { ...state.owners, loading: true, loaded: false }, + }; + + case Action.UPDATE_OWNERS: + return { + ...state, + owners: { data: action.owners, loading: false, loaded: true }, + }; + + case Action.OWNER_EQUIPMENT_REQUEST: + return { + ...state, + ownerEquipment: { + data: action.equipment, + loading: true, + loaded: false, + }, + }; + + case Action.UPDATE_OWNER_EQUIPMENT: + return { + ...state, + ownerEquipment: { + data: action.equipment, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_OWNERS: + return { ...state, owners: { data: {}, loading: false, loaded: false } }; + + // XXX: Looks like `Action.DELETE_OWNER` is unused + case Action.ADD_OWNER: + case Action.UPDATE_OWNER: /* case Action.DELETE_OWNER: */ { + const ownerId = action.owner.id; + const owner = { notes: [], ...state.owner[ownerId], ...action.owner }; + return { ...state, owner: { ...state.owner, [ownerId]: owner } }; + } + + case Action.UPDATE_OWNER_NOTES: + return produce(state, (draftState) => { + const existingOwner = draftState.owner[action.ownerId] || {}; + existingOwner.notes = action.notes; + draftState.owner[action.ownerId] = existingOwner; + }); + + case Action.ADD_OWNER_NOTE: + return produce(state, (draftState) => { + const existingOwner = draftState.owner[action.ownerId]; + const existingNotes = existingOwner.notes || []; + existingNotes.push(action.note); + existingOwner.notes = existingNotes; + }); + + case Action.ADD_OWNER_CONTACT: + return produce(state, (draftState) => { + const existingOwner = draftState.owner[action.ownerId] || {}; + const updatedContacts = existingOwner.contacts || []; + updatedContacts.push(action.contact); + + existingOwner.contacts = updatedContacts; + }); + + case Action.UPDATE_OWNER_CONTACT: + return produce(state, (draftState) => { + const existingOwner = draftState.owner[action.ownerId] || {}; + const updatedContacts = existingOwner.contacts || []; + + if (action.contact.isPrimary) { + const previousPrimaryContact = _.find(updatedContacts, { + isPrimary: true, + }); + if (previousPrimaryContact) { + previousPrimaryContact.isPrimary = false; + } + } + + const pos = _.findIndex( + updatedContacts, + (contact) => contact.id === action.contact.id + ); + updatedContacts[pos] = action.contact; + + existingOwner.contacts = updatedContacts; + }); + + // Projects + case Action.PROJECTS_REQUEST: + return { + ...state, + projects: { ...state.projects, loading: true, loaded: false }, + }; + + case Action.UPDATE_PROJECTS: + return { + ...state, + projects: { data: action.projects, loading: false, loaded: true }, + }; + + case Action.CLEAR_PROJECTS: + return { + ...state, + projects: { data: {}, loading: false, loaded: false }, + }; + + case Action.ADD_PROJECT: + case Action.UPDATE_PROJECT: { + const projectId = action.project.id; + const project = { + notes: [], + ...state.project[projectId], + ...action.project, + }; + + return { ...state, project: { ...state.project, [projectId]: project } }; + } + + // case Action.UPDATE_PROJECT_EQUIPMENT: + // return { ...state, projectEquipment: { data: action.projectEquipment, loading: false, success: true } }; + + // XXX: Looks like this is unused + // case Action.UPDATE_PROJECT_TIME_RECORDS: + // return { ...state, projectTimeRecords: { data: action.projectTimeRecords, loading: false, success: true } }; + + case Action.ADD_PROJECT_NOTE: { + const existingProject = { ...(state.project[action.projectId] || {}) }; + const notes = (existingProject.notes || []).slice(); + notes.push(action.note); + + return { + ...state, + project: { ...state.project, [action.projectId]: existingProject }, + }; + } + + case Action.UPDATE_PROJECT_NOTES: { + const existingProject = { ...(state.project[action.projectId] || {}) }; + existingProject.notes = action.notes; + + return { + ...state, + project: { ...state.project, [action.projectId]: existingProject }, + }; + } + + case Action.UPDATE_PROJECT_RENTAL_AGREEMENTS: + return { + ...state, + projectRentalAgreements: { data: action.rentalAgreements }, + }; + + case Action.DELETE_PROJECT_RENTAL_REQUEST: { + const existingProject = { ...(state.project[action.projectId] || {}) }; + const updatedList = existingProject.rentalRequests.filter( + (rentalRequest) => rentalRequest.id !== action.requestId + ); + existingProject.rentalRequests = updatedList; + return { + ...state, + project: { ...state.project, [action.projectId]: existingProject }, + }; + } + + case Action.ADD_PROJECT_CONTACT: + return produce(state, (draftState) => { + const existingProject = draftState.project[action.projectId] || {}; + const updatedContacts = existingProject.contacts || []; + updatedContacts.push(action.contact); + + existingProject.contacts = updatedContacts; + }); + + case Action.UPDATE_PROJECT_CONTACT: + return produce(state, (draftState) => { + const existingProject = draftState.project[action.projectId] || {}; + const updatedContacts = existingProject.contacts || []; + + if (action.contact.isPrimary) { + const previousPrimaryContact = _.find(updatedContacts, { + isPrimary: true, + }); + if (previousPrimaryContact) { + previousPrimaryContact.isPrimary = false; + } + } + + const pos = _.findIndex( + updatedContacts, + (contact) => contact.id === action.contact.id + ); + updatedContacts[pos] = action.contact; + + existingProject.contacts = updatedContacts; + }); + + // Rental Requests + case Action.RENTAL_REQUESTS_REQUEST: + return { + ...state, + rentalRequests: { + ...state.rentalRequests, + loading: true, + loaded: false, + }, + }; + + case Action.UPDATE_RENTAL_REQUESTS: + return { + ...state, + rentalRequests: { + data: action.rentalRequests, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_RENTAL_REQUESTS: + return { + ...state, + rentalRequests: { data: {}, loading: false, loaded: false }, + }; + + // Rental Request + case Action.ADD_RENTAL_REQUEST: + case Action.UPDATE_RENTAL_REQUEST: + return produce(state, (draftState) => { + const rentalRequests = draftState.rentalRequest; + const rentalRequestId = action.rentalRequestId; + rentalRequests[rentalRequestId] = { + notes: [], + rotationList: [], + ...rentalRequests[rentalRequestId], + ...action.rentalRequest, + }; + }); + + case Action.UPDATE_RENTAL_REQUEST_NOTES: + return produce(state, (draftState) => { + const rentalRequests = draftState.rentalRequest; + const rentalRequestId = action.rentalRequestId; + rentalRequests[rentalRequestId] = { + ...rentalRequests[rentalRequestId], + notes: action.notes, + }; + }); + + case Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST: + return produce(state, (draftState) => { + const rentalRequests = draftState.rentalRequest; + const rentalRequestId = action.rentalRequestId; + rentalRequests[rentalRequestId] = { + ...rentalRequests[rentalRequestId], + rotationList: action.rotationList, + }; + }); + + // Time Entries + case Action.TIME_ENTRIES_REQUEST: + return { ...state, timeEntries: { ...state.timeEntries, loading: true } }; + + case Action.UPDATE_TIME_ENTRIES: + return { + ...state, + timeEntries: { data: action.timeEntries, loading: false, loaded: true }, + }; + + case Action.CLEAR_TIME_ENTRIES: + return { + ...state, + timeEntries: { data: {}, loading: false, loaded: false }, + }; + + // Hiring Responses + case Action.HIRING_RESPONSES_REQUEST: + return { + ...state, + hiringResponses: { + ...state.hiringResponses, + loading: true, + loaded: false, + }, + }; + + case Action.UPDATE_HIRING_RESPONSES: + return { + ...state, + hiringResponses: { + data: action.hiringResponses, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_HIRING_RESPONSES: + return { + ...state, + hiringResponses: { data: {}, loading: false, loaded: false }, + }; + + // Owners' Coverage + case Action.OWNERS_COVERAGE_REQUEST: + return { + ...state, + ownersCoverage: { + ...state.ownersCoverage, + loading: true, + loaded: false, + }, + }; + + case Action.UPDATE_OWNERS_COVERAGE: + return { + ...state, + ownersCoverage: { + data: action.ownersCoverage, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_OWNERS_COVERAGE: + return { + ...state, + ownersCoverage: { data: {}, loading: false, loaded: false }, + }; + + // Rental Agreements + // XXX: Looks like this is unused + // case Action.ADD_RENTAL_AGREEMENT: + // return { ...state, rentalAgreement: { ...state.rentalAgreement, [action.rentalAgreement.id]: action.rentalAgreement } }; + + // case Action.GENERATE_ANOTHER_RENTAL_AGREEMENT: + // return { ...state, rentalAgreement: { ...state.rentalAgreement, [action.rentalAgreement.id]: action.rentalAgreement } }; + + case Action.UPDATE_RENTAL_AGREEMENT: + return produce(state, (draftState) => { + draftState.rentalAgreement[action.rentalAgreement.id] = + action.rentalAgreement; + }); + + case Action.RENTAL_AGREEMENT_TIME_RECORDS: + return { + ...state, + rentalAgreementTimeRecords: action.rentalAgreementTimeRecords, + }; + + // Rental Rates, Conditions + case Action.ADD_RENTAL_RATES: + return produce(state, (draftState) => { + const rentalAgreementRates = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementRates; + rentalAgreementRates.push(...action.rentalRates); + }); + + case Action.UPDATE_RENTAL_RATES: + return produce(state, (draftState) => { + const rentalAgreementRates = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementRates; + action.rentalRates.forEach((rentalRate) => { + findAndUpdate(rentalAgreementRates, rentalRate, "id"); + }); + }); + + case Action.DELETE_RENTAL_RATE: + return produce(state, (draftState) => { + const rentalAgreementRates = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementRates; + _.remove(rentalAgreementRates, { id: action.rentalRate.id }); + }); + + case Action.ADD_RENTAL_CONDITIONS: + return produce(state, (draftState) => { + const rentalAgreementConditions = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementConditions; + rentalAgreementConditions.push(...action.rentalConditions); + }); + + case Action.UPDATE_RENTAL_CONDITIONS: + return produce(state, (draftState) => { + const rentalAgreementConditions = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementConditions; + action.rentalConditions.forEach((rentalCondition) => { + findAndUpdate(rentalAgreementConditions, rentalCondition, "id"); + }); + }); + + case Action.DELETE_RENTAL_CONDITION: + return produce(state, (draftState) => { + const rentalAgreementConditions = + draftState.rentalAgreement[action.rentalAgreementId] + .rentalAgreementConditions; + _.remove(rentalAgreementConditions, { id: action.rentalCondition.id }); + }); + + // AIT Report + case Action.AIT_REPORT_REQUEST: + return { + ...state, + aitResponses: { ...state.aitResponses, loading: true, loaded: false }, + }; + + case Action.UPDATE_AIT_REPORT: + return { + ...state, + aitResponses: { + data: action.aitResponses, + loading: false, + loaded: true, + }, + }; + + case Action.CLEAR_AIT_REPORT: + return { + ...state, + aitResponses: { data: {}, loading: false, loaded: false }, + }; + + // Roles, Permissions + case Action.UPDATE_ROLES: + return { ...state, roles: action.roles }; + + case Action.ADD_ROLE: + return { ...state, role: action.role }; + + case Action.UPDATE_ROLE: + return { ...state, role: action.role }; + + case Action.DELETE_ROLE: + return { ...state, role: action.role }; + + case Action.UPDATE_ROLE_PERMISSIONS: + return { ...state, rolePermissions: action.rolePermissions }; + + // History + case Action.UPDATE_EQUIPMENT_HISTORY: + return produce(state, (draftState) => { + draftState.history.equipment[action.id] = action.history; + }); + + case Action.UPDATE_OWNER_HISTORY: + return produce(state, (draftState) => { + draftState.history.owner[action.id] = action.history; + }); + + case Action.UPDATE_PROJECT_HISTORY: + return produce(state, (draftState) => { + draftState.history.project[action.id] = action.history; + }); + + case Action.UPDATE_RENTAL_REQUEST_HISTORY: + return produce(state, (draftState) => { + draftState.history.rentalRequest[action.id] = action.history; + }); + + // Notes + case Action.DELETE_NOTE: { + let notesCollectionName = null; + + if (action.noteId in state.equipmentNotes) { + notesCollectionName = "equipmentNotes"; + } + + if (notesCollectionName) { + const notes = state[notesCollectionName].slice(); + _.remove(notes, { id: action.noteId }); + + return { ...state, [notesCollectionName]: notes }; + } + + return state; + } + + // Time Record + case Action.DELETE_TIME_RECORD: + return { ...state, timeRecord: { data: action.timeRecord } }; + + // Businesses + case Action.UPDATE_BUSINESS: + return { ...state, business: action.business }; + default: + return state; + } +} + +export const modelsSelector = (state) => state.models; diff --git a/client2/src/js/reducers/search.js b/client2/src/js/reducers/search.js new file mode 100644 index 000000000..d8788f420 --- /dev/null +++ b/client2/src/js/reducers/search.js @@ -0,0 +1,50 @@ +import * as Action from "../actionTypes"; + +const DEFAULT_SEARCHES = { + equipmentList: {}, + owners: {}, + projects: {}, + rentalRequests: {}, + timeEntries: {}, + hiringResponses: {}, + aitResponses: {}, + ownersCoverage: {}, + users: {}, + roles: {}, +}; + +export default function searchReducer(state = DEFAULT_SEARCHES, action) { + switch (action.type) { + case Action.UPDATE_EQUIPMENT_LIST_SEARCH: + return { ...state, equipmentList: action.equipmentList }; + + case Action.UPDATE_OWNERS_SEARCH: + return { ...state, owners: action.owners }; + + case Action.UPDATE_PROJECTS_SEARCH: + return { ...state, projects: action.projects }; + + case Action.UPDATE_RENTAL_REQUESTS_SEARCH: + return { ...state, rentalRequests: action.rentalRequests }; + + case Action.UPDATE_TIME_ENTRIES_SEARCH: + return { ...state, timeEntries: action.timeEntries }; + + case Action.UPDATE_HIRING_RESPONSES_SEARCH: + return { ...state, hiringResponses: action.hiringResponses }; + + case Action.UPDATE_OWNERS_COVERAGE_SEARCH: + return { ...state, ownersCoverage: action.ownersCoverage }; + + case Action.UPDATE_USERS_SEARCH: + return { ...state, users: action.users }; + + case Action.UPDATE_ROLES_SEARCH: + return { ...state, roles: action.roles }; + + case Action.UPDATE_AIT_SEARCH: + return { ...state, aitResponses: action.aitResponses }; + default: + return state; + } +} diff --git a/client2/src/js/reducers/ui.js b/client2/src/js/reducers/ui.js new file mode 100644 index 000000000..02ebea02b --- /dev/null +++ b/client2/src/js/reducers/ui.js @@ -0,0 +1,149 @@ +import * as Action from "../actionTypes"; + +const DEFAULT_STATE = { + requests: { + waiting: false, + error: null, // ApiError + }, + + equipmentList: {}, + equipmentPhysicalAttachments: {}, + owners: {}, + ownerContacts: {}, + ownerEquipment: {}, + users: {}, + userRoles: {}, + projects: {}, + projectContacts: {}, + rentalRequests: {}, + timeEntries: {}, + hiringResponses: {}, + ownersCoverage: {}, + aitResponses: {}, + roles: {}, + history: {}, + documents: {}, + showSessionTimeoutDialog: false, + districtEquipment: {}, + appError: null, + showErrorDialog: false, + activeRentalAgreementId: null, + activeProjectId: null, + activeRentalRequestId: null, + activeOwnerId: null, + activeEquipmentId: null, +}; + +export default function uiReducer(state = DEFAULT_STATE, action) { + switch (action.type) { + // Requests + + case Action.REQUESTS_BEGIN: + return { ...state, requests: { ...state.requests, waiting: true } }; + + case Action.REQUESTS_END: + return { ...state, requests: { ...state.requests, waiting: false } }; + + case Action.REQUESTS_ERROR: + return { + ...state, + requests: { ...state.requests, error: action.error }, + showErrorDialog: true, + }; + + // Screens + + case Action.UPDATE_EQUIPMENT_LIST_UI: + return { ...state, equipmentList: action.equipmentList }; + + case Action.UPDATE_PHYSICAL_ATTACHMENTS_UI: + return { + ...state, + equipmentPhysicalAttachments: action.equipmentPhysicalAttachments, + }; + + case Action.UPDATE_OWNERS_UI: + return { ...state, owners: action.owners }; + + case Action.UPDATE_USERS_UI: + return { ...state, users: action.users }; + + case Action.UPDATE_USER_ROLES_UI: + return { ...state, userRoles: action.userRoles }; + + case Action.UPDATE_OWNER_CONTACTS_UI: + return { ...state, ownerContacts: action.ownerContacts }; + + case Action.UPDATE_OWNER_EQUIPMENT_UI: + return { ...state, ownerEquipment: action.ownerEquipment }; + + case Action.UPDATE_PROJECTS_UI: + return { ...state, projects: action.projects }; + + case Action.UPDATE_PROJECT_CONTACTS_UI: + return { ...state, projectContacts: action.projectContacts }; + + case Action.UPDATE_RENTAL_REQUESTS_UI: + return { ...state, rentalRequests: action.rentalRequests }; + + case Action.UPDATE_TIME_ENTRIES_UI: + return { ...state, timeEntries: action.timeEntries }; + + case Action.UPDATE_HIRING_RESPONSES_UI: + return { ...state, hiringResponses: action.hiringResponses }; + + case Action.UPDATE_OWNERS_COVERAGE_UI: + return { ...state, ownersCoverage: action.ownersCoverage }; + + case Action.UPDATE_ROLES_UI: + return { ...state, roles: action.roles }; + + case Action.UPDATE_HISTORY_UI: + return { ...state, history: action.history }; + + case Action.UPDATE_DOCUMENTS_UI: + return { ...state, documents: action.documents }; + + case Action.UPDATE_DISTRICT_EQUIPMENT_UI: + return { ...state, districtEquipment: action.districtEquipment }; + + case Action.SET_ACTIVE_RENTAL_AGREEMENT_ID_UI: + return { ...state, activeRentalAgreementId: action.rentalAgreementId }; + + case Action.SET_ACTIVE_PROJECT_ID_UI: + return { ...state, activeProjectId: action.projectId }; + + case Action.SET_ACTIVE_RENTAL_REQUEST_ID_UI: + return { ...state, activeRentalRequestId: action.rentalRequestId }; + + case Action.SET_ACTIVE_OWNER_ID_UI: + return { ...state, activeOwnerId: action.ownerId }; + + case Action.SET_ACTIVE_EQUIPMENT_ID_UI: + return { ...state, activeEquipmentId: action.equipmentId }; + + case Action.UPDATE_AIT_REPORT_UI: + return { ...state, aitResponses: action.aitResponses }; + + // case Action.GENERATE_ANOTHER_RENTAL_AGREEMENT: + // return { ...state, activeRentalAgreementId: action.rentalAgreement.id }; + + // Modals + + case Action.SHOW_SESSION_TIMEOUT_DIALOG: + return { ...state, showSessionTimeoutDialog: true }; + + case Action.CLOSE_SESSION_TIMEOUT_DIALOG: + return { ...state, showSessionTimeoutDialog: false }; + + case Action.SHOW_ERROR_DIALOG: + return { ...state, appError: { ...action }, showErrorDialog: true }; + + case Action.CLOSE_ERROR_DIALOG: + return { ...state, showErrorDialog: false }; + default: + return state; + } +} + +export const uiSelector = (state) => state.ui; diff --git a/client2/src/js/reducers/user.js b/client2/src/js/reducers/user.js new file mode 100644 index 000000000..4c144be00 --- /dev/null +++ b/client2/src/js/reducers/user.js @@ -0,0 +1,17 @@ +import * as Action from "../actionTypes"; + +const DEFAULT_USER = { + firstName: null, + lastName: null, + fullName: null, + districtName: null, +}; + +export default function userReducer(state = DEFAULT_USER, action) { + switch (action.type) { + case Action.UPDATE_CURRENT_USER: + return { ...state, ...action.user }; + default: + return state; + } +} diff --git a/client2/src/js/reducers/version.js b/client2/src/js/reducers/version.js new file mode 100644 index 000000000..eb910c163 --- /dev/null +++ b/client2/src/js/reducers/version.js @@ -0,0 +1,15 @@ +import * as Action from "../actionTypes"; + +const DEFAULT_VERSION = { + applicationVersions: [{}], + databaseVersions: [{}], +}; + +export default function versionReducer(state = DEFAULT_VERSION, action) { + switch (action.type) { + case Action.UPDATE_VERSION: + return { ...state, ...action.version }; + default: + return state; + } +} diff --git a/client2/src/js/selectors/history-selectors.js b/client2/src/js/selectors/history-selectors.js new file mode 100644 index 000000000..6571ef3d4 --- /dev/null +++ b/client2/src/js/selectors/history-selectors.js @@ -0,0 +1,37 @@ +import { createSelector } from 'reselect'; + +import * as Constant from '../constants'; + +import { modelsSelector } from '../reducers/models'; + +import { activeEquipmentIdSelector, activeOwnerIdSelector, activeProjectIdSelector, activeRentalRequestIdSelector } from './ui-selectors'; + +const getHistoryType = (state, props) => { + return props.historyEntity.type; +}; + +export const makeGetHistorySelector = () => { + return createSelector( + [ modelsSelector, + getHistoryType, + activeEquipmentIdSelector, + activeOwnerIdSelector, + activeProjectIdSelector, + activeRentalRequestIdSelector, + ], + (models, historyType, activeEquipmentId, activeOwnerId, activeProjectId, activeRentalRequestId) => { + switch (historyType) { + case Constant.HISTORY_EQUIPMENT: + return models.history.equipment[activeEquipmentId]; + case Constant.HISTORY_OWNER: + return models.history.owner[activeOwnerId]; + case Constant.HISTORY_PROJECT: + return models.history.project[activeProjectId]; + case Constant.HISTORY_REQUEST: + return models.history.rentalRequest[activeRentalRequestId]; + default: + return null; + } + } + ); +}; diff --git a/client2/src/js/selectors/ui-selectors.js b/client2/src/js/selectors/ui-selectors.js new file mode 100644 index 000000000..4804c403b --- /dev/null +++ b/client2/src/js/selectors/ui-selectors.js @@ -0,0 +1,64 @@ +import { createSelector } from 'reselect'; + +import { uiSelector } from '../reducers/ui'; +import { modelsSelector } from '../reducers/models'; + + +export const activeRentalAgreementIdSelector = createSelector( + uiSelector, + (ui) => parseInt(ui.activeRentalAgreementId, 10) +); + +export const activeRentalAgreementSelector = createSelector( + activeRentalAgreementIdSelector, + modelsSelector, + (activeRentalAgreementId, models) => models.rentalAgreement[activeRentalAgreementId] || null +); + + +export const activeProjectIdSelector = createSelector( + uiSelector, + (ui) => parseInt(ui.activeProjectId, 10) +); + +export const activeProjectSelector = createSelector( + activeProjectIdSelector, + modelsSelector, + (activeProjectId, models) => models.project[activeProjectId] || null +); + + +export const activeRentalRequestIdSelector = createSelector( + uiSelector, + (ui) => parseInt(ui.activeRentalRequestId, 10) +); + +export const activeRentalRequestSelector = createSelector( + activeRentalRequestIdSelector, + modelsSelector, + (activeRentalRequestId, models) => models.rentalRequest[activeRentalRequestId] || null +); + + +export const activeOwnerIdSelector = createSelector( + uiSelector, + (ui) => parseInt(ui.activeOwnerId, 10) +); + +export const activeOwnerSelector = createSelector( + activeOwnerIdSelector, + modelsSelector, + (activeOwnerId, models) => models.owner[activeOwnerId] || null +); + + +export const activeEquipmentIdSelector = createSelector( + uiSelector, + (ui) => parseInt(ui.activeEquipmentId, 10) +); + +export const activeEquipmentSelector = createSelector( + activeEquipmentIdSelector, + modelsSelector, + (activeEquipmentId, models) => models.equipment[activeEquipmentId] || null +); diff --git a/client2/src/js/store.js b/client2/src/js/store.js new file mode 100644 index 000000000..122771de4 --- /dev/null +++ b/client2/src/js/store.js @@ -0,0 +1,35 @@ +import { createStore, applyMiddleware, compose } from "redux"; +import thunk from "redux-thunk"; + +import allReducers from "./reducers/all"; + +const composeEnhancers = + typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ + ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ + // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... + }) + : compose; + +const middleware = [thunk]; + +if (process.env.NODE_ENV !== "production") { + // Only add this redux store mutation detection middleware in dev + const freeze = require("redux-freeze"); + middleware.push(freeze); +} + +// Note passing middleware as the last argument to createStore requires redux@>=3.1.0 +const store = createStore( + allReducers, + composeEnhancers(applyMiddleware(...middleware)) +); + +if (process.env.NODE_ENV !== "production") { + if (module.hot) { + module.hot.accept("./reducers/all", () => + store.replaceReducer(require("./reducers/all").default) + ); + } +} + +export default store; diff --git a/client2/src/js/utils/array.js b/client2/src/js/utils/array.js new file mode 100644 index 000000000..fe8730797 --- /dev/null +++ b/client2/src/js/utils/array.js @@ -0,0 +1,35 @@ +import _ from 'lodash'; + + +export function sort(arr, keys, dir, sortCompareFn) { + const flatKeys = Array.isArray(keys) ? _.flatten(keys) : [keys]; + + const comparators = flatKeys.map((key) => { + return (item) => { + const val = _.get(item, key); + return sortCompareFn ? sortCompareFn(val, item, key) : val; + }; + }); + const sortDirection = typeof dir === 'boolean' ? sortDir(dir) : dir; + return _.orderBy(arr, comparators, _.fill(Array(comparators.length), sortDirection || 'asc')); +} + +export function caseInsensitiveSort(val/* , item, key */) { + if (typeof val === 'string') { + return val.toLowerCase(); + } + return val; +} + +export function sortDir(isDescending) { + return isDescending ? 'desc' : 'asc'; +} + +export function findAndUpdate(arr, obj, key = 'id') { + const val = obj[key]; + const pos = _.findIndex(arr, (item) => item[key] === val); + if (pos !== -1) { + arr[pos] = { ...arr[pos], ...obj }; + } + return arr; +} diff --git a/client2/src/js/utils/date.js b/client2/src/js/utils/date.js new file mode 100644 index 000000000..fee7e4dbc --- /dev/null +++ b/client2/src/js/utils/date.js @@ -0,0 +1,169 @@ +import Moment from "moment"; + +import * as Constant from "../constants"; + +export function dateIsBetween(date, startDate, endDate) { + if (startDate && date.isBefore(startDate)) { + return false; + } + if (endDate && date.isAfter(endDate)) { + return false; + } + return true; +} + +export function formatDateTime(dateTime, format) { + if (!dateTime) { + return ""; + } + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return ""; + } + if (!format) { + format = Constant.DATE_TIME_ISO_8601; + } + return dt.format(format); +} + +export function formatDateTimeUTCToLocal(dateTime, format) { + if (!dateTime) { + return ""; + } + var dt = Moment.utc(dateTime).local(); + if (!dt || !dt.isValid()) { + return ""; + } + if (!format) { + format = Constant.DATE_TIME_ISO_8601; + } + return dt.format(format); +} + +export function sortableDateTime(dateTime) { + if (!dateTime) { + return 0; + } + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return 0; + } + return dt.unix(); +} + +export function daysFromToday(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return 0; + } + var today = Moment.utc().startOf("d"); + return dt.startOf("d").diff(today, "d"); +} + +export function daysAgo(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return 0; + } + var today = Moment().startOf("d"); + return today.diff(dt.startOf("d"), "d"); +} + +export function hoursAgo(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return 0; + } + var now = Moment(); + return now.diff(dt, "h"); +} + +export function today(format) { + if (!format) { + format = Constant.DATE_TIME_ISO_8601; + } + var dt = Moment.utc().startOf("d"); + return dt.format(format); +} + +export function businessDayOnOrBefore(dateTime, format) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return ""; + } + if (dt.day() === 6) { + // Saturday + dt.subtract(1, "d"); + } else if (dt.day() === 0) { + // Sunday + dt.subtract(2, "d"); + } + // TODO: Holidays + if (!format) { + format = Constant.DATE_TIME_ISO_8601; + } + return dt.format(format); +} + +export function isValidDate(dateTime) { + var dt = Moment.utc(dateTime); + return dt && dt.isValid(); +} + +export function toZuluTime(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return ""; + } + return dt.utc().format(Constant.DATE_ZULU); +} + +export function startOfCurrentFiscal(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return ""; + } + // January-March + if (dt.quarter() === 1) { + dt.subtract(1, "year"); + } + return dt.month("April").startOf("month"); +} + +export function endOfCurrentFiscal(dateTime) { + var dt = Moment.utc(dateTime); + if (!dt || !dt.isValid()) { + return ""; + } + // April-December + if (dt.quarter() > 1) { + dt.add(1, "year"); + } + return dt.month("March").endOf("month"); +} + +export function startOfPreviousFiscal(dateTime) { + var fiscalStart = Moment.utc(startOfCurrentFiscal(dateTime)); + if (!fiscalStart || !fiscalStart.isValid()) { + return ""; + } + return fiscalStart.subtract(1, "year").month("April").startOf("month"); +} + +export function endOfPreviousFiscal(dateTime) { + var fiscalEnd = Moment.utc(endOfCurrentFiscal(dateTime)); + if (!fiscalEnd || !fiscalEnd.isValid()) { + return ""; + } + return fiscalEnd.subtract(1, "year").month("March").endOf("month"); +} + +export function isValidYear(year) { + let currentYear = new Date().getFullYear(); + return ( + year.length === 4 && + year.match(/\d{4}/) && + parseInt(year, 10) <= currentYear + 1 && + parseInt(year, 10) >= 1900 + ); +} diff --git a/client2/src/js/utils/http.js b/client2/src/js/utils/http.js new file mode 100644 index 000000000..0fb7a8e25 --- /dev/null +++ b/client2/src/js/utils/http.js @@ -0,0 +1,301 @@ +import _ from "lodash"; +// import Promise from "bluebird"; + +import * as Action from "../actionTypes"; +import store from "../store"; + +import * as Constant from "../constants"; + +import { resetSessionTimeoutTimer } from "../App.jsx"; + +const ROOT_API_PREFIX = + window.location.pathname === "/" + ? "" + : window.location.pathname.split("/").slice(0, -1).join("/"); + +var numRequestsInFlight = 0; + +function incrementRequests() { + numRequestsInFlight += 1; + if (numRequestsInFlight === 1) { + store.dispatch({ type: Action.REQUESTS_BEGIN }); + } +} + +function decrementRequests() { + numRequestsInFlight -= 1; + if (numRequestsInFlight <= 0) { + numRequestsInFlight = 0; // sanity check; + store.dispatch({ type: Action.REQUESTS_END }); + } +} + +export const HttpError = function (msg, method, path, status, body) { + this.message = msg || ""; + this.method = method; + this.path = path; + this.status = status || null; + this.body = body; +}; + +HttpError.prototype = Object.create(Error.prototype, { + constructor: { value: HttpError }, +}); + +export const ApiError = function ( + msg, + method, + path, + status, + errorCode, + errorDescription, + json +) { + this.message = msg || ""; + this.method = method; + this.path = path; + this.status = status || null; + this.errorCode = errorCode || null; + this.errorDescription = errorDescription || null; + this.json = json || null; +}; + +ApiError.prototype = Object.create(Error.prototype, { + constructor: { value: ApiError }, +}); + +export const Resource404 = function (name, id) { + this.name = name; + this.id = id; +}; + +Resource404.prototype = Object.create(Error.prototype, { + constructor: { value: Resource404 }, + toString: { + value() { + return `Resouce ${this.name} #${this.id} Not Found`; + }, + }, +}); + +export function request(path, options) { + options = options || {}; + + var xhr = new XMLHttpRequest(); + + // calling server service + // console.log('Calling service. Path: ' + path); + + if (!options.headers) { + options.headers = {}; + } + + if (!options.files) { + options.headers = Object.assign( + { + "Content-Type": "application/x-www-form-urlencoded", + }, + options.headers + ); + } + + var method = (options.method || "GET").toUpperCase(); + + if (options.onUploadProgress) { + xhr.upload.addEventListener("progress", function (e) { + if (e.lengthComputable) { + options.onUploadProgress((e.loaded / e.total) * 100); + } else { + options.onUploadProgress(null); + } + }); + + xhr.upload.addEventListener("load", function (/*e*/) { + options.onUploadProgress(100); + }); + } + + if (options.responseType && window.navigator.appName !== "Netscape") { + xhr.responseType = options.responseType; + } else if (options.responseType && window.navigator.appName === "Netscape") { + xhr.open(options.method, path); + xhr.responseType = options.responseType; + } + + return new Promise((resolve, reject) => { + xhr.addEventListener("load", function () { + if (xhr.status >= 400) { + var responseText = ""; + try { + responseText = xhr.responseText; + } catch (e) { + /* swallow */ + } + + var err = new HttpError( + `API ${method} ${path} failed (${xhr.status}) "${responseText}"`, + method, + path, + xhr.status, + responseText + ); + reject(err); + } else { + // console.log('Call complete! Path: ' + path); + resolve(xhr); + } + }); + + xhr.addEventListener("error", function () { + reject( + new HttpError(`Request ${method} ${path} failed to send`, method, path) + ); + }); + + var qs = _.map( + options.querystring, + (value, key) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}` + ).join("&"); + xhr.open(method, `${path}${qs ? "?" : ""}${qs}`, true); + + Object.keys(options.headers).forEach((key) => { + xhr.setRequestHeader(key, options.headers[key]); + }); + + if (!options.silent) { + incrementRequests(); + } + + var payload = options.body || null; + + if (options.files) { + payload = new FormData(); + if (typeof options.body === "object") { + Object.keys(options.body).forEach((key) => { + payload.append(key, options.body[key]); + }); + } + options.files.forEach((file) => { + payload.append("files", file, file.name); + }); + } + + xhr.send(payload); + }).finally(() => { + if (!options.silent) { + decrementRequests(); + } + }); +} + +export function jsonRequest(path, options) { + if (!options.keepAlive) { + resetSessionTimeoutTimer(); + } + + var jsonHeaders = { + Accept: "application/json", + }; + + if (options.body) { + options.body = JSON.stringify(options.body); + jsonHeaders["Content-Type"] = "application/json"; + } + + options.headers = Object.assign(options.headers || {}, jsonHeaders); + + return request(path, options) + .then((xhr) => { + if (xhr.status === 204) { + return; + } else if (xhr.responseType === Constant.RESPONSE_TYPE_BLOB) { + return xhr.response; + } else if (options.ignoreResponse) { + return null; + } else { + return xhr.responseText ? JSON.parse(xhr.responseText) : null; + } + }) + .catch((err) => { + if (err instanceof HttpError) { + var errMsg = `API ${err.method} ${err.path} failed (${err.status})`; + var json = null; + var errorCode = null; + var errorDescription = null; + try { + // Example error payload from server: + // { + // "responseStatus": "ERROR", + // "data": null, + // "error": { + // "error": "HETS-01", + // "description": "Record not found" + // } + // } + + json = JSON.parse(err.body); + errorCode = json.error.error; + errorDescription = json.error.description; + } catch (err) { + /* not json */ + } + + throw new ApiError( + errMsg, + err.method, + err.path, + err.status, + errorCode, + errorDescription, + json + ); + } else { + throw err; + } + }); +} + +export function buildApiPath(path) { + return `${ROOT_API_PREFIX}/api/${path}`.replace("//", "/"); // remove double slashes +} + +export function ApiRequest(path, options) { + this.path = buildApiPath(path); + this.options = options; +} + +ApiRequest.prototype.get = function apiGet(params, options) { + return jsonRequest(this.path, { + method: "GET", + querystring: params, + ...this.options, + ...options, + }); +}; + +ApiRequest.prototype.post = function apiPost(data, options) { + return jsonRequest(this.path, { + method: "POST", + body: data, + ...this.options, + ...options, + }); +}; + +ApiRequest.prototype.put = function apiPut(data, options) { + return jsonRequest(this.path, { + method: "PUT", + body: data, + ...this.options, + ...options, + }); +}; + +ApiRequest.prototype.delete = function apiDelete(data, options) { + return jsonRequest(this.path, { + method: "DELETE", + body: data, + ...this.options, + ...options, + }); +}; diff --git a/client2/src/js/utils/routes.js b/client2/src/js/utils/routes.js new file mode 100644 index 000000000..1d7f480f1 --- /dev/null +++ b/client2/src/js/utils/routes.js @@ -0,0 +1,11 @@ +import { hashHistory } from 'react-router'; + +export function currentPathStartsWith(path) { + if (path.charAt(0) !== '/') { + path = '/' + path; + } + + var currentPath = hashHistory.getCurrentLocation().pathname; + + return currentPath.indexOf(path) === 0; +} diff --git a/client2/src/js/utils/string.js b/client2/src/js/utils/string.js new file mode 100644 index 000000000..e94afd592 --- /dev/null +++ b/client2/src/js/utils/string.js @@ -0,0 +1,109 @@ +import * as Constant from "../constants"; + +function toString(str) { + if (str === null || str === undefined) { + return ""; + } + return String(str); +} + +export function dasherize(str) { + return toString(str) + .trim() + .replace(/([A-Z])/g, "-$1") + .replace(/[-_\s]+/g, "-") + .toLowerCase(); +} + +export function titleCase(str) { + return toString(str).replace(/\b\w/g, (l) => l.toUpperCase()); +} + +export function plural(num, singular, plural) { + return num === 1 ? singular : plural; +} + +export function concat(left, right, sep) { + if (!sep) { + sep = " "; + } + var a = toString(left).trim(); + var b = toString(right).trim(); + if (a && b) { + return `${a}${sep}${b}`; + } + if (a) { + return a; + } + if (b) { + return b; + } + return ""; +} + +export function firstLastName(first, last) { + return concat(first, last); +} + +export function lastFirstName(last, first) { + return concat(last, first, ", "); +} + +export function isBlank(str) { + return toString(str).trim().length === 0; +} + +export function isBlankOrZero(str) { + return toString(str).trim() === 0; +} + +export function notBlank(str) { + return !isBlank(str); +} + +export function padLeft(str, padChar, len) { + if (!str || !padChar || !len) { + return ""; + } + if (str.length >= len) { + return str; + } + var pad = Array(len + 1).join(padChar); + return pad.substring(str.length) + str; +} + +export function formatPhoneNumber(str) { + var phoneNumber = toString(str); + var match = phoneNumber.match(Constant.NANP_REGEX); + if (match) { + match.shift(); + + var extension = match.pop(); + var number = match + .filter((x) => { + return x; + }) + .join("-"); + return extension ? number + "x" + extension : number; + } + return phoneNumber; +} + +export function onlyLetters(str) { + var a = toString(str).trim(); + return /^[a-zA-Z]+$/.test(a); +} + +export function formatCurrency(number) { + if (number === null || number === undefined) { + return ""; + } + return new Intl.NumberFormat("en-CA", { + style: "currency", + currency: "CAD", + }).format(number); +} + +export function formatHours(number) { + return (number || 0).toFixed(2); +} diff --git a/client2/src/js/utils/string_test.js b/client2/src/js/utils/string_test.js new file mode 100644 index 000000000..d767adc10 --- /dev/null +++ b/client2/src/js/utils/string_test.js @@ -0,0 +1,25 @@ +/*global describe, it */ +/*eslint-env node*/ + +// Import currently not working - update needed in pipeline + +var assert = require('assert'); +import { dasherize, plural } from './string'; + +describe('String Utils', function() { + 'use strict'; + + describe('#dasherize()', function () { + it('should dasherize', function () { + assert.equal(dasherize('fooBarBaz'), 'foo-bar-baz'); + }); + }); + + describe('#plural()', function () { + it('should pluralize', function () { + assert.equal(plural(0, 'cat', 'cats'), 'cats'); + assert.equal(plural(1, 'cat', 'cats'), 'cat'); + assert.equal(plural(2, 'cat', 'cats'), 'cats'); + }); + }); +}); diff --git a/client2/src/js/views/404.jsx b/client2/src/js/views/404.jsx new file mode 100644 index 000000000..e95de9e6a --- /dev/null +++ b/client2/src/js/views/404.jsx @@ -0,0 +1,26 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +class Main extends React.Component { + static propTypes = { + location: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + path: props.location.pathname, + }; + } + + render() { + return
+

Not found :(

+ +

Sorry, but the page you were trying to view ({this.state.path}) does not exist. You can try going to the home page.

+
; + } +} + +export default Main; diff --git a/client2/src/js/views/AitReport.jsx b/client2/src/js/views/AitReport.jsx new file mode 100644 index 000000000..ac134b656 --- /dev/null +++ b/client2/src/js/views/AitReport.jsx @@ -0,0 +1,552 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Link } from "react-router"; +import { + Alert, + Row, + Col, + ButtonToolbar, + Button, + ButtonGroup, + Form, +} from "react-bootstrap"; +import _ from "lodash"; +import Moment from "moment"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import store from "../store"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import DateControl from "../components/DateControl.jsx"; +import DropdownControl from "../components/DropdownControl.jsx"; +import Favourites from "../components/Favourites.jsx"; +import FormInputControl from "../components/FormInputControl.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; +import PrintButton from "../components/PrintButton.jsx"; +import SortTable from "../components/SortTable.jsx"; +import Spinner from "../components/Spinner.jsx"; + +import { + formatDateTime, + startOfCurrentFiscal, + endOfCurrentFiscal, + startOfPreviousFiscal, + endOfPreviousFiscal, + toZuluTime, + dateIsBetween, +} from "../utils/date"; + +const THIS_FISCAL = "This Fiscal"; +const LAST_FISCAL = "Last Fiscal"; +const CUSTOM = "Custom"; + +class AitReport extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + agreementSummaryLite: PropTypes.object, + projects: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + equipment: PropTypes.object, + aitResponses: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + var today = Moment(); + + this.state = { + search: { + projectIds: props.search.projectIds || [], + districtEquipmentTypes: props.search.districtEquipmentTypes || [], + equipmentIds: props.search.equipmentIds || [], + rentalAgreementNumber: props.search.rentalAgreementNumber || "", + dateRange: props.search.dateRange || THIS_FISCAL, + startDate: + props.search.startDate || + startOfCurrentFiscal(today).format("YYYY-MM-DD"), + endDate: + props.search.endDate || + endOfCurrentFiscal(today).format("YYYY-MM-DD"), + }, + ui: { + sortField: props.ui.sortField || "rentalAgreementNumber", + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = { + rentalAgreementNumber: this.state.search.rentalAgreementNumber || "", + }; + + if (this.state.search.projectIds.length > 0) { + searchParams.projects = this.state.search.projectIds; + } + + if (this.state.search.districtEquipmentTypes.length > 0) { + searchParams.districtEquipmentTypes = + this.state.search.districtEquipmentTypes; + } + + if (this.state.search.equipmentIds.length > 0) { + searchParams.equipment = this.state.search.equipmentIds; + } + + var startDate = Moment(this.state.search.startDate); + var endDate = Moment(this.state.search.endDate); + + if (startDate && startDate.isValid()) { + searchParams.startDate = toZuluTime(startDate.startOf("day")); + } + + if (endDate && endDate.isValid()) { + searchParams.endDate = toZuluTime(endDate.startOf("day")); + } + return searchParams; + }; + + componentDidMount() { + Api.getRentalAgreementSummaryLite(); + Api.getProjectsAgreementSummary(); + Api.getDistrictEquipmentTypesAgreementSummary(); + Api.getEquipmentAgreementSummary(); + + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, (f) => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchAitReport(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var today = Moment(); + + var defaultSearchParameters = { + projectIds: [], + districtEquipmentTypes: [], + equipmentIds: [], + rentalAgreementNumber: "", + dateRange: THIS_FISCAL, + startDate: startOfCurrentFiscal(today).format("YYYY-MM-DD"), + endDate: endOfCurrentFiscal(today).format("YYYY-MM-DD"), + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ + type: Action.UPDATE_AIT_SEARCH, + aitResponses: this.state.search, + }); + store.dispatch({ type: Action.CLEAR_AIT_REPORT }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState( + { search: { ...this.state.search, ...state, ...{ loaded: true } } }, + () => { + store.dispatch({ + type: Action.UPDATE_AIT_SEARCH, + aitResponses: this.state.search, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_AIT_REPORT_UI, + aitResponses: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + print = () => { + window.print(); + }; + + renderResults = () => { + if (Object.keys(this.props.aitResponses.data).length === 0) { + return No results; + } + + var aitResponses = _.sortBy(this.props.aitResponses.data, (response) => { + var sortValue = response[this.state.ui.sortField]; + if (typeof sortValue === "string") { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.state.ui.sortDesc) { + _.reverse(aitResponses); + } + + return ( + + {_.map(aitResponses, (entry) => { + return ( + + + + {entry.rentalAgreementNumber} + + + + + {entry.equipmentCode} + + + {entry.districtEquipmentName} + + + {entry.projectNumber ? entry.projectNumber : "N/A"} + + + {formatDateTime(entry.datedOn, "YYYY-MMM-DD")} + {formatDateTime(entry.startDate, "YYYY-MMM-DD")} + + ); + })} + + ); + }; + + matchesDateFilter = (agreementIds) => { + const startDate = Moment(this.state.search.startDate); + const endDate = Moment(this.state.search.endDate); + + const matchingAgreementIds = _.chain(this.props.agreementSummaryLite.data) + .filter((a) => dateIsBetween(Moment(a.datedOn), startDate, endDate)) + .map("id") + .value(); + + return _.intersection(matchingAgreementIds, agreementIds).length > 0; + }; + + matchesProjectFilter = (projectIds) => { + if (this.state.search.projectIds.length === 0) { + return true; + } + + return _.intersection(this.state.search.projectIds, projectIds).length > 0; + }; + + matchesDistrictEquipmentTypeFilter = (districtEquipmentTypeId) => { + if (this.state.search.districtEquipmentTypes.length === 0) { + return true; + } + + return _.includes( + this.state.search.districtEquipmentTypes, + districtEquipmentTypeId + ); + }; + + updateDateRangeSearchState = (state) => { + var today = Moment(); + var startDate; + var endDate; + + switch (state.dateRange) { + case THIS_FISCAL: + // Fiscal Year: Apr 1 - March 31 + startDate = startOfCurrentFiscal(today); + endDate = endOfCurrentFiscal(today); + break; + case LAST_FISCAL: + // Fiscal Year: Apr 1 - March 31 + startDate = startOfPreviousFiscal(today); + endDate = endOfPreviousFiscal(today); + break; + case CUSTOM: + startDate = today; + endDate = today; + break; + default: + break; + } + + this.updateSearchState( + { + ...state, + startDate: startDate.format("YYYY-MM-DD"), + endDate: endDate.format("YYYY-MM-DD"), + }, + this.filterSelectedProjects + ); + }; + + updateDateSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedProjects); + }; + + updateProjectSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedEquipmentType); + }; + + updateEquipmentTypeSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedEquipment); + }; + + filterSelectedProjects = () => { + var acceptableProjects = _.map(this.getFilteredProjects(), "id"); + var projectIds = _.intersection( + this.state.search.projectIds, + acceptableProjects + ); + this.updateSearchState( + { projectIds: projectIds }, + this.filterSelectedEquipmentType + ); + }; + + filterSelectedEquipmentType = () => { + var acceptableDistrictEquipmentTypes = _.map( + this.getFilteredDistrictEquipmentType(), + "id" + ); + var districtEquipmentTypes = _.intersection( + this.state.search.districtEquipmentTypes, + acceptableDistrictEquipmentTypes + ); + this.updateSearchState( + { districtEquipmentTypes: districtEquipmentTypes }, + this.filterSelectedEquipment + ); + }; + + filterSelectedEquipment = () => { + var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), "id"); + var equipmentIds = _.intersection( + this.state.search.equipmentIds, + acceptableEquipmentIds + ); + this.updateSearchState({ equipmentIds: equipmentIds }); + }; + + getFilteredProjects = () => { + return _.chain(this.props.projects.data) + .filter((x) => this.matchesDateFilter(x.agreementIds)) + .sortBy("name") + .value(); + }; + + getFilteredDistrictEquipmentType = () => { + return _.chain(this.props.districtEquipmentTypes.data) + .filter( + (x) => + this.matchesDateFilter(x.agreementIds) && + this.matchesProjectFilter(x.projectIds) + ) + .sortBy("name") + .value(); + }; + + getFilteredEquipment = () => { + return _.chain(this.props.equipment.data) + .filter( + (x) => + this.matchesDateFilter(x.agreementIds) && + this.matchesProjectFilter(x.projectIds) && + this.matchesDistrictEquipmentTypeFilter(x.districtEquipmentTypeId) + ) + .sortBy("equipmentCode") + .value(); + }; + + render() { + var resultCount = ""; + if (this.props.aitResponses.loaded) { + resultCount = + "(" + Object.keys(this.props.aitResponses.data).length + ")"; + } + + var projects = this.getFilteredProjects(); + var districtEquipmentTypes = this.getFilteredDistrictEquipmentType(); + var equipment = this.getFilteredEquipment(); + + return ( +
+ + Rental Agreement Summary {resultCount} + + + + + +
+ + + + + + + + + + + + + + {(() => { + if (this.state.search.dateRange === CUSTOM) { + return ( + + + + + + + ); + } + })()} + + + + + + + +
+
+ + {(() => { + if (this.props.aitResponses.loading) { + return ( +
+ +
+ ); + } + + if (this.props.aitResponses.loaded) { + return this.renderResults(); + } + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + agreementSummaryLite: state.lookups.agreementSummaryLite, + projects: state.lookups.projectsAgreementSummary, + districtEquipmentTypes: + state.lookups.districtEquipmentTypesAgreementSummary, + equipment: state.lookups.equipment.agreementSummary, + aitResponses: state.models.aitResponses, + favourites: state.models.favourites.aitReport, + search: state.search.aitResponses, + ui: state.ui.aitResponses, + }; +} + +export default connect(mapStateToProps)(AitReport); diff --git a/client2/src/js/views/BusinessOwner.jsx b/client2/src/js/views/BusinessOwner.jsx new file mode 100644 index 000000000..245a99b6f --- /dev/null +++ b/client2/src/js/views/BusinessOwner.jsx @@ -0,0 +1,304 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Well, Row, Col, Alert, Glyphicon, Label } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import Main from './Main.jsx'; +import Spinner from '../components/Spinner.jsx'; +import ColDisplay from '../components/ColDisplay.jsx'; +import SortTable from '../components/SortTable.jsx'; +import ReturnButton from '../components/ReturnButton.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import PrintButton from '../components/PrintButton.jsx'; + +import { formatDateTime } from '../utils/date'; +import { sortDir } from '../utils/array'; +import { activeOwnerSelector } from '../selectors/ui-selectors'; + + +class BusinessOwner extends React.Component { + static propTypes = { + owner: PropTypes.object, + uiEquipment: PropTypes.object, + uiContacts: PropTypes.object, + params: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + + success: false, + + contact: {}, + + status: '', + + // Contacts + uiContacts : { + sortField: props.uiContacts.sortField || 'name', + sortDesc: props.uiContacts.sortDesc === true, + }, + + // Equipment + uiEquipment : { + sortField: props.uiEquipment.sortField || 'equipmentNumber', + sortDesc: props.uiEquipment.sortDesc === true, + }, + }; + } + + componentDidMount() { + const ownerLoaded = Boolean(this.props.owner); + this.setState({ loading: !ownerLoaded, success: ownerLoaded }); + + this.fetch().then(() => { + this.setState({ loading: false }); + }); + } + + componentDidUpdate(prevProps) { + if (this.props.params.ownerId !== prevProps.params.ownerId) { + this.fetch(); + } + } + + fetch = () => { + var {ownerId} = this.props.params; + + return Api.getOwnerForBusiness(ownerId).then(() => { + this.setState({ success: true }); + }).catch(() => { + this.setState({ success: false }); + }); + }; + + updateContactsUIState = (state, callback) => { + this.setState({ uiContacts: { ...this.state.uiContacts, ...state }}, () => { + store.dispatch({ type: Action.UPDATE_OWNER_CONTACTS_UI, ownerContacts: this.state.uiContacts }); + if (callback) { callback(); } + }); + }; + + updateEquipmentUIState = (state, callback) => { + this.setState({ uiEquipment: { ...this.state.uiEquipment, ...state }}, () => { + store.dispatch({ type: Action.UPDATE_OWNER_EQUIPMENT_UI, ownerEquipment: this.state.uiEquipment }); + if (callback) { callback(); } + }); + }; + + render() { + return ( +
+
+ { this.state.loading &&
} + { !this.state.loading && this.state.success && this.renderPage() } + { !this.state.loading && !this.state.success && this.renderError() } +
+
+ ); + } + + renderPage = () => { + var owner = this.props.owner; + + return
+
+ + + + + + +
+ + +
+ +
+ + + + + +
+ + + { owner.organizationName } + + + { owner.fullAddress } + + + { owner.ownerName } + + + { owner.ownerCode } + + + { owner.primaryContactName } + + + { owner.doingBusinessAs } + + + { owner.registeredCompanyNumber } + + + { owner.districtName } + + + { owner.localAreaName } + + + { owner.isMaintenanceContractor ? 'Yes' : 'No' } + + + { owner.meetsResidency ? 'Yes' : 'No' } + + +
+
+ + + + + { owner.workSafeBCPolicyNumber } + + + + { formatDateTime(owner.workSafeBCExpiryDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + + + + + { owner.cglCompanyName } + + + + + { owner.cglPolicyNumber } + + + + + { formatDateTime(owner.cglEndDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + + + + + + + {(() => { + if (!owner.contacts || Object.keys(owner.contacts).length === 0) { return No contacts; } + + var contacts = _.orderBy(owner.contacts, [this.state.uiContacts.sortField], sortDir(this.state.uiContacts.sortDesc)); + + var headers = [ + { field: 'name', title: 'Name' }, + { field: 'phone', title: 'Phone' }, + { field: 'mobilePhoneNumber', title: 'Cell' }, + { field: 'faxPhoneNumber', title: 'Fax' }, + { field: 'emailAddress', title: 'Email' }, + { field: 'role', title: 'Role' }, + ]; + + return + { + _.map(contacts, (contact) => { + return + { contact.isPrimary && } { contact.name } + { contact.phone } + { contact.mobilePhoneNumber } + { contact.faxPhoneNumber } + { contact.emailAddress } + { contact.role } + ; + }) + } + ; + })()} + + + + {(() => { + if (!owner.equipmentList || owner.equipmentList.length === 0) { return No equipment; } + + var equipmentList = _.orderBy(owner.equipmentList, [this.state.uiEquipment.sortField], sortDir(this.state.uiEquipment.sortDesc)); + + var headers = [ + { field: 'equipmentNumber', title: 'ID' }, + { field: 'localArea.name', title: 'Local Area' }, + { field: 'typeName', title: 'Equipment Type' }, + { field: 'details', title: 'Make/Model/Size/Year' }, + { field: 'attachments', title: 'Attachments' }, + { field: 'lastVerifiedDate', title: 'Last Verified' }, + ]; + + return + { + _.map(equipmentList, (equipment) => { + return + { equipment.equipmentCode } + { equipment.localArea.name } + { equipment.typeName } + { equipment.details } + { _.map(equipment.equipmentAttachments, a => a.description).join(', ') } + { equipment.isApproved ? formatDateTime(equipment.lastVerifiedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) : 'Not Approved' } + ; + }) + } + ; + })()} + +
+
; + }; + + renderError = () => { + return
+
+ {(() => { + return + + + +
+ +
+ +
; + })()} + + {(() => { + return
+ + +

This record does not exist or you do not have permission to access it.

+ +
+
; + })()} +
+
; + }; +} + +function mapStateToProps(state) { + return { + owner: activeOwnerSelector(state), + uiEquipment: state.ui.ownerEquipment, + uiContacts: state.ui.ownerContacts, + }; +} + +export default connect(mapStateToProps)(BusinessOwner); diff --git a/client2/src/js/views/BusinessPortal.jsx b/client2/src/js/views/BusinessPortal.jsx new file mode 100644 index 000000000..d3a481655 --- /dev/null +++ b/client2/src/js/views/BusinessPortal.jsx @@ -0,0 +1,221 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Link } from 'react-router'; +import { Well, Row, Col, FormGroup, Alert, Button } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import Main from './Main.jsx'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import Spinner from '../components/Spinner.jsx'; +import ColDisplay from '../components/ColDisplay.jsx'; +import SortTable from '../components/SortTable.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import Form from '../components/Form.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; + + +class BusinessPortal extends React.Component { + static propTypes = { + user: PropTypes.object, + business: PropTypes.object, + uiOwners: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + validating: false, + success: false, + secretKey: '', + postalCode: '', + errors: {}, + + // owners + uiOwners : { + sortField: props.uiOwners.sortField || 'organizationName', + sortDesc: props.uiOwners.sortDesc === true, + }, + }; + } + + componentDidMount() { + const businessLoaded = Boolean(this.props.business); + this.setState({ loading: !businessLoaded, success: businessLoaded }); + + this.fetch().then(() => { + this.setState({ loading: false }); + }); + } + + fetch = () => { + return Api.getBusiness().then(() => { + this.setState({ success: !_.isEmpty(this.props.business) }); + }); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateOwnersUIState = (state, callback) => { + this.setState({ uiOwners: { ...this.state.uiOwners, ...state }}, () => { + store.dispatch({ type: Action.UPDATE_OWNERS_UI, owners: this.state.uiOwners }); + if (callback) { callback(); } + }); + }; + + validateOwner = (e) => { + e.preventDefault(); + + this.setState({ validating: true, errors: {} }); + + Api.validateOwner(this.state.secretKey, this.state.postalCode).then(() => { + // clear input fields + this.inputPostalCode.value = ''; + this.inputSecretKey.value = ''; + }).catch((error) => { + if (error.status === 400 && (error.errorCode === 'HETS-19' || error.errorCode === 'HETS-20' || error.errorCode === 'HETS-21')) { + this.setState({ errors: { secretKey: error.errorDescription } }); + } else if (error.status === 400 && error.errorCode === 'HETS-22') { + this.setState({ errors: { postalCode: error.errorDescription } }); + } else { + throw error; + } + }).finally(() => { + this.setState({ validating: false }); + }); + }; + + render() { + return
+
+ Business Portal + { this.state.loading &&
} + { !this.state.loading && this.state.success && this.renderPage() } + { !this.state.loading && !this.state.success && this.renderError() } +
+
; + } + + renderPage = () => { + var business = this.props.business; + const hasErrors = Object.keys(this.state.errors).length > 0; + + return
+ + + + + { business.bceidLegalName } + + + { business.bceidDoingBusinessAs } + + + + + + {(() => { + if (_.isEmpty(this.props.business.owners)) { return No district owners associated; } + + var owners = _.sortBy(this.props.business.owners, this.state.uiOwners.sortField); + if (this.state.uiOwners.sortDesc) { + _.reverse(owners); + } + + var headers = [ + { field: 'organizationName', title: 'Name' }, + { field: 'primaryContactName', title: 'Primary Contact' }, + { field: 'districtName', title: 'District' }, + { field: 'localAreaName', title: 'Local Area' }, + ]; + + return + { + _.map(owners, (owner) => { + return + {owner.organizationName} + { owner.primaryContactNameBusiness } + { owner.districtNameBusiness } + { owner.localAreaNameBusiness } + ; + }) + } + ; + })()} + + + +
+ + +

+ The Hired Equipment Program is for owners/operators who have a dump truck, bulldozer, backhoe or other piece of equipment they want to hire out to the Ministry Transportation and Infrastructure for day labour and emergency projects. +

+

+ The Hired Equipment Program distributes available work to local equipment owners. The program is based on seniority and is designed to deliver work to registered users fairly and efficiently through the development of local area call-out lists. Details about the Hired Equipment Program can be found here. +

+
+

+ If you are NEW to the Hired Equipment Program, contact your local district office to register your company and equipment. +

+

+ If you are REGISTERED with the Hired Equipment Program and this is your first time to the site, enter your Secret Key and Postal Code to validate your account, then select your account. +

+

+ For RETURNING equipment owners, select your company above to view your account. +

+
+
+ + this.inputSecretKey = input} /> + + + this.inputPostalCode = input} /> + + +
+ { hasErrors &&
Secret key validation failed.
} +
+
; + }; + + renderError = () => { + return

An error was encountered. You may not have permission to access this page.

; + }; +} + +function mapStateToProps(state) { + return { + user: state.user, + business: state.models.business, + uiOwners: state.ui.owners, + }; +} + +export default connect(mapStateToProps)(BusinessPortal); diff --git a/client2/src/js/views/DistrictAdmin.jsx b/client2/src/js/views/DistrictAdmin.jsx new file mode 100644 index 000000000..c61992d20 --- /dev/null +++ b/client2/src/js/views/DistrictAdmin.jsx @@ -0,0 +1,295 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Button, ButtonGroup, Glyphicon, Well, Alert, Row, Col } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../api'; +import * as Constant from '../constants'; +import * as Action from '../actionTypes'; +// import store from '../store'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import ModalDialog from '../components/ModalDialog.jsx'; +import SortTable from '../components/SortTable.jsx'; +import TableControl from '../components/TableControl.jsx'; +import Spinner from '../components/Spinner.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import Confirm from '../components/Confirm.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import ConditionAddEditDialog from './dialogs/ConditionAddEditDialog.jsx'; +import DistrictEquipmentTypeAddEditDialog from './dialogs/DistrictEquipmentTypeAddEditDialog.jsx'; +import EquipmentTransferDialog from './dialogs/EquipmentTransferDialog.jsx'; + +import { caseInsensitiveSort, sort } from '../utils/array'; + + + +class DistrictAdmin extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + rentalConditions: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + equipmentTypes: PropTypes.object, + router: PropTypes.object, + uiEquipment: PropTypes.object, + dispatch: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + showConditionAddEditDialog: false, + showDistrictEquipmentTypeAddEditDialog: false, + showEquipmentTransferDialog: false, + condition: {}, + districtEquipmentType: {}, + + // Equipment + uiEquipment : { + sortField: props.uiEquipment.sortField || 'districtEquipmentName', + sortDesc: props.uiEquipment.sortDesc === true, + }, + }; + } + + componentDidMount() { + Api.getRentalConditions(); + Api.getDistrictEquipmentTypes(); + } + + updateEquipmentUIState = (state, callback) => { + this.setState({ uiEquipment: { ...this.state.uiEquipment, ...state }}, () => { + this.props.dispatch({ type: Action.UPDATE_DISTRICT_EQUIPMENT_UI, districtEquipment: this.state.uiEquipment }); + if (callback) { callback(); } + }); + }; + + addCondition = () => { + this.setState({ condition: { id: 0 } }, this.showConditionAddEditDialog); + }; + + editCondition = (condition) => { + this.setState({ condition: condition }, this.showConditionAddEditDialog); + }; + + deleteCondition = (condition) => { + Api.deleteCondition(condition.id).then(() => { + Api.getRentalConditions(); + }); + }; + + showConditionAddEditDialog = () => { + this.setState({ showConditionAddEditDialog: true }); + }; + + closeConditionAddEditDialog = () => { + this.setState({ showConditionAddEditDialog: false }); + }; + + showEquipmentTransferDialog = () => { + this.setState({ showEquipmentTransferDialog: true }); + }; + + closeEquipmentTransferDialog = () => { + this.setState({ showEquipmentTransferDialog: false }); + }; + + conditionSaved = () => { + Api.getRentalConditions(); + }; + + showDistrictEquipmentTypeAddEditDialog = () => { + this.setState({ showDistrictEquipmentTypeAddEditDialog: true }); + }; + + closeDistrictEquipmentTypeAddEditDialog = () => { + this.setState({ showDistrictEquipmentTypeAddEditDialog: false }); + }; + + closeDistrictEquipmentTypeErrorDialog = () => { + this.setState({ showDistrictEquipmentTypeErrorDialog: false }); + }; + + addDistrictEquipmentType = () => { + this.setState({ districtEquipmentType: { id: 0 } }, this.showDistrictEquipmentTypeAddEditDialog); + }; + + editDistrictEquipmentType = (equipment) => { + this.setState({ districtEquipmentType: equipment }, this.showDistrictEquipmentTypeAddEditDialog); + }; + + districtEquipmentTypeSaved = () => { + Api.getDistrictEquipmentTypes(); + }; + + deleteDistrictEquipmentType = (equipment) => { + Api.deleteDistrictEquipmentType(equipment).then(() => { + return Api.getDistrictEquipmentTypes(); + }).catch((error) => { + if (error.status === 400 && error.errorCode === 'HETS-37') { + this.setState({ showDistrictEquipmentTypeErrorDialog: true, districtEquipmentTypeError: error.errorDescription }); + } else { + throw error; + } + }); + }; + + render() { + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_DISTRICT_CODE_TABLE_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return ( +
You do not have permission to view this page.
+ ); + } + + return
+ District Admin + + + + {(() => { + if (!this.props.districtEquipmentTypes.loaded) { return
; } + + var addDistrictEquipmentButton = ; + + var equipmentTypes = this.props.districtEquipmentTypes.data; + + if (Object.keys(equipmentTypes).length === 0) { return No equipment types { addDistrictEquipmentButton }; } + + var sortedEquipmentTypes = sort(equipmentTypes, this.state.uiEquipment.sortField, this.state.uiEquipment.sortDesc, caseInsensitiveSort); + + var headers = [ + { field: 'districtEquipmentName', title: 'Equipment Type/Description' }, + { field: 'equipmentType.blueBookSection', title: 'Blue Book Section Number' }, + { field: 'equipmentType.name', title: 'Blue Book Section Name' }, + { field: 'addDistrictEquipmentType', title: 'Add District Equipment Type', style: { textAlign: 'right' }, + node: addDistrictEquipmentButton, + }, + ]; + + return ( + + { + _.map(sortedEquipmentTypes, (equipment) => { + return + { equipment.districtEquipmentName } + { equipment.equipmentType.blueBookSection } + { equipment.equipmentType.name } + + + + }> + + + + + + + ; + }) + } + + ); + })()} +
+ + + + {(() => { + if (this.props.rentalConditions.loading) { return
; } + + var addConditionButton = ; + + if (Object.keys(this.props.rentalConditions.data).length === 0) { return No users { addConditionButton }; } + + return ( + + { + _.map(this.props.rentalConditions.data, (condition) => { + return + { condition.conditionTypeCode } + { condition.description } + + + }> + + + + + + ; + }) + } + + ); + })()} +
+ + + + + Bulk transfer will enable the user to transfer equipment associated with one owner code to another owner code. + + + + + { this.state.showEquipmentTransferDialog && + + } + { this.state.showConditionAddEditDialog && + + } + { this.state.showDistrictEquipmentTypeAddEditDialog && + + } + { this.state.showDistrictEquipmentTypeErrorDialog && + + + + } + > +
{ this.state.districtEquipmentTypeError }
+
+ } +
; + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + rentalConditions: state.lookups.rentalConditions, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + equipmentTypes: state.lookups.equipmentTypes, + uiEquipment: state.ui.districtEquipment, + }; +} + +export default connect(mapStateToProps)(DistrictAdmin); diff --git a/client2/src/js/views/Equipment.jsx b/client2/src/js/views/Equipment.jsx new file mode 100644 index 000000000..0360b49d1 --- /dev/null +++ b/client2/src/js/views/Equipment.jsx @@ -0,0 +1,401 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { + Alert, + Row, + Col, + ButtonToolbar, + Button, + ButtonGroup, + OverlayTrigger, + Tooltip, +} from "react-bootstrap"; +import _ from "lodash"; +import Moment from "moment"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import store from "../store"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import CheckboxControl from "../components/CheckboxControl.jsx"; +import DateControl from "../components/DateControl.jsx"; +import DropdownControl from "../components/DropdownControl.jsx"; +import Favourites from "../components/Favourites.jsx"; +import FormInputControl from "../components/FormInputControl.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; +import Spinner from "../components/Spinner.jsx"; +import Form from "../components/Form.jsx"; +import EquipmentTable from "./EquipmentTable.jsx"; +import PrintButton from "../components/PrintButton.jsx"; + +import { toZuluTime } from "../utils/date"; + +class Equipment extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + equipmentList: PropTypes.object, + localAreas: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + owners: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showAddDialog: false, + search: { + selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], + selectedEquipmentTypesIds: props.search.selectedEquipmentTypesIds || [], + equipmentAttachment: props.search.equipmentAttachment || "", + ownerName: props.search.ownerName || "", + lastVerifiedDate: props.search.lastVerifiedDate || "", + hired: props.search.hired || false, + twentyYears: props.search.twentyYears || false, + statusCode: + props.search.statusCode || Constant.EQUIPMENT_STATUS_CODE_APPROVED, + equipmentId: props.search.equipmentId || "", + projectName: props.search.projectName || "", + }, + ui: { + sortField: props.ui.sortField || "seniorityText", + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.equipmentAttachment) { + searchParams.equipmentAttachment = this.state.search.equipmentAttachment; + } + + if (this.state.search.ownerName) { + searchParams.ownerName = this.state.search.ownerName; + } + + if (this.state.search.hired) { + searchParams.hired = this.state.search.hired; + } + + if (this.state.search.twentyYears) { + searchParams.twentyYears = this.state.search.twentyYears; + } + + if (this.state.search.statusCode) { + searchParams.status = this.state.search.statusCode; + } + + if (this.state.search.selectedLocalAreasIds.length > 0) { + searchParams.localareas = this.state.search.selectedLocalAreasIds; + } + + if (this.state.search.selectedEquipmentTypesIds.length > 0) { + searchParams.types = this.state.search.selectedEquipmentTypesIds; + } + + if (this.state.search.equipmentId) { + searchParams.equipmentId = this.state.search.equipmentId; + } + + if (this.state.search.projectName) { + searchParams.projectName = this.state.search.projectName; + } + + var notVerifiedSinceDate = Moment(this.state.search.lastVerifiedDate); + if (notVerifiedSinceDate && notVerifiedSinceDate.isValid()) { + searchParams.notverifiedsincedate = toZuluTime( + notVerifiedSinceDate.startOf("day") + ); + } + + return searchParams; + }; + + componentDidMount() { + Api.getDistrictEquipmentTypes(); + + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, (f) => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchEquipmentList(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + selectedLocalAreasIds: [], + selectedEquipmentTypesIds: [], + equipmentAttachment: "", + ownerName: "", + lastVerifiedDate: "", + hired: false, + twentyYears: false, + statusCode: Constant.EQUIPMENT_STATUS_CODE_APPROVED, + equipmentId: "", + projectName: "", + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, + equipmentList: this.state.search, + }); + store.dispatch({ type: Action.CLEAR_EQUIPMENT_LIST }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, + equipmentList: this.state.search, + }); + if (callback) { + callback(); + } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_EQUIPMENT_LIST_UI, + equipmentList: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + renderResults = () => { + if (Object.keys(this.props.equipmentList.data).length === 0) { + return No equipment; + } + + return ( + + ); + }; + + render() { + // Constrain the local area drop downs to those in the District of the current logged in user + var localAreas = _.chain(this.props.localAreas).sortBy("name").value(); + + var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) + .filter((type) => type.district.id === this.props.currentUser.district.id) + .sortBy("districtEquipmentName") + .value(); + + var resultCount = ""; + if (this.props.equipmentList.loaded) { + resultCount = + "(" + Object.keys(this.props.equipmentList.data).length + ")"; + } + + return ( +
+ + Equipment {resultCount} + + + + + +
+ + + + + + + + + + Hired + + + Equipment 20 years or older + + } + > + + 20+ Years + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.equipmentList.loading) { + return ( +
+ +
+ ); + } + + if (this.props.equipmentList.loaded) { + return this.renderResults(); + } + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + equipmentList: state.models.equipmentList, + localAreas: state.lookups.localAreas, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + favourites: state.models.favourites.equipment, + search: state.search.equipmentList, + ui: state.ui.equipmentList, + }; +} + +export default connect(mapStateToProps)(Equipment); diff --git a/client2/src/js/views/EquipmentDetail.jsx b/client2/src/js/views/EquipmentDetail.jsx new file mode 100644 index 000000000..d0c1186c3 --- /dev/null +++ b/client2/src/js/views/EquipmentDetail.jsx @@ -0,0 +1,543 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Link } from 'react-router'; +import { Well, Row, Col } from 'react-bootstrap'; +import { Alert, Button, ButtonGroup, Glyphicon, Label } from 'react-bootstrap'; +import _ from 'lodash'; +import Promise from 'bluebird'; + +import EquipmentEditDialog from './dialogs/EquipmentEditDialog.jsx'; +import SeniorityEditDialog from './dialogs/SeniorityEditDialog.jsx'; +import AttachmentAddDialog from './dialogs/AttachmentAddDialog.jsx'; +import AttachmentEditDialog from './dialogs/AttachmentEditDialog.jsx'; +import DocumentsListDialog from './dialogs/DocumentsListDialog.jsx'; +import NotesDialog from './dialogs/NotesDialog.jsx'; +import EquipmentChangeStatusDialog from './dialogs/EquipmentChangeStatusDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import * as Log from '../history'; +import store from '../store'; + +import BadgeLabel from '../components/BadgeLabel.jsx'; +import ColDisplay from '../components/ColDisplay.jsx'; +import Confirm from '../components/Confirm.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import History from '../components/History.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import StatusDropdown from '../components/StatusDropdown.jsx'; +import ReturnButton from '../components/ReturnButton.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import { activeEquipmentSelector, activeEquipmentIdSelector } from '../selectors/ui-selectors'; + +import { formatDateTime } from '../utils/date'; +import { formatHours } from '../utils/string'; + +/* + +TODO: +* Print / Notes / Docs / History / Actions on Equipment / Seniority Data History / Equipment Attachments + +*/ + +const EQUIPMENT_IN_ACTIVE_RENTAL_REQUEST_WARNING_MESSAGE = 'This equipment is part of an In Progress ' + + 'Rental Request. Release the list (finish hiring / delete) before making this change'; + + +class EquipmentDetail extends React.Component { + static propTypes = { + equipment: PropTypes.object, + equipmentId: PropTypes.number, + notes: PropTypes.array, + attachments: PropTypes.object, + documents: PropTypes.object, + history: PropTypes.object, + params: PropTypes.object, + ui: PropTypes.object, + location: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + loadingDocuments: true, + loadingNotes: true, + reloading: false, + + showEditDialog: false, + showDocumentsDialog: false, + showSeniorityDialog: false, + showPhysicalAttachmentDialog: false, + showPhysicalAttachmentEditDialog: false, + showNotesDialog: false, + showChangeStatusDialog: false, + equipmentPhysicalAttachment: {}, + ui : { + // Physical Attachments + sortField: props.ui.sortField || 'attachmentTypeName', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + componentDidMount() { + const { equipment, equipmentId } = this.props; + // Only show loading spinner if there is no existing equipment in the store + if (equipment) { + this.setState({ loading: false }); + } + + // Notes and documents need be fetched every time as they are not equipment-specific in the store ATM + Api.getEquipmentNotes(equipmentId).then(() => this.setState({ loadingNotes: false })); + Api.getEquipmentDocuments(equipmentId).then(() => this.setState({ loadingDocuments: false })); + + // Re-fetch equipment every time + Promise.all([ + this.fetch(), + ]).then(() => { + this.setState({ loading: false }); + }); + } + + componentDidUpdate(prevProps) { + if (prevProps.params.equipmentId !== this.props.params.equipmentId) { + this.fetch(); + } + } + + fetch = () => { + this.setState({ reloading: true }); + return Api.getEquipment(this.props.equipmentId).then(() => this.setState({ reloading: false })); + }; + + showNotes = () => { + this.setState({ showNotesDialog: true }); + }; + + closeNotesDialog = () => { + this.setState({ showNotesDialog: false }); + }; + + showDocuments = () => { + this.setState({ showDocumentsDialog: true }); + }; + + closeDocumentsDialog = () => { + this.setState({ showDocumentsDialog: false }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ type: Action.UPDATE_PHYSICAL_ATTACHMENTS_UI, equipmentPhysicalAttachments: this.state.ui }); + if (callback) { callback(); } + }); + }; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + updateStatusState = (state) => { + if (state !== this.props.equipment.status) { + this.setState({ status: state }, () => this.openChangeStatusDialog()); + } + }; + + openChangeStatusDialog = () => { + this.setState({ showChangeStatusDialog: true }); + }; + + closeChangeStatusDialog = () => { + this.setState({ showChangeStatusDialog: false }); + }; + + onStatusChanged = () => { + this.closeChangeStatusDialog(); + Api.getEquipmentNotes(this.props.equipment.id); + }; + + openSeniorityDialog = () => { + this.setState({ showSeniorityDialog: true }); + }; + + closeSeniorityDialog = () => { + this.setState({ showSeniorityDialog: false }); + }; + + openPhysicalAttachmentDialog = () => { + this.setState({ + showPhysicalAttachmentDialog: true, + }); + }; + + closePhysicalAttachmentDialog = () => { + this.setState({ showPhysicalAttachmentDialog: false }); + }; + + physicalAttachmentsAdded = () => { + var equipId = this.props.params.equipmentId; + Api.getEquipment(equipId); + }; + + openPhysicalAttachmentEditDialog = (attachment) => { + this.setState({ + equipmentPhysicalAttachment: attachment, + showPhysicalAttachmentEditDialog: true, + }); + }; + + closePhysicalAttachmentEditDialog = () => { + this.setState({ showPhysicalAttachmentEditDialog: false }); + }; + + physicalAttachmentEdited = () => { + var equipId = this.props.params.equipmentId; + Api.getEquipment(equipId); + }; + + deletePhysicalAttachment = (attachmentId) => { + Api.deletePhysicalAttachment(attachmentId).then(() => { + let attachment = _.find(this.props.equipment.equipmentAttachments, ((attachment) => attachment.id === attachmentId )); + Log.equipmentAttachmentDeleted(this.props.equipment, attachment.typeName); + var equipId = this.props.params.equipmentId; + Api.getEquipment(equipId); + }); + }; + + getLastVerifiedStyle = (equipment) => { + var daysSinceVerified = equipment.daysSinceVerified; + if (daysSinceVerified >= Constant.EQUIPMENT_DAYS_SINCE_VERIFIED_CRITICAL) { return 'danger'; } + if (daysSinceVerified >= Constant.EQUIPMENT_DAYS_SINCE_VERIFIED_WARNING) { return 'warning'; } + return 'success'; + }; + + getStatuses = () => { + var dropdownItems = _.pull([ + Constant.EQUIPMENT_STATUS_CODE_APPROVED, + Constant.EQUIPMENT_STATUS_CODE_PENDING, + Constant.EQUIPMENT_STATUS_CODE_ARCHIVED, + ], this.props.equipment.status); + if (this.props.equipment.ownerStatus === Constant.OWNER_STATUS_CODE_PENDING) { + return _.pull(dropdownItems, Constant.EQUIPMENT_STATUS_CODE_APPROVED); + } else if (this.props.equipment.ownerStatus === Constant.OWNER_STATUS_CODE_ARCHIVED) { + return []; + } + return dropdownItems; + }; + + render() { + var equipment = this.props.equipment || {}; + const { loadingNotes, loadingDocuments } = this.state; + + var lastVerifiedStyle = this.getLastVerifiedStyle(equipment); + + return ( +
+
+ {(() => { + if (this.state.loading) { return
; } + + return ( +
+ + + + { this.props.equipment && + + } + + + + + +
+ + +
+ +
+ + + + + +
+ + { equipment.organizationName }}/> +
+ District Office: { equipment.districtName } +
+
+ Service/Local Area: { equipment.localArea && `${ equipment.localArea.serviceAreaId } - ${ equipment.localAreaName }` } +
+
+
+ ); + })()} + + + + + + {(() => { + if (this.state.loading) { return
; } + + return + + { equipment.typeName } + + + { equipment.make } + + + { equipment.model } + + + { equipment.year } + + + { equipment.size } + + { equipment.isDumpTruck && + + { equipment.licencedGvw } + + } + { equipment.isDumpTruck && + + { equipment.legalCapacity } + + } + + { equipment.type } + + + { equipment.licencePlate } + + + + { equipment.serialNumber } + { equipment.hasDuplicates ? ! : null } + + + { equipment.isDumpTruck && + + { equipment.pupLegalCapacity } + + } + ; + })()} +
+ + + + + {(() => { + if (this.state.loading ) { return
; } + if (!equipment.equipmentAttachments || Object.keys(equipment.equipmentAttachments).length === 0) { return No Attachments; } + + var physicalAttachments = _.sortBy(equipment.equipmentAttachments, this.state.ui.sortField); + if (this.state.ui.sortDesc) { + _.reverse(physicalAttachments); + } + + + var headers = [ + { field: 'attachmentTypeName', title: 'Type' }, + { field: 'blank' }, + ]; + + return + { + _.map(physicalAttachments, (attachment) => { + return + { attachment.typeName } + + + + + } + > + + + + + + ; + }) + } + ; + })()} +
+ +
+ + + + + {(() => { + if (this.state.loading) { return
; } + + return + + { equipment.seniorityString } + + + { formatHours(equipment.hoursYtd) } + + + Hours { equipment.yearMinus1 } }>{ formatHours(equipment.serviceHoursLastYear) } + + + Hours { equipment.yearMinus2 } }>{ formatHours(equipment.serviceHoursTwoYearsAgo) } + + + Hours { equipment.yearMinus3 } }>{ formatHours(equipment.serviceHoursThreeYearsAgo) } + + + { equipment.yearsOfService } + + + + { formatDateTime(equipment.receivedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + + + + + { formatDateTime(equipment.approvedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + + + + + { equipment.isSeniorityOverridden ? 'Manually Updated' : 'Not Overriden'} + + + + { equipment.seniorityOverrideReason } + + ; + })()} +
+ + + + + { equipment.historyEntity && } + + +
+
+ { this.state.showChangeStatusDialog && ( + + )} + { this.state.showNotesDialog && ( + + )} + { this.state.showDocumentsDialog && ( + + )} + { this.state.showEditDialog && ( + + )} + { this.state.showSeniorityDialog && ( + + )} + { this.state.showPhysicalAttachmentDialog && ( + + )} + { this.state.showPhysicalAttachmentEditDialog && ( + + )} +
+ ); + } +} + + +function mapStateToProps(state) { + return { + equipment: activeEquipmentSelector(state), + equipmentId: activeEquipmentIdSelector(state), + notes: state.models.equipmentNotes, + attachments: state.models.equipmentAttachments, + documents: state.models.documents, + history: state.models.equipmentHistory, + ui: state.ui.equipmentPhysicalAttachments, + }; +} + +export default connect(mapStateToProps)(EquipmentDetail); diff --git a/client2/src/js/views/EquipmentTable.jsx b/client2/src/js/views/EquipmentTable.jsx new file mode 100644 index 000000000..40e58fd1f --- /dev/null +++ b/client2/src/js/views/EquipmentTable.jsx @@ -0,0 +1,82 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Link } from 'react-router'; +import _ from 'lodash'; +import { Button, Glyphicon } from 'react-bootstrap'; +import { LinkContainer } from 'react-router-bootstrap'; + +import * as Constant from '../constants'; + +import SortTable from '../components/SortTable.jsx'; + +import { formatDateTime } from '../utils/date'; + + +class EquipmentTable extends React.Component { + static propTypes = { + ui: PropTypes.object, + updateUIState: PropTypes.func, + equipmentList: PropTypes.object, + }; + + shouldComponentUpdate(nextProps) { + if (this.props.ui !== nextProps.ui || this.props.equipmentList !== nextProps.equipmentList) { + return true; + } + return false; + } + + render() { + var equipmentList = _.sortBy(this.props.equipmentList, equipment => { + var sortValue = equipment[this.props.ui.sortField]; + if (typeof sortValue === 'string') { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.props.ui.sortDesc) { + _.reverse(equipmentList); + } + + return ( + + { + _.map(equipmentList, (equip) => { + return ( + + { equip.equipmentCode } + { equip.localArea } + { equip.ownerName } + { equip.equipmentType } + { equip.details } + { equip.attachmentCount } + { equip.projectName } + { equip.status } + { formatDateTime(equip.lastVerifiedDate, 'YYYY-MMM-DD') } + + + + + + + ); + }) + } + + ); + } +} + +export default EquipmentTable; diff --git a/client2/src/js/views/Footer.jsx b/client2/src/js/views/Footer.jsx new file mode 100644 index 000000000..b57eaac5c --- /dev/null +++ b/client2/src/js/views/Footer.jsx @@ -0,0 +1,43 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Row } from 'react-bootstrap'; + + +class Footer extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + }; + + render() { + return ; + } +} + + +function mapStateToProps(state) { + return { + currentUser: state.user, + }; +} + +export default connect(mapStateToProps, null, null, { pure:false })(Footer); diff --git a/client2/src/js/views/HiringReport.jsx b/client2/src/js/views/HiringReport.jsx new file mode 100644 index 000000000..051ea0a26 --- /dev/null +++ b/client2/src/js/views/HiringReport.jsx @@ -0,0 +1,430 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Link } from "react-router"; +import { + Alert, + Row, + Col, + ButtonToolbar, + Button, + ButtonGroup, + Form, +} from "react-bootstrap"; +import _ from "lodash"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import store from "../store"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import Favourites from "../components/Favourites.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; +import SortTable from "../components/SortTable.jsx"; +import Spinner from "../components/Spinner.jsx"; +import PrintButton from "../components/PrintButton.jsx"; + +import { formatDateTime } from "../utils/date"; + +class HiringReport extends React.Component { + static propTypes = { + projects: PropTypes.object, + localAreas: PropTypes.object, + owners: PropTypes.object, + equipment: PropTypes.object, + hiringResponses: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + search: { + projectIds: props.search.projectIds || [], + localAreaIds: props.search.localAreaIds || [], + ownerIds: props.search.ownerIds || [], + equipmentIds: props.search.equipmentIds || [], + }, + ui: { + sortField: props.ui.sortField || "name", + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + componentDidMount() { + Api.getProjectsCurrentFiscal(); + Api.getEquipmentHires(); + Api.getOwnersLiteHires(); + + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, (f) => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.projectIds.length > 0) { + searchParams.projects = this.state.search.projectIds; + } + + if (this.state.search.localAreaIds.length > 0) { + searchParams.localAreas = this.state.search.localAreaIds; + } + + if (this.state.search.ownerIds.length > 0) { + searchParams.owners = this.state.search.ownerIds; + } + + if (this.state.search.equipmentIds.length > 0) { + searchParams.equipment = this.state.search.equipmentIds; + } + + return searchParams; + }; + + fetch = () => { + Api.searchHiringReport(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + projectIds: [], + localAreaIds: [], + ownerIds: [], + equipmentIds: [], + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ + type: Action.UPDATE_HIRING_RESPONSES_SEARCH, + hiringResponses: this.state.search, + }); + store.dispatch({ type: Action.CLEAR_HIRING_RESPONSES }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState( + { search: { ...this.state.search, ...state, ...{ loaded: true } } }, + () => { + store.dispatch({ + type: Action.UPDATE_HIRING_RESPONSES_SEARCH, + hiringResponses: this.state.search, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_HIRING_RESPONSES_UI, + hiringResponses: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + renderResults = () => { + if (Object.keys(this.props.hiringResponses.data).length === 0) { + return No results; + } + + var hiringResponses = _.sortBy( + this.props.hiringResponses.data, + (response) => { + var sortValue = response[this.state.ui.sortField]; + if (typeof sortValue === "string") { + return sortValue.toLowerCase(); + } + return sortValue; + } + ); + + if (this.state.ui.sortDesc) { + _.reverse(hiringResponses); + } + + return ( + + {_.map(hiringResponses, (entry) => { + var reason = + entry.reason === Constant.HIRING_REFUSAL_OTHER + ? entry.offerResponseNote + : entry.reason; + + return ( + + {entry.localAreaLabel} + {entry.ownerCode} + + + {entry.companyName} + + + + + {entry.equipmentCode} + + + {entry.equipmentDetails} + + + {entry.projectNumber ? entry.projectNumber : "N/A"} + + + {formatDateTime(entry.noteDate, "YYYY-MMM-DD")} + {entry.noteType} + {reason} + + {entry.userName} ({entry.userId}) + + + ); + })} + + ); + }; + + matchesProjectFilter = (projectIds) => { + if (this.state.search.projectIds.length === 0) { + return true; + } + + return _.intersection(this.state.search.projectIds, projectIds).length > 0; + }; + + matchesLocalAreaFilter = (localAreaId) => { + if (this.state.search.localAreaIds.length === 0) { + return true; + } + + return _.includes(this.state.search.localAreaIds, localAreaId); + }; + + matchesOwnerFilter = (ownerId) => { + if (this.state.search.ownerIds.length === 0) { + return true; + } + + return _.includes(this.state.search.ownerIds, ownerId); + }; + + updateProjectSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedOwners); + }; + + updateLocalAreaSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedOwners); + }; + + updateOwnerSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedEquipment); + }; + + filterSelectedOwners = () => { + var acceptableOwnerIds = _.map(this.getFilteredOwners(), "id"); + var ownerIds = _.intersection( + this.state.search.ownerIds, + acceptableOwnerIds + ); + this.updateSearchState( + { ownerIds: ownerIds }, + this.filterSelectedEquipment + ); + }; + + filterSelectedEquipment = () => { + var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), "id"); + var equipmentIds = _.intersection( + this.state.search.equipmentIds, + acceptableEquipmentIds + ); + this.updateSearchState({ equipmentIds: equipmentIds }); + }; + + getFilteredOwners = () => { + return _.chain(this.props.owners.data) + .filter( + (x) => + this.matchesProjectFilter(x.projectIds) && + this.matchesLocalAreaFilter(x.localAreaId) + ) + .sortBy("organizationName") + .value(); + }; + + getFilteredEquipment = () => { + return _.chain(this.props.equipment.data) + .filter( + (x) => + this.matchesProjectFilter(x.projectIds) && + this.matchesOwnerFilter(x.ownerId) + ) + .sortBy("equipmentCode") + .value(); + }; + + render() { + var resultCount = ""; + if (this.props.hiringResponses.loaded) { + resultCount = + "(" + Object.keys(this.props.hiringResponses.data).length + ")"; + } + + var projects = _.sortBy(this.props.projects.data, "name"); + var localAreas = _.sortBy(this.props.localAreas, "name"); + var owners = this.getFilteredOwners(); + var equipment = this.getFilteredEquipment(); + + return ( +
+ + Hiring Report - Not Hired / Force Hire {resultCount} + + + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.hiringResponses.loading) { + return ( +
+ +
+ ); + } + + if (this.props.hiringResponses.loaded) { + return this.renderResults(); + } + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + projects: state.lookups.projectsCurrentFiscal, + localAreas: state.lookups.localAreas, + owners: state.lookups.owners.hires, + equipment: state.lookups.equipment.hires, + hiringResponses: state.models.hiringResponses, + favourites: state.models.favourites.hiringReport, + search: state.search.hiringResponses, + ui: state.ui.hiringResponses, + }; +} + +export default connect(mapStateToProps)(HiringReport); diff --git a/client2/src/js/views/Home.jsx b/client2/src/js/views/Home.jsx new file mode 100644 index 000000000..951838ae4 --- /dev/null +++ b/client2/src/js/views/Home.jsx @@ -0,0 +1,106 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Well, Row, Col, Button } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; + + +class Home extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + searchSummaryCounts: PropTypes.object, + router: PropTypes.object, + }; + + componentDidMount() { + this.fetch(); + } + + fetch = () => { + Api.getSearchSummaryCounts(); + }; + + goToUnapprovedOwners = () => { + var unapprovedStatus = Constant.OWNER_STATUS_CODE_PENDING; + + // update search parameters + store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: { statusCode: unapprovedStatus } }); + + // perform search + Api.searchOwners({ status: unapprovedStatus }); + + // navigate to search page + this.props.router.push({ pathname: Constant.OWNERS_PATHNAME }); + }; + + goToUnapprovedEquipment = () => { + var unapprovedStatus = Constant.EQUIPMENT_STATUS_CODE_PENDING; + + // update search parameters + store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: { statusCode: Constant.EQUIPMENT_STATUS_CODE_PENDING } }); + + // perform search + Api.searchEquipmentList({ status: unapprovedStatus }); + + // navigate to search page + this.props.router.push({ pathname: Constant.EQUIPMENT_PATHNAME }); + }; + + goToHiredEquipment = () => { + // update search parameters + store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: { statusCode: Constant.EQUIPMENT_STATUS_CODE_APPROVED, hired: true } }); + + // perform search + Api.searchEquipmentList({ status: Constant.EQUIPMENT_STATUS_CODE_APPROVED, hired: true }); + + // navigate to search page + this.props.router.push({ pathname: Constant.EQUIPMENT_PATHNAME }); + }; + + goToBlockedRotationLists = () => { + // update search parameters + store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: { statusCode: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS } }); + + // perform search + Api.searchRentalRequests({ status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS }); + + // navigate to search page + this.props.router.push({ pathname: Constant.RENTAL_REQUESTS_PATHNAME }); + }; + + render() { + var counts = this.props.searchSummaryCounts; + + return
+ {this.props.currentUser.fullName}
{this.props.currentUser.districtName} District
+ + + + + + + + + + + +
; + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + searchSummaryCounts: state.lookups.searchSummaryCounts, + }; +} + +export default connect(mapStateToProps)(Home); diff --git a/client2/src/js/views/Main.jsx b/client2/src/js/views/Main.jsx new file mode 100644 index 000000000..1d5144f4f --- /dev/null +++ b/client2/src/js/views/Main.jsx @@ -0,0 +1,106 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {connect} from 'react-redux'; +import * as Api from '../api'; +import { unhandledApiError, closeSessionTimeoutDialog } from '../actions'; + +import TopNav from './TopNav.jsx'; +import Footer from './Footer.jsx'; +import ConfirmDialog from './dialogs/ConfirmDialog.jsx'; +import ErrorDialog from './dialogs/ErrorDialog.jsx'; +import Countdown from '../components/Countdown.jsx'; + +import { resetSessionTimeoutTimer } from '../App.jsx'; +import { ApiError } from '../utils/http'; +import { bindActionCreators } from 'redux'; + + +class Main extends React.Component { + static propTypes = { + children: PropTypes.object, + showNav: PropTypes.bool, + showSessionTimeoutDialog: PropTypes.bool, + showErrorDialog: PropTypes.bool, + + unhandledApiError: PropTypes.func, + closeSessionTimeoutDialog: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + headerHeight: 0, + }; + } + + componentDidMount() { + const height = document.getElementById('header-main').clientHeight; + this.setState({ headerHeight: height + 10 }); + + window.addEventListener('unhandledrejection', this.unhandledRejection); + } + + unhandledRejection = (e) => { + var err = e.detail.reason; + + if (err instanceof ApiError) { + this.props.unhandledApiError(err); + } + }; + + onCloseSessionTimeoutDialog = () => { + Api.keepAlive(); + resetSessionTimeoutTimer(); + this.props.closeSessionTimeoutDialog(); + }; + + onEndSession = () => { + Api.logoffUser().then(logoffUrl => { + if (logoffUrl) { + window.location.href = logoffUrl; + } + }); + this.props.closeSessionTimeoutDialog(); + }; + + componentWillUnmount() { + window.removeEventListener('unhandledrejection', this.unhandledRejection); + } + + render() { + return ( +
+ +
+ {this.props.children} +
+
+ + Your session will time out in . Would you + like to keep the session active or end the session? + + +
+ ); + } +} + +function mapStateToProps(state) { + return { + showSessionTimeoutDialog: state.ui.showSessionTimeoutDialog, + showErrorDialog: state.ui.showErrorDialog, + }; +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators({ unhandledApiError, closeSessionTimeoutDialog }, dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(Main); diff --git a/client2/src/js/views/OvertimeRates.jsx b/client2/src/js/views/OvertimeRates.jsx new file mode 100644 index 000000000..31a9f0aa7 --- /dev/null +++ b/client2/src/js/views/OvertimeRates.jsx @@ -0,0 +1,131 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Button, ButtonGroup, Glyphicon, Well } from "react-bootstrap"; +import _ from "lodash"; + +import * as Api from "../api"; +import * as Constant from "../constants"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import TableControl from "../components/TableControl.jsx"; +import Spinner from "../components/Spinner.jsx"; +import OvertimeRateEditDialog from "./dialogs/OvertimeRateEditDialog.jsx"; + +class OvertimeRates extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + overtimeRateTypes: PropTypes.array, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showOvertimeRateEditDialog: false, + overtimeRateType: {}, + }; + } + + componentDidMount() { + this.fetch(); + } + + fetch = () => { + Api.getOvertimeRateTypes(); + }; + + editRate = (overtimeRateType) => { + this.setState( + { overtimeRateType: overtimeRateType }, + this.showOvertimeRateEditDialog + ); + }; + + showOvertimeRateEditDialog = () => { + this.setState({ showOvertimeRateEditDialog: true }); + }; + + closeOvertimeRateEditDialog = () => { + this.setState({ showOvertimeRateEditDialog: false }); + }; + + overtimeRateSaved = () => { + this.fetch(); + }; + + render() { + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return
You do not have permission to view this page.
; + } + + return ( +
+ Manage Rental Agreement Overtime Rates + + + {(() => { + if (this.props.overtimeRateTypes.length === 0) { + return ( +
+ +
+ ); + } + + return ( + + {_.map(this.props.overtimeRateTypes, (overtimeRateType) => { + return ( + + {overtimeRateType.rateType} + {overtimeRateType.description} + {`$${overtimeRateType.rate.toFixed(2)}/Hr`} + + + + + + + ); + })} + + ); + })()} +
+ + {this.state.showOvertimeRateEditDialog && ( + + )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + overtimeRateTypes: state.lookups.overtimeRateTypes, + }; +} + +export default connect(mapStateToProps)(OvertimeRates); diff --git a/client2/src/js/views/Owners.jsx b/client2/src/js/views/Owners.jsx new file mode 100644 index 000000000..9464eb039 --- /dev/null +++ b/client2/src/js/views/Owners.jsx @@ -0,0 +1,260 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; +import OwnersAddDialog from './dialogs/OwnersAddDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import DropdownControl from '../components/DropdownControl.jsx'; +import EditButton from '../components/EditButton.jsx'; +import Favourites from '../components/Favourites.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import MultiDropdown from '../components/MultiDropdown.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import Form from '../components/Form.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import { sort, caseInsensitiveSort } from '../utils/array.js'; + + +class Owners extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + ownerList: PropTypes.object, + localAreas: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showAddDialog: false, + + search: { + selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], + ownerCode: props.search.ownerCode || '', + ownerName: props.search.ownerName || '', + statusCode: props.search.statusCode || Constant.OWNER_STATUS_CODE_APPROVED, + }, + + ui : { + sortField: props.ui.sortField || 'organizationName', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.ownerCode) { + searchParams.ownerCode = this.state.search.ownerCode; + } + + if (this.state.search.ownerName) { + searchParams.ownerName = this.state.search.ownerName; + } + + if (this.state.search.statusCode) { + searchParams.status = this.state.search.statusCode; + } + + if (this.state.search.selectedLocalAreasIds.length > 0) { + searchParams.localareas = this.state.search.selectedLocalAreasIds; + } + + return searchParams; + }; + + componentDidMount() { + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchOwners(this.buildSearchParams()); + }; + + search = () => { + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + selectedLocalAreasIds: [], + ownerCode: '', + ownerName: '', + statusCode: Constant.OWNER_STATUS_CODE_APPROVED, + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: this.state.search }); + store.dispatch({ type: Action.CLEAR_OWNERS }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () => { + store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: this.state.search }); + if (callback) { callback(); } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () => { + store.dispatch({ type: Action.UPDATE_OWNERS_UI, owners: this.state.ui }); + if (callback) { callback(); } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + openAddDialog = () => { + this.setState({ showAddDialog: true }); + }; + + closeAddDialog = () => { + this.setState({ showAddDialog: false }); + }; + + ownerSaved = (owner) => { + this.fetch(); + this.props.router.push({ + pathname: `${ Constant.OWNERS_PATHNAME }/${ owner.id }`, + }); + }; + + renderResults = (ownerList, addOwnerButton) => { + if (Object.keys(this.props.ownerList.data).length === 0) { return No owners { addOwnerButton }; } + + return + { + _.map(ownerList, (owner) => { + return + { owner.ownerCode } + { owner.localAreaName } + { owner.organizationName } + { owner.primaryContactName } + { owner.workPhoneNumber } + { owner.mobilePhoneNumber } + { owner.equipmentCount } + { owner.status } + + + + + + ; + }) + } + ; + }; + + render() { + // Constrain the local area drop downs to those in the District of the current logged in user + var localAreas = _.chain(this.props.localAreas) + .sortBy('name') + .value(); + + var resultCount = ''; + if (this.props.ownerList.loaded) { + resultCount = '(' + Object.keys(this.props.ownerList.data).length + ')'; + } + + var ownerList = sort(this.props.ownerList.data, this.state.ui.sortField, this.state.ui.sortDesc, caseInsensitiveSort); + + return
+ Owners { resultCount } + + + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.ownerList.loading) { return
; } + + var addOwnerButton = ; + + if (this.props.ownerList.loaded) { + return this.renderResults(ownerList, addOwnerButton); + } + + return { addOwnerButton }; + })()} + { this.state.showAddDialog && + + } +
; + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + ownerList: state.models.owners, + localAreas: state.lookups.localAreas, + favourites: state.models.favourites.owner, + search: state.search.owners, + ui: state.ui.owners, + }; +} + +export default connect(mapStateToProps)(Owners); diff --git a/client2/src/js/views/OwnersDetail.jsx b/client2/src/js/views/OwnersDetail.jsx new file mode 100644 index 000000000..1ac321855 --- /dev/null +++ b/client2/src/js/views/OwnersDetail.jsx @@ -0,0 +1,988 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { + Well, + Row, + Col, + Alert, + Button, + ButtonGroup, + Glyphicon, + Label, +} from "react-bootstrap"; +import { Link } from "react-router"; +import _ from "lodash"; +import Promise from "bluebird"; + +import ContactsEditDialog from "./dialogs/ContactsEditDialog.jsx"; +import DocumentsListDialog from "./dialogs/DocumentsListDialog.jsx"; +import EquipmentAddDialog from "./dialogs/EquipmentAddDialog.jsx"; +import OwnersEditDialog from "./dialogs/OwnersEditDialog.jsx"; +import OwnersPolicyEditDialog from "./dialogs/OwnersPolicyEditDialog.jsx"; +import NotesDialog from "./dialogs/NotesDialog.jsx"; +import OwnerChangeStatusDialog from "./dialogs/OwnerChangeStatusDialog.jsx"; +import StatusDropdown from "../components/StatusDropdown.jsx"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import * as Log from "../history"; +import store from "../store"; + +import CheckboxControl from "../components/CheckboxControl.jsx"; +import ColDisplay from "../components/ColDisplay.jsx"; +import DeleteButton from "../components/DeleteButton.jsx"; +import EditButton from "../components/EditButton.jsx"; +import History from "../components/History.jsx"; +import SortTable from "../components/SortTable.jsx"; +import Spinner from "../components/Spinner.jsx"; +import TooltipButton from "../components/TooltipButton.jsx"; +import Confirm from "../components/Confirm.jsx"; +import OverlayTrigger from "../components/OverlayTrigger.jsx"; +import ReturnButton from "../components/ReturnButton.jsx"; +import PageHeader from "../components/ui/PageHeader.jsx"; +import SubHeader from "../components/ui/SubHeader.jsx"; +import PrintButton from "../components/PrintButton.jsx"; +import Authorize from "../components/Authorize.jsx"; + +import { + activeOwnerSelector, + activeOwnerIdSelector, +} from "../selectors/ui-selectors.js"; + +import { + formatDateTime, + formatDateTimeUTCToLocal, + today, + toZuluTime, +} from "../utils/date"; +import { sortDir, sort } from "../utils/array.js"; +import { firstLastName } from "../utils/string.js"; + +/* + +TODO: +* Print / Notes / Policy Proof Documents (attachments) + +*/ + +const CONTACT_NAME_SORT_FIELDS = ["givenName", "surname"]; + +const OWNER_WITH_EQUIPMENT_IN_ACTIVE_RENTAL_REQUEST_WARNING_MESSAGE = + "This owner has equipment that " + + "is part of an In Progress Rental Request. Release the list (finish hiring / delete) before making this change"; + +class OwnersDetail extends React.Component { + static propTypes = { + ownerId: PropTypes.number.isRequired, + owner: PropTypes.object, + documents: PropTypes.object, + uiContacts: PropTypes.object, + uiEquipment: PropTypes.object, + router: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + reloading: false, + + showEditDialog: false, + showContactDialog: false, + showPolicyDialog: false, + showPolicyDocumentsDialog: false, + showEquipmentDialog: false, + showDocumentsDialog: false, + showNotesDialog: false, + showChangeStatusDialog: false, + + showAttachments: false, + + contact: {}, + + status: "", + + // Contacts + uiContacts: { + sortField: props.uiContacts.sortField || CONTACT_NAME_SORT_FIELDS, + sortDesc: props.uiContacts.sortDesc === true, + }, + + // Equipment + uiEquipment: { + sortField: props.uiEquipment.sortField || "equipmentNumber", + sortDesc: props.uiEquipment.sortDesc === true, + }, + }; + } + + componentDidMount() { + const { ownerId, owner } = this.props; + + /* Documents need be fetched every time as they are not project specific in the store ATM */ + Api.getOwnerDocuments(ownerId).then(() => + this.setState({ loadingDocuments: false }) + ); + + // Only show loading spinner if there is no existing project in the store + if (owner) { + this.setState({ loading: false }); + } + + // Re-fetch project and notes every time + Promise.all([this.fetch(), Api.getOwnerNotes(ownerId)]).then(() => { + this.setState({ loading: false }); + }); + } + + fetch = () => { + this.setState({ reloading: true }); + return Api.getOwner(this.props.ownerId).then(() => + this.setState({ reloading: false }) + ); + }; + + updateContactsUIState = (state, callback) => { + this.setState( + { uiContacts: { ...this.state.uiContacts, ...state } }, + () => { + store.dispatch({ + type: Action.UPDATE_OWNER_CONTACTS_UI, + ownerContacts: this.state.uiContacts, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateEquipmentUIState = (state, callback) => { + this.setState( + { uiEquipment: { ...this.state.uiEquipment, ...state } }, + () => { + store.dispatch({ + type: Action.UPDATE_OWNER_EQUIPMENT_UI, + ownerEquipment: this.state.uiEquipment, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateStatusState = (state) => { + if (state !== this.props.owner.status) { + this.setState({ status: state }, this.openChangeStatusDialog); + } + }; + + openChangeStatusDialog = () => { + this.setState({ showChangeStatusDialog: true }); + }; + + closeChangeStatusDialog = () => { + this.setState({ showChangeStatusDialog: false }); + }; + + onStatusChanged = () => { + this.closeChangeStatusDialog(); + Api.getOwnerNotes(this.props.owner.id); + }; + + showDocuments = () => { + this.setState({ showDocumentsDialog: true }); + }; + + closeDocumentsDialog = () => { + this.setState({ showDocumentsDialog: false }); + }; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + ownerSaved = () => { + Log.ownerModified(this.props.owner); + }; + + openContactDialog = (contactId) => { + var contact; + if (contactId === 0) { + // New + contact = { + id: 0, + owner: this.props.owner, + }; + } else if (contactId) { + // Open the contact for viewing if possible + contact = this.props.owner.contacts.find( + (contact) => contact.id === contactId + ); + } + this.setState({ + contact: contact, + showContactDialog: true, + }); + }; + + closeContactDialog = () => { + this.setState({ showContactDialog: false }); + }; + + deleteContact = (contact) => { + Api.deleteContact(contact).then(() => { + Log.ownerContactDeleted(this.props.owner, contact).then(() => { + // In addition to refreshing the contacts, we need to update the owner + // to get primary contact info and history. + this.fetch(); + }); + }); + }; + + contactSaved = (contact) => { + var isNew = !contact.id; + var log = isNew ? Log.ownerContactAdded : Log.ownerContactUpdated; + + log(this.props.owner, contact).then(() => { + // In addition to refreshing the contacts, we need to update the owner + // to get primary contact info and history. + this.fetch(); + }); + + this.closeContactDialog(); + }; + + openEquipmentDialog = () => { + this.setState({ showEquipmentDialog: true }); + }; + + closeEquipmentDialog = () => { + this.setState({ showEquipmentDialog: false }); + }; + + equipmentSaved = (equipment) => { + this.closeEquipmentDialog(); + Log.ownerEquipmentAdded(this.props.owner, equipment); + Log.equipmentAdded(equipment); + // Open it up + this.props.router.push({ + pathname: `${Constant.EQUIPMENT_PATHNAME}/${equipment.id}`, + state: { + returnUrl: `${Constant.OWNERS_PATHNAME}/${this.props.owner.id}`, + }, + }); + }; + + equipmentVerifyAll = () => { + var now = today(); + var owner = this.props.owner; + + // Update the last verified date on all pieces of equipment + var equipmentList = _.map(owner.equipmentList, (equipment) => { + return { + ...equipment, + lastVerifiedDate: toZuluTime(now), + owner: { id: owner.id }, + }; + }); + + Api.updateOwnerEquipment(owner, equipmentList).then(() => { + this.fetch(); + }); + }; + + equipmentVerify = (equipment) => { + const updatedEquipment = { + ...equipment, + lastVerifiedDate: toZuluTime(today()), + owner: { id: this.props.owner.id }, + }; + + Log.ownerEquipmentVerified(this.props.owner, updatedEquipment); + + Api.updateEquipment(updatedEquipment).then(() => { + this.fetch(); + }); + }; + + openPolicyDialog = () => { + this.setState({ showPolicyDialog: true }); + }; + + closePolicyDialog = () => { + this.setState({ showPolicyDialog: false }); + }; + + policySaved = () => { + Log.ownerModifiedPolicy(this.props.owner); + }; + + openPolicyDocumentsDialog = () => { + // TODO Show popup with links to policy documents + this.setState({ showPolicyDocumentsDialog: true }); + }; + + closePolicyDocumentsDialog = () => { + this.setState({ showPolicyDocumentsDialog: false }); + }; + + addPolicyDocument = () => { + // TODO Upload policy document (proof of policy coverage) + }; + + openNotesDialog = () => { + this.setState({ showNotesDialog: true }); + }; + + closeNotesDialog = () => { + this.setState({ showNotesDialog: false }); + }; + + render() { + const { loading, loadingDocuments } = this.state; + var owner = this.props.owner || {}; + + var isApproved = owner.status === Constant.OWNER_STATUS_CODE_APPROVED; + var restrictEquipmentAddTooltip = + "Equipment can only be added to an approved owner."; + var restrictEquipmentVerifyTooltip = + "Equipment can only be verified for an approved owner."; + + const statuses = _.pull( + [ + Constant.OWNER_STATUS_CODE_APPROVED, + Constant.OWNER_STATUS_CODE_PENDING, + Constant.OWNER_STATUS_CODE_ARCHIVED, + ], + owner.status + ); + + return ( +
+
+ + + + + + + + +
+ + +
+ +
+ + + + + + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + return ( +
+ + + + {owner.doingBusinessAs} + + + + + {owner.primaryContactName} + + + + + {owner.ownerName} + + + + + {owner.ownerCode} + + + + + {owner.districtName} + + + + + {owner.meetsResidency ? "Yes" : "No"} + + + + + {owner.registeredCompanyNumber} + + + + + {owner.localAreaName} + + + + + {owner.isMaintenanceContractor ? "Yes" : "No"} + + + + + {owner.address1} {owner.address2}
{" "} + {owner.city} {owner.province} {owner.postalCode} +
+ +
+
+ ); + })()} +
+ + + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + return ( + + + + {owner.workSafeBCPolicyNumber} + + + + + {formatDateTime( + owner.workSafeBCExpiryDate, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + + {owner.cglCompanyName} + + + + + {owner.cglPolicyNumber} + + + + + {formatDateTime( + owner.cglEndDate, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + ); + })()} +
+ + + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + var addContactButton = ( + + + + ); + + if (!owner.contacts || owner.contacts.length === 0) { + return ( + + No contacts {addContactButton} + + ); + } + + var contacts = sort( + owner.contacts, + this.state.uiContacts.sortField, + this.state.uiContacts.sortDesc + ); + + var headers = [ + { field: CONTACT_NAME_SORT_FIELDS, title: "Name" }, + { field: "phone", title: "Phone" }, + { field: "mobilePhoneNumber", title: "Cell Phone" }, + { field: "faxPhoneNumber", title: "Fax" }, + { field: "emailAddress", title: "Email" }, + { field: "role", title: "Role" }, + { field: "notes", title: "Notes" }, + { + field: "addContact", + title: "Add Contact", + style: { textAlign: "right" }, + node: addContactButton, + }, + ]; + + return ( + + {contacts.map((contact) => { + return ( + + + {contact.isPrimary && } + {firstLastName( + contact.givenName, + contact.surname + )} + + {contact.phone} + {contact.mobilePhoneNumber} + {contact.faxPhoneNumber} + + + {contact.emailAddress} + + + {contact.role} + {contact.notes ? "Y" : ""} + + + {contact.canDelete && !contact.isPrimary && ( + + + + )} + {contact.canEdit && ( + + )} + + + + ); + })} + + ); + })()} +
+ + + + Show Attachments + + + + } + > + + Verify All + + + + + + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + if ( + !owner.equipmentList || + owner.equipmentList.length === 0 + ) { + return No equipment; + } + + var equipmentList = _.orderBy( + owner.equipmentList, + [this.state.uiEquipment.sortField], + sortDir(this.state.uiEquipment.sortDesc) + ); + + var headers = [ + { field: "equipmentNumber", title: "ID" }, + { field: "localArea.name", title: "Local Area" }, + { field: "typeName", title: "Equipment Type" }, + { field: "details", title: "Make/Model/Size/Year" }, + { field: "lastVerifiedDate", title: "Last Verified" }, + { field: "blank" }, + ]; + + return ( + + {_.map(equipmentList, (equipment) => { + const location = { + pathname: `${Constant.EQUIPMENT_PATHNAME}/${equipment.id}`, + state: { + returnUrl: `${Constant.OWNERS_PATHNAME}/${owner.id}`, + }, + }; + return ( + + + + {equipment.equipmentCode} + + + {equipment.localArea.name} + {equipment.typeName} + + {equipment.details} + {this.state.showAttachments && ( +
+ Attachments: + {equipment.equipmentAttachments && + equipment.equipmentAttachments.map( + (item, i) => ( + + + + {item.typeName} + {i + 1 < + equipment.equipmentAttachments + .length && ,} + + + ) + )} + {(!equipment.equipmentAttachments || + equipment.equipmentAttachments.length === + 0) && none} +
+ )} + + + {equipment.isApproved + ? formatDateTimeUTCToLocal( + equipment.lastVerifiedDate, + Constant.DATE_YEAR_SHORT_MONTH_DAY + ) + : "Not Approved"} + + + + + OK + + + + + ); + })} +
+ ); + })()} +
+ + + {owner.historyEntity && ( + + )} + + +
+
+ {this.state.showChangeStatusDialog && ( + + )} + {this.state.showNotesDialog && ( + + )} + {this.state.showDocumentsDialog && ( + + )} + {this.state.showEditDialog && ( + + )} + {this.state.showEquipmentDialog && ( + + )} + {this.state.showPolicyDialog && ( + + )} + {this.state.showContactDialog && ( + + )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + owner: activeOwnerSelector(state), + ownerId: activeOwnerIdSelector(state), + documents: state.models.documents, + uiContacts: state.ui.ownerContacts, + uiEquipment: state.ui.ownerEquipment, + }; +} + +export default connect(mapStateToProps)(OwnersDetail); diff --git a/client2/src/js/views/Projects.jsx b/client2/src/js/views/Projects.jsx new file mode 100644 index 000000000..90aa4b2aa --- /dev/null +++ b/client2/src/js/views/Projects.jsx @@ -0,0 +1,267 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, Form } from 'react-bootstrap'; +import _ from 'lodash'; + +import ProjectsAddDialog from './dialogs/ProjectsAddDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import DropdownControl from '../components/DropdownControl.jsx'; +import EditButton from '../components/EditButton.jsx'; +import Favourites from '../components/Favourites.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + + +class Projects extends React.Component { + static propTypes = { + fiscalYears: PropTypes.array, + projects: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showAddDialog: false, + search: { + statusCode: props.search.statusCode || Constant.PROJECT_STATUS_CODE_ACTIVE, + projectName: props.search.projectName || '', + projectNumber: props.search.projectNumber || '', + fiscalYear: props.search.fiscalYear || '', + }, + ui : { + sortField: props.ui.sortField || 'name', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.projectName) { + searchParams.project = this.state.search.projectName; + } + + if (this.state.search.statusCode) { + searchParams.status = this.state.search.statusCode; + } + + if (this.state.search.projectNumber) { + searchParams.projectNumber = this.state.search.projectNumber; + } + + if (this.state.search.fiscalYear) { + searchParams.fiscalYear = this.state.search.fiscalYear; + } + + return searchParams; + }; + + componentDidMount() { + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchProjects(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + statusCode: Constant.PROJECT_STATUS_CODE_ACTIVE, + projectName: '', + projectNumber: '', + fiscalYear: '', + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ type: Action.UPDATE_PROJECTS_SEARCH, projects: this.state.search }); + store.dispatch({ type: Action.CLEAR_PROJECTS }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ + store.dispatch({ type: Action.UPDATE_PROJECTS_SEARCH, projects: this.state.search }); + if (callback) { callback(); } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_PROJECTS_UI, projects: this.state.ui }); + if (callback) { callback(); } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + openAddDialog = () => { + this.setState({ showAddDialog: true }); + }; + + closeAddDialog = () => { + this.setState({ showAddDialog: false }); + }; + + projectAdded = (project) => { + this.fetch(); + this.props.router.push({ + pathname: `${ Constant.PROJECTS_PATHNAME }/${ project.id }`, + }); + }; + + renderResults = (addProjectButton) => { + if (Object.keys(this.props.projects.data).length === 0) { + return No Projects { addProjectButton }; + } + + var projects = _.sortBy(this.props.projects.data, project => { + var sortValue = project[this.state.ui.sortField]; + if (typeof sortValue === 'string') { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.state.ui.sortDesc) { + _.reverse(projects); + } + + return + { + _.map(projects, (project) => { + return + { project.name } + { project.fiscalYear } + { project.provincialProjectNumber } + { project.primaryContactName } + { project.primaryContactPhone } + { project.hires } + { project.requests } + { project.status } + + + + + + ; + }) + } + ; + }; + + render() { + var resultCount = ''; + if (this.props.projects.loaded) { + resultCount = '(' + Object.keys(this.props.projects.data).length + ')'; + } + + return
+ Projects { resultCount } + + + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.projects.loading) { + return
; + } + + var addProjectButton = ( + + ); + + if (this.props.projects.loaded) { + return this.renderResults(addProjectButton); + } + + return { addProjectButton }; + })()} + { this.state.showAddDialog && ( + + )} +
; + } +} + + +function mapStateToProps(state) { + return { + fiscalYears: state.lookups.fiscalYears, + projects: state.models.projects, + favourites: state.models.favourites.project, + search: state.search.projects, + ui: state.ui.projects, + }; +} + +export default connect(mapStateToProps)(Projects); diff --git a/client2/src/js/views/ProjectsDetail.jsx b/client2/src/js/views/ProjectsDetail.jsx new file mode 100644 index 000000000..24ef5d3cc --- /dev/null +++ b/client2/src/js/views/ProjectsDetail.jsx @@ -0,0 +1,584 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Well, Row, Col } from 'react-bootstrap'; +import { Alert, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; +import { Link } from 'react-router'; +import _ from 'lodash'; +import Promise from 'bluebird'; + +import ProjectsEditDialog from './dialogs/ProjectsEditDialog.jsx'; +import ContactsEditDialog from './dialogs/ContactsEditDialog.jsx'; +import DocumentsListDialog from './dialogs/DocumentsListDialog.jsx'; +import RentalRequestsAddDialog from './dialogs/RentalRequestsAddDialog.jsx'; +import TimeEntryDialog from './dialogs/TimeEntryDialog.jsx'; +import NotesDialog from './dialogs/NotesDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import * as Log from '../history'; +import store from '../store'; + +import CheckboxControl from '../components/CheckboxControl.jsx'; +import ColDisplay from '../components/ColDisplay.jsx'; +import Confirm from '../components/Confirm.jsx'; +import DeleteButton from '../components/DeleteButton.jsx'; +import EditButton from '../components/EditButton.jsx'; +import History from '../components/History.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import StatusDropdown from '../components/StatusDropdown.jsx'; +import TableControl from '../components/TableControl.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import { activeProjectSelector, activeProjectIdSelector } from '../selectors/ui-selectors.js'; + +import { formatDateTime } from '../utils/date'; +import { sort, caseInsensitiveSort } from '../utils/array.js'; +import { firstLastName } from '../utils/string.js'; +import ReturnButton from '../components/ReturnButton.jsx'; +import PrintButton from '../components/PrintButton.jsx'; + + +const CONTACT_NAME_SORT_FIELDS = ['givenName', 'surname']; + +const STATUS_NOT_EDITABLE_MESSAGE = 'The project can only be marked as completed when it has no active requests or actively hired equipment.'; + +class ProjectsDetail extends React.Component { + static propTypes = { + projectId: PropTypes.number, + project: PropTypes.object, + documents: PropTypes.object, + uiContacts: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + loadingDocuments: true, + reloading: false, + + showNotesDialog: false, + showDocumentsDialog: false, + showEditDialog: false, + showAddRequestDialog: false, + showTimeEntryDialog: false, + showContactDialog: false, + + includeCompletedRequests: false, + + contact: {}, + + rentalAgreement: {}, + + // Contacts + uiContacts : { + sortField: props.uiContacts.sortField || CONTACT_NAME_SORT_FIELDS, + sortDesc: props.uiContacts.sortDesc === true, + }, + }; + } + + componentDidMount() { + const { projectId, project } = this.props; + + /* Documents need be fetched every time as they are not project specific in the store ATM */ + Api.getProjectDocuments(projectId).then(() => this.setState({ loadingDocuments: false })); + + // Only show loading spinner if there is no existing project in the store + if (project) { + this.setState({ loading: false }); + } + + // Re-fetch project and notes every time + Promise.all([ + this.fetch(), + Api.getProjectNotes(projectId), + ]).then(() => { + this.setState({ loading: false }); + }); + } + + fetch = () => { + this.setState({ reloading: true }); + return Api.getProject(this.props.projectId).then(() => this.setState({ reloading: false })); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateContactsUIState = (state, callback) => { + this.setState({ uiContacts: { ...this.state.uiContacts, ...state }}, () => { + store.dispatch({ type: Action.UPDATE_PROJECT_CONTACTS_UI, projectContacts: this.state.uiContacts }); + if (callback) { callback(); } + }); + }; + + showNotes = () => { + this.setState({ showNotesDialog: true }); + }; + + closeNotesDialog = () => { + this.setState({ showNotesDialog: false }); + }; + + showDocuments = () => { + this.setState({ showDocumentsDialog: true }); + }; + + closeDocumentsDialog = () => { + this.setState({ showDocumentsDialog: false }); + }; + + addDocument = () => { + + }; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + openContactDialog = (contactId) => { + var contact; + if (contactId === 0) { + // New + contact = { + id: 0, + owner: this.props.project, + }; + } else if (contactId) { + // Open the contact for viewing if possible + contact = _.find(this.props.project.contacts, (contact) => contact.id === contactId); + } + this.setState({ + contact: contact, + showContactDialog: true, + }); + }; + + closeContactDialog = () => { + this.setState({ contact:null, showContactDialog: false }); + }; + + deleteContact = (contact) => { + Api.deleteContact(contact).then(() => { + Log.projectContactDeleted(this.props.project, contact).then(() => { + this.fetch(); + }); + }); + }; + + contactSaved = (contact) => { + var isNew = !contact.id; + var log = isNew ? Log.projectContactAdded : Log.projectContactUpdated; + + log(this.props.project, contact).then(() => { + // In addition to refreshing the contacts, we need to update the owner + // to get primary contact info and history. + this.fetch(); + }); + + this.closeContactDialog(); + }; + + openAddRequestDialog = () => { + this.setState({ showAddRequestDialog: true }); + }; + + closeAddRequestDialog = () => { + this.setState({ showAddRequestDialog: false }); + }; + + newRentalAdded = (rentalRequest) => { + this.fetch(); + + Log.projectRentalRequestAdded(this.props.project, rentalRequest); + + this.props.router.push({ + pathname: `${ Constant.RENTAL_REQUESTS_PATHNAME }/${ rentalRequest.id }`, + }); + }; + + confirmEndHire = (item) => { + Api.releaseRentalAgreement(item.id).then(() => { + Api.getProject(this.props.projectId); + Log.projectEquipmentReleased(this.props.project, item.equipment); + }); + }; + + openTimeEntryDialog = (rentalAgreement) => { + this.setState({ rentalAgreement }, () => { + this.setState({ + showTimeEntryDialog: true, + fiscalYearStartDate: this.props.project.fiscalYearStartDate, + }); + }); + }; + + closeTimeEntryDialog = () => { + this.setState({ showTimeEntryDialog: false }); + }; + + cancelRequest = (request) => { + store.dispatch({ type: Action.DELETE_PROJECT_RENTAL_REQUEST, projectId: this.props.projectId, requestId: request.id }); + Api.cancelRentalRequest(request.id).then(() => { + this.fetch(); + }); + }; + + renderRentalRequestListItem = (item) => { + return + + + Request + + + { item.localAreaName } + { item.equipmentTypeName } + { item.equipmentCount } + TBD + N/A + N/A + N/A + N/A + + 0 } onConfirm={ this.cancelRequest.bind(this, item) }/> + + ; + }; + + renderRentalAgreementListItem = (item) => { + return + + + { item.equipmentCode } + + + { item.localAreaName } + { item.equipmentTypeName } +   + { item.equipment.equipmentDetails } + { item.isCompleted ? + 'Completed' + : + + } + + + { item.status === Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED ? +
Released
+ : + + }> + + + + } + + Agreement + { formatDateTime(item.datedOn, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + + ; + }; + + getStatuses = () => { + var project = this.props.project || {}; + + return _.pull([ + Constant.PROJECT_STATUS_CODE_ACTIVE, + Constant.PROJECT_STATUS_CODE_COMPLETED, + ], project.status); + }; + + updateStatusState = (state) => { + if (state !== this.props.project.status) { + const project = { + ...this.props.project, + status: state, + }; + + store.dispatch({ type: Action.UPDATE_PROJECT, project }); + Log.projectModifiedStatus(project); + Api.updateProject(project); + } + }; + + render() { + const { loading, loadingDocuments } = this.state; + var project = this.props.project || {}; + + // As per business requirements: + // "Lists the records - requests then rental agreements, within the groups, list in largest-to-smallest ID order (aka reverse chronological create)." + var rentalRequests = _.orderBy(project.rentalRequests, ['id'], ['desc']); + var rentalAgreements = _.orderBy(project.rentalAgreements, ['id'], ['desc']); + + var combinedList =_.concat(rentalRequests, rentalAgreements); + // Exclude completed items + if (!this.state.includeCompletedRequests) { + _.remove(combinedList, (x) => !x.isActive); + } + + return ( +
+
+
+ + + + + + + +
+ + +
+ +
+ + +
+ + + + + + {(() => { + if (loading) { return
; } + + var mailto = + { project.primaryContactName } + ; + + return + + { project.fiscalYear } + + + { project.provincialProjectNumber } + + + { project.responsibilityCentre } + + + { project.serviceLine } + + + { project.stob } + + + { project.product } + + + { project.businessFunction } + + + { project.workActivity } + + + { project.costType } + + + { project.information } + + + + { project.primaryContactEmail ? mailto : `${project.primaryContactName}` }{ project.primaryContactPhone ? `, ${project.primaryContactPhone}` : '' } + + + ; + })()} +
+ + + Show Completed + + + {(() => { + if (loading) { return
; } + + if (Object.keys(combinedList).length === 0) { return No equipment; } + + var headers = [ + { field: 'equipmentCode', title: 'ID' }, + { field: 'localAreaName', title: 'Local Area' }, + { field: 'equipmentTypeName', title: 'Type' }, + { field: 'equipmentCount', title: 'Quantity' }, + { field: 'equipmentMake', title: 'Year Make/Model/Size' }, + { field: 'lastTimeRecord', title: 'Time Entry' }, + { field: 'release', title: 'Release' }, + { field: 'agreement', title: 'Agreement' }, + { field: 'hiredDate', title: 'Hired Date' }, + { field: 'blank' }, + ]; + + return + { + _.map(combinedList, (listItem) => { + if (listItem.isRentalRequest) { + return this.renderRentalRequestListItem(listItem); + } else { + return this.renderRentalAgreementListItem(listItem); + } + }) + } + ; + })()} +
+ + + + + {(() => { + if (loading) { return
; } + + var addContactButton = ; + + if (!project.contacts || project.contacts.length === 0) { return No contacts { addContactButton }; } + + var contacts = sort(project.contacts, this.state.uiContacts.sortField, this.state.uiContacts.sortDesc, caseInsensitiveSort); + + var headers = [ + { field: 'name', title: 'Name' }, + { field: 'phone', title: 'Phone' }, + { field: 'mobilePhoneNumber', title: 'Cell Phone' }, + { field: 'faxPhoneNumber', title: 'Fax' }, + { field: 'emailAddress', title: 'Email' }, + { field: 'role', title: 'Role' }, + { field: 'notes', title: 'Notes' }, + { field: 'addContact', title: 'Add Contact', style: { textAlign: 'right' }, + node: addContactButton, + }, + ]; + + return + { + contacts.map((contact) => { + return + + { contact.isPrimary && } + { firstLastName(contact.givenName, contact.surname) } + + { contact.phone } + { contact.mobilePhoneNumber } + { contact.faxPhoneNumber } + { contact.emailAddress } + { contact.role } + { contact.notes ? 'Y' : '' } + + + {contact.canDelete && ( + + )} + {contact.canEdit && ( + + )} + + + ; + }) + } + ; + })()} +
+ + + { project.historyEntity && } + + +
+
+ {this.state.showEditDialog && ( + + )} + {this.state.showNotesDialog && ( + + )} + {this.state.showDocumentsDialog && ( + + )} + {this.state.showAddRequestDialog && ( + + )} + {this.state.showTimeEntryDialog && ( + + )} + {this.state.showContactDialog && ( + + )} +
+ ); + } +} + + +function mapStateToProps(state) { + return { + project: activeProjectSelector(state), + projectId: activeProjectIdSelector(state), + documents: state.models.documents, + uiContacts: state.ui.projectContacts, + }; +} + +export default connect(mapStateToProps)(ProjectsDetail); diff --git a/client2/src/js/views/RentalAgreementsDetail.jsx b/client2/src/js/views/RentalAgreementsDetail.jsx new file mode 100644 index 000000000..3323b0f1c --- /dev/null +++ b/client2/src/js/views/RentalAgreementsDetail.jsx @@ -0,0 +1,866 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Link } from "react-router"; +import { + Well, + Row, + Col, + Table, + Alert, + Button, + Glyphicon, + Label, + ButtonGroup, +} from "react-bootstrap"; +import _ from "lodash"; + +import EquipmentRentalRatesEditDialog from "./dialogs/EquipmentRentalRatesEditDialog.jsx"; +import RentalAgreementsEditDialog from "./dialogs/RentalAgreementsEditDialog.jsx"; +import RentalConditionsEditDialog from "./dialogs/RentalConditionsEditDialog.jsx"; +import RentalAgreementOvertimeNotesDialog from "./dialogs/RentalAgreementOvertimeNotesDialog.jsx"; +import RentalRatesEditDialog from "./dialogs/RentalRatesEditDialog.jsx"; +import CloneDialog from "./dialogs/CloneDialog.jsx"; + +import * as Api from "../api"; +import * as Constant from "../constants"; + +import ColDisplay from "../components/ColDisplay.jsx"; +import DeleteButton from "../components/DeleteButton.jsx"; +import EditButton from "../components/EditButton.jsx"; +import Spinner from "../components/Spinner.jsx"; +import TooltipButton from "../components/TooltipButton.jsx"; +import SubHeader from "../components/ui/SubHeader.jsx"; +import ReturnButton from "../components/ReturnButton.jsx"; +import Authorize from "../components/Authorize.jsx"; + +import { + activeRentalAgreementSelector, + activeRentalAgreementIdSelector, +} from "../selectors/ui-selectors"; + +import { buildApiPath } from "../utils/http.js"; +import { formatDateTime } from "../utils/date"; +import { formatCurrency } from "../utils/string"; + +class RentalAgreementsDetail extends React.Component { + static propTypes = { + rentalAgreement: PropTypes.object, + rentalAgreementId: PropTypes.number, + rentalConditions: PropTypes.array, + ui: PropTypes.object, + location: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + rentalAgreementDocumentLoading: false, + + showEditDialog: false, + showEquipmentRateDialog: false, + showRentalRateDialog: false, + showConditionDialog: false, + showCloneDialog: false, + + rentalRate: {}, + rentalCondition: {}, + }; + } + + componentDidMount() { + const { rentalAgreement } = this.props; + + // Only show loading spinner if there is no existing rental agreement in the store + if (rentalAgreement) { + this.setState({ loading: false }); + } + + // Re-fetch rental agreement every time + Promise.all([this.fetch(rentalAgreement)]).then(() => { + this.setState({ loading: false }); + }); + } + + fetch = () => { + return Api.getRentalAgreement(this.props.rentalAgreementId); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + openEquipmentRateDialog = () => { + this.setState({ showEquipmentRateDialog: true }); + }; + + closeEquipmentRateDialog = () => { + this.setState({ showEquipmentRateDialog: false }); + }; + + openRentalRateDialog = (rentalRate) => { + this.setState({ + rentalRate, + showRentalRateDialog: true, + }); + }; + + addRentalRate = (isIncluded) => { + // New + this.openRentalRateDialog({ + id: 0, + isIncludedInTotal: isIncluded, + rentalAgreement: this.props.rentalAgreement, + }); + }; + + closeRentalRateDialog = () => { + this.setState({ showRentalRateDialog: false }); + }; + + deleteRentalRate = (rentalRate) => { + Api.deleteRentalRate(rentalRate).then(() => { + // In addition to refreshing the rental rates, we need to update the rental agreement to get + // possibly new info. + this.fetch(); + }); + }; + + openConditionDialog = (rentalCondition) => { + this.setState({ + rentalCondition, + showConditionDialog: true, + }); + }; + + closeConditionDialog = () => { + this.setState({ showConditionDialog: false }); + }; + + addCondition = () => { + this.openConditionDialog({ + id: 0, + rentalAgreement: this.props.rentalAgreement, + }); + }; + + deleteCondition = (rentalCondition) => { + Api.deleteRentalCondition(rentalCondition).then(() => { + // In addition to refreshing the rental condition, we need to update the rental agreement to + // get possibly new info. + this.fetch(); + }); + }; + + openOvertimeNotesDialog = () => { + this.setState({ showOvertimeNotesDialog: true }); + }; + + closeOvertimeNotesDialog = () => { + this.setState({ showOvertimeNotesDialog: false }); + }; + + generateRentalAgreementDocument = () => { + Api.generateRentalAgreementDocument(this.props.rentalAgreementId).then( + () => { + window.open( + buildApiPath(`/rentalagreements/${this.props.rentalAgreementId}/doc`) + ); + } + ); + }; + + openCloneDialog = () => { + this.setState({ showCloneDialog: true }); + }; + + closeCloneDialog = () => { + this.setState({ showCloneDialog: false }); + }; + + render() { + const { loading } = this.state; + const rentalAgreement = this.props.rentalAgreement || {}; + + var buttons = ( +
+ + + + + +
+ ); + + return ( +
+ + +
+ {!loading && ( + + )} +
+ + {buttons} +
+ + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + var equipmentDetails = + rentalAgreement.equipment && rentalAgreement.equipment.id !== 0 + ? `${rentalAgreement.equipment.year} ${rentalAgreement.equipment.make}/${rentalAgreement.equipment.model}/${rentalAgreement.equipment.size}` + : ""; + + return ( +
+ + + + + {rentalAgreement.number} + + + + + + View + + + + + + {rentalAgreement.project.name} + + + + + {rentalAgreement.district.name} + + + + + {rentalAgreement.ownerName} + + + + + {rentalAgreement.equipment.owner.workSafeBcpolicyNumber} + + + + + + {rentalAgreement.equipment.equipmentCode} + + + + + + {rentalAgreement.equipment.serialNumber} + + + + + {equipmentDetails} + + + + + {rentalAgreement.pointOfHire} + + + +
+ ); + })()} +
+ + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + return ( + + + + {formatDateTime( + rentalAgreement.estimateStartWork, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + + {rentalAgreement.estimateHours} + + + + + {formatDateTime( + rentalAgreement.datedOn, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + + {rentalAgreement.agreementCity} + + + + ); + })()} +
+ + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + return ( + + + Pay Rate: + {formatCurrency(rentalAgreement.equipmentRate)} + + + Period: + {rentalAgreement.ratePeriod} + + + Comment: + {rentalAgreement.rateComment} + + + + ); + })()} + + {(() => { + if (loading) { + return; + } + + // filter to included rates only + // as-needed rates are shown in the next section + var includedRates = _.filter(rentalAgreement.rentalAgreementRates, { + isIncludedInTotal: true, + }); + + var button = ( + + + + Add Included Rates and Attachments + + + ); + + if (Object.keys(includedRates || []).length === 0) { + return ( +
+ + No included rates or attachments + + {button} +
+ ); + } + + // newly-added rates (with an id of 0) need to appear at the end of the list + includedRates = _.orderBy( + includedRates, + [(r) => r.id === 0, (r) => r.id], + ["asc", "asc"] + ); + + return ( +
+ + + + + + + + + + + {_.map(includedRates, (obj, i) => { + return ( + + + + + + + ); + })} + +
RatePeriodComment
{formatCurrency(obj.rate)}{obj.ratePeriod}{obj.comment} + + + + + + +
+ {button} +
+ ); + })()} +
+ + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + // filter to as-needed rates only + // included rates are shown in the previous section + var asNeededRates = _.filter(rentalAgreement.rentalAgreementRates, { + isIncludedInTotal: false, + }); + + var button = ( + + + + Add Other Rates and Attachments + + + ); + + if (Object.keys(asNeededRates || []).length === 0) { + return ( +
+ + No as-needed rates or attachments + + {button} +
+ ); + } + + // newly-added rates (with an id of 0) need to appear at the end of the list + asNeededRates = _.orderBy( + asNeededRates, + [(r) => r.id === 0, (r) => r.id], + ["asc", "asc"] + ); + + return ( +
+ + + + + + + + + + + {_.map(asNeededRates, (obj, i) => { + return ( + + + + + + + ); + })} + +
RatePeriodComment
{formatCurrency(obj.rate)} + {obj.set + ? Constant.RENTAL_RATE_PERIOD_SET + : obj.ratePeriod} + {obj.comment} + + + + + + +
+ {button} +
+ ); + })()} +
+ + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + // newly-added conditions (with an id of 0) need to appear at the end of the list + var rentalConditions = _.orderBy( + rentalAgreement.rentalAgreementConditions, + [(c) => c.id === 0, (c) => c.id], + ["asc", "asc"] + ); + + var button = ( + + + + ); + + if (Object.keys(rentalConditions || []).length === 0) { + return ( +
+ No rental conditions + {button} +
+ ); + } + + return ( +
+ + + + + + + + + + {_.map(rentalConditions, (obj, i) => { + return ( + + + + + + ); + })} + +
ConditionComment
{obj.conditionName}{obj.comment} + + + + + + +
+ {button} +
+ ); + })()} +
+ + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + var rates = _.orderBy( + rentalAgreement.overtimeRates, + ["comment"], + ["desc"] + ); + + return ( + + {rates.map((rate) => { + debugger; + if (rate.active) { + return ( + + {rate.comment} + + ); + } + })} + + ); + })()} + + {rentalAgreement && rentalAgreement.note} + +
+ + {buttons} + {this.state.showEditDialog && ( + + )} + {this.state.showEquipmentRateDialog && ( + + )} + {this.state.showRentalRateDialog && ( + + )} + {this.state.showConditionDialog && ( + + )} + {this.state.showOvertimeNotesDialog && ( + + )} + {this.state.showCloneDialog && ( + + )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + rentalAgreement: activeRentalAgreementSelector(state), + rentalAgreementId: activeRentalAgreementIdSelector(state), + }; +} + +export default connect(mapStateToProps)(RentalAgreementsDetail); diff --git a/client2/src/js/views/RentalRequests.jsx b/client2/src/js/views/RentalRequests.jsx new file mode 100644 index 000000000..4d6f17c2e --- /dev/null +++ b/client2/src/js/views/RentalRequests.jsx @@ -0,0 +1,384 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, Form } from 'react-bootstrap'; +import { Link } from 'react-router'; +import _ from 'lodash'; +import Moment from 'moment'; + +import RentalRequestsAddDialog from './dialogs/RentalRequestsAddDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import * as Log from '../history'; +import store from '../store'; + +import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import DateControl from '../components/DateControl.jsx'; +import DeleteButton from '../components/DeleteButton.jsx'; +import DropdownControl from '../components/DropdownControl.jsx'; +import EditButton from '../components/EditButton.jsx'; +import Favourites from '../components/Favourites.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import Mailto from '../components/Mailto.jsx'; +import MultiDropdown from '../components/MultiDropdown.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import { formatDateTime, startOfCurrentFiscal, endOfCurrentFiscal, startOfPreviousFiscal, endOfPreviousFiscal, toZuluTime } from '../utils/date'; + +const WITHIN_30_DAYS = 'Within 30 Days'; +const THIS_MONTH = 'This Month'; +const THIS_QUARTER = 'This Quarter'; +const THIS_FISCAL = 'This Fiscal'; +const LAST_MONTH = 'Last Month'; +const LAST_QUARTER = 'Last Quarter'; +const LAST_FISCAL = 'Last Fiscal'; +const CUSTOM = 'Custom'; + + +class RentalRequests extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + rentalRequests: PropTypes.object, + rentalRequest: PropTypes.object, + localAreas: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showAddDialog: false, + addViewOnly: false, + search: { + selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], + projectName: props.search.projectName || '', + status: props.search.status || Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, + dateRange: props.search.dateRange || '', + }, + ui : { + sortField: props.ui.sortField || 'projectName', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = { + status: this.state.search.status || '', + project: this.state.search.projectName || '', + }; + + if (this.state.search.selectedLocalAreasIds.length > 0) { + searchParams.localAreas = this.state.search.selectedLocalAreasIds; + } + + // Time period drop-down; e.g. "This Month" + var startDate; + var endDate; + var today = Moment(); + + switch (this.state.search.dateRange) { + case WITHIN_30_DAYS: + endDate = today.add(30, 'day'); + break; + case THIS_MONTH: + startDate = today.startOf('month'); + endDate = Moment(startDate).endOf('month'); + break; + case THIS_QUARTER: + startDate = today.startOf('quarter'); + endDate = Moment(startDate).endOf('quarter'); + break; + case THIS_FISCAL: + // Fiscal Year: Apr 1 - March 31 + startDate = startOfCurrentFiscal(today); + endDate = endOfCurrentFiscal(today); + break; + case LAST_MONTH: + startDate = today.subtract(1, 'month').startOf('month'); + endDate = Moment(startDate).endOf('month'); + break; + case LAST_QUARTER: + startDate = today.subtract(1, 'quarter').startOf('quarter'); + endDate = Moment(startDate).endOf('quarter'); + break; + case LAST_FISCAL: + // Fiscal Year: Apr 1 - March 31 + startDate = startOfPreviousFiscal(today); + endDate = endOfPreviousFiscal(today); + break; + case CUSTOM: + startDate = Moment(this.state.search.startDate); + endDate = Moment(this.state.search.endDate); + break; + default: + break; + } + + if (startDate && startDate.isValid()) { + searchParams.startDate = toZuluTime(startDate.startOf('day')); + } + if (endDate && endDate.isValid()) { + searchParams.endDate = toZuluTime(endDate.startOf('day')); + } + + return searchParams; + }; + + componentDidMount() { + var defaultFavourite = null; + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + defaultFavourite = _.find(this.props.favourites, f => f.isDefault); + } + + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); // also fetches + } else if (this.props.rentalRequests.loaded) { + // if a search was performed previously, refresh the search results + this.fetch(); + } + } + + fetch = () => { + Api.searchRentalRequests(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + selectedLocalAreasIds: [], + projectName: '', + status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, + dateRange: '', + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: this.state.search }); + store.dispatch({ type: Action.CLEAR_RENTAL_REQUESTS }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ + store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: this.state.search }); + if (callback) { callback(); } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_UI, rentalRequests: this.state.ui }); + if (callback) { callback(); } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + deleteRequest = (request) => { + Api.cancelRentalRequest(request.id).then(() => { + this.fetch(); + }); + }; + + openAddDialog = (viewOnly) => { + this.setState({ showAddDialog: true, addViewOnly: viewOnly }); + }; + + closeAddDialog = () => { + this.setState({ showAddDialog: false }); + }; + + newRentalAdded = (rentalRequest) => { + Log.rentalRequestAdded(rentalRequest); + + this.props.router.push({ + pathname: `${ Constant.RENTAL_REQUESTS_PATHNAME }/${ rentalRequest.id }`, + }); + }; + + renderResults = (addRequestButtons) => { + if (Object.keys(this.props.rentalRequests.data).length === 0) { return No Rental Requests { addRequestButtons }; } + + var rentalRequests = _.sortBy(this.props.rentalRequests.data, rentalRequest => { + var sortValue = rentalRequest[this.state.ui.sortField]; + if (typeof sortValue === 'string') { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.state.ui.sortDesc) { + _.reverse(rentalRequests); + } + + return + { + _.map(rentalRequests, (request) => { + var projectLink = request.projectId ? { request.projectName } : request.projectName; + + return + { request.localAreaName } + { request.equipmentCount } + { request.districtEquipmentName } + { formatDateTime(request.expectedStartDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + { formatDateTime(request.expectedEndDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + { projectLink } + + { + request.primaryContactName ? + { request.primaryContactName } : + 'None' + } + + { request.status } + + + {request.canDelete && ( + + )} + {request.canView && ( + + )} + + + ; + }) + } + ; + }; + + render() { + // Constrain the local area drop downs to those in the District of the current logged in user + var localAreas = _.chain(this.props.localAreas) + .sortBy('name') + .value(); + + var resultCount = ''; + if (this.props.rentalRequests.loaded) { + resultCount = '(' + Object.keys(this.props.rentalRequests.data).length + ')'; + } + + return
+ Rental Requests { resultCount } + + + + + +
+ + + + + + + + + + + + + {(() => { + if (this.state.search.dateRange === CUSTOM) { + return + + + + + ; + } + })()} + + + + + + + +
+
+ + {(() => { + if (this.props.rentalRequests.loading) { return
; } + + var addViewOnlyRequestButton = ( + + ); + + var addRentalRequestButton = ( + + ); + + var addRequestButtons =
+ { addRentalRequestButton } + { addViewOnlyRequestButton } +
; + + if (this.props.rentalRequests.loaded) { + return this.renderResults(addRequestButtons); + } + + return { addRequestButtons }; + })()} + { this.state.showAddDialog && ( + + )} +
; + } +} + + +function mapStateToProps(state) { + return { + currentUser: state.user, + rentalRequests: state.models.rentalRequests, + localAreas: state.lookups.localAreas, + favourites: state.models.favourites.rentalRequests, + search: state.search.rentalRequests, + ui: state.ui.rentalRequests, + }; +} + +export default connect(mapStateToProps)(RentalRequests); diff --git a/client2/src/js/views/RentalRequestsDetail.jsx b/client2/src/js/views/RentalRequestsDetail.jsx new file mode 100644 index 000000000..a33700dfe --- /dev/null +++ b/client2/src/js/views/RentalRequestsDetail.jsx @@ -0,0 +1,772 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { + Well, + Row, + Col, + Alert, + Button, + ButtonGroup, + Glyphicon, + Label, +} from "react-bootstrap"; +import { Link } from "react-router"; +import _ from "lodash"; +import Promise from "bluebird"; +import Moment from "moment"; + +import HireOfferEditDialog from "./dialogs/HireOfferEditDialog.jsx"; +import RentalRequestsEditDialog from "./dialogs/RentalRequestsEditDialog.jsx"; +import DocumentsListDialog from "./dialogs/DocumentsListDialog.jsx"; +import NotesDialog from "./dialogs/NotesDialog.jsx"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import * as Log from "../history"; +import store from "../store"; + +import CheckboxControl from "../components/CheckboxControl.jsx"; +import ColDisplay from "../components/ColDisplay.jsx"; +import PageOrientation from "../components/PageOrientation.jsx"; +import Spinner from "../components/Spinner.jsx"; +import TableControl from "../components/TableControl.jsx"; +import Confirm from "../components/Confirm.jsx"; +import History from "../components/History.jsx"; +import OverlayTrigger from "../components/OverlayTrigger.jsx"; +import TooltipButton from "../components/TooltipButton.jsx"; +import ReturnButton from "../components/ReturnButton.jsx"; +import SubHeader from "../components/ui/SubHeader.jsx"; +import Watermark from "../components/Watermark.jsx"; + +import { formatDateTime, formatDateTimeUTCToLocal } from "../utils/date"; +import { concat } from "../utils/string"; +import PrintButton from "../components/PrintButton.jsx"; +import { + activeRentalRequestSelector, + activeRentalRequestIdSelector, +} from "../selectors/ui-selectors.js"; + +/* + +TODO: +* Print / Notes / Docs / Contacts (TBD) / History / Request Status List / Clone / Request Attachments + +*/ +const STATUS_YES = "Yes"; +const STATUS_NO = "No"; +const STATUS_FORCE_HIRE = "Force Hire"; +const STATUS_ASKED = "Asked"; +const STATUS_IN_PROGRESS = "In Progress"; + +class RentalRequestsDetail extends React.Component { + static propTypes = { + rentalRequestId: PropTypes.number, + rentalRequest: PropTypes.object, + documents: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + loadingDocuments: false, + reloading: false, + + showEditDialog: false, + showHireOfferDialog: false, + showNotesDialog: false, + showAttachments: false, + + rotationListHireOffer: {}, + showAllResponseFields: false, + + isNew: props.rentalRequestId === 0, + }; + } + + componentDidMount() { + const { rentalRequestId, rentalRequest } = this.props; + + /* Documents need be fetched every time as they are not rentalRequest specific in the store ATM */ + Api.getRentalRequestDocuments(rentalRequestId).then(() => + this.setState({ loadingDocuments: false }) + ); + + // Only show loading spinner if there is no existing rental request in the store + if (rentalRequest) { + this.setState({ loading: false }); + } + + // Re-fetch rental request, rotationlist, and notes every time + Promise.all([ + this.fetch(), + Api.getRentalRequestNotes(rentalRequestId), + Api.getRentalRequestRotationList(rentalRequestId), + ]).then(() => { + this.setState({ loading: false }); + }); + } + + fetch = () => { + this.setState({ reloading: true }); + return Api.getRentalRequest(this.props.rentalRequestId).then(() => + this.setState({ reloading: false }) + ); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateContactsUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_PROJECT_CONTACTS_UI, + projectContacts: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + showNotes = () => { + this.setState({ showNotesDialog: true }); + }; + + closeNotesDialog = () => { + this.setState({ showNotesDialog: false }); + }; + + showDocuments = () => { + this.setState({ showDocumentsDialog: true }); + }; + + closeDocumentsDialog = () => { + this.setState({ showDocumentsDialog: false }); + }; + + addDocument = () => {}; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + rentalRequestSaved = () => { + Promise.all([ + this.fetch(), + Api.getRentalRequestRotationList(this.props.rentalRequestId), + ]); + }; + + openHireOfferDialog = (hireOffer, showAllResponseFields) => { + this.setState({ + rotationListHireOffer: hireOffer, + showAllResponseFields, + showHireOfferDialog: true, + }); + }; + + closeHireOfferDialog = () => { + this.setState({ showHireOfferDialog: false }); + }; + + hireOfferSaved = (hireOffer) => { + Log.rentalRequestEquipmentHired( + this.props.rentalRequest, + hireOffer.equipment, + hireOffer.offerResponse + ); + + this.closeHireOfferDialog(); + + var rotationListItem = _.find( + this.props.rentalRequest.rotationList, + (i) => i.id === hireOffer.id + ); + if ( + rotationListItem && + rotationListItem.rentalAgreementId && + !hireOffer.rentalAgreementId + ) { + // navigate to rental agreement if it was newly generated + this.props.router.push({ + pathname: `${Constant.RENTAL_AGREEMENTS_PATHNAME}/${rotationListItem.rentalAgreementId}`, + }); + } else { + // close popup dialog and refresh page data + this.fetch(); + } + }; + + downloadDoc = (promise, filename) => { + promise.then((response) => { + var blob; + if (window.navigator.msSaveBlob) { + blob = window.navigator.msSaveBlob(response, filename); + } else { + blob = new Blob([response], { + type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + }); + } + //Create a link element, hide it, direct + //it towards the blob, and then 'click' it programatically + let a = document.createElement("a"); + a.style.cssText = "display: none"; + document.body.appendChild(a); + //Create a DOMString representing the blob + //and point the link element towards it + let url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + //programatically click the link to trigger the download + a.click(); + //release the reference to the file by revoking the Object URL + window.URL.revokeObjectURL(url); + }); + }; + + printSeniorityList = () => { + var localAreaIds = [this.props.rentalRequest.localAreaId]; + var districtEquipmentTypeIds = [ + this.props.rentalRequest.districtEquipmentTypeId, + ]; + var promise = Api.equipmentSeniorityListDoc( + localAreaIds, + districtEquipmentTypeIds + ); + var filename = + "SeniorityList-" + + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + + ".docx"; + this.downloadDoc(promise, filename); + }; + + addRequest = () => {}; + + renderStatusText = (listItem) => { + let text = "Hire"; + if ( + listItem.offerResponse === STATUS_NO && + listItem.offerRefusalReason === Constant.HIRING_REFUSAL_OTHER + ) { + text = listItem.offerResponseNote; + } else if (listItem.offerResponse === STATUS_NO) { + text = listItem.offerRefusalReason; + } else if (listItem.offerResponse === STATUS_ASKED) { + text = `${listItem.offerResponse} (${Moment( + listItem.askedDateTime + ).format("YYYY-MM-DD hh:mm A")})`; + } else if ( + listItem.offerResponse === STATUS_FORCE_HIRE || + listItem.offerResponse === STATUS_YES + ) { + text = listItem.offerResponse; + } + return text; + }; + + render() { + const { loading, loadingDocuments } = this.state; + var rentalRequest = this.props.rentalRequest || {}; + + var viewOnly = !rentalRequest.projectId; + var canEditRequest = + !viewOnly && + rentalRequest.status !== Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED; + + return ( +
+ + + + +
+ +
+ + + + +
+ +
+ +
+ + + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + var requestAttachments = + rentalRequest.rentalRequestAttachments && + rentalRequest.rentalRequestAttachments[0] + ? rentalRequest.rentalRequestAttachments[0].attachment + : "None"; + + return ( + + + + {rentalRequest.localAreaName} + + + + + {concat( + rentalRequest.projectPrimaryContactName, + rentalRequest.projectPrimaryContactPhone, + ", " + )} + + + + + {rentalRequest.equipmentTypeName} + + + + + {rentalRequest.equipmentCount} + + + + + {requestAttachments} + + + + + {rentalRequest.expectedHours} + + + + + + {rentalRequest.project && rentalRequest.project.name} + + + + + + {formatDateTime( + rentalRequest.expectedStartDate, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + + + {rentalRequest.project && + rentalRequest.project.provincialProjectNumber} + + + + + + {formatDateTime( + rentalRequest.expectedEndDate, + Constant.DATE_YEAR_SHORT_MONTH_DAY + )} + + + + ); + })()} +
+ + + + + Hire Rotation List + + + + Seniority List + + + Show Attachments + + + {(() => { + if (loading) { + return ( +
+ +
+ ); + } + + var rotationList = this.props.rentalRequest.rotationList; + + if (Object.keys(rotationList || []).length === 0) { + return No equipment; + } + + // Sort in rotation list order + rotationList = _.sortBy(rotationList, "rotationListSortOrder"); + + // use spans for table headers so we can force them to wrap when printing + var headers = [ + { field: "seniorityString", title: "Seniority" }, + { field: "block", title: "Blk" }, + { + field: "serviceHoursThisYear", + node: ( +
+ YTD Hours +
+ ), + }, + { + field: "equipmentCode", + node: ( +
+ Equip. ID +
+ ), + }, + { + field: "equipmentDetails", + node: ( +
+ Equip. Details +
+ ), + }, + { field: "equipmentOwner", title: "Owner" }, + { field: "primaryContactName", title: "Contact" }, + { + field: "primaryContactWorkPhone", + node: ( +
+ Phone +
+ ), + }, + { + field: "primaryContactCellPhone", + node: ( +
+ Cell Phone +
+ ), + }, + { field: "status", title: "Status" }, + { field: "", title: "Comments" }, + ]; + + var numberEquipmentAvailableForNormalHire = + rentalRequest.equipmentCount - rentalRequest.yesCount; + + return ( + + {_.map(rotationList, (listItem, i) => { + const owner = listItem.equipment.owner; + var showAllResponseFields = false; + if ( + numberEquipmentAvailableForNormalHire > 0 && + (listItem.offerResponse === STATUS_ASKED || + !listItem.offerResponse) && + rentalRequest.yesCount < rentalRequest.equipmentCount + ) { + showAllResponseFields = true; + numberEquipmentAvailableForNormalHire -= 1; + } + + const showBlankLine = + i > 0 && + rotationList[i - 1].equipment.blockNumber !== + listItem.equipment.blockNumber; + + return [ + showBlankLine && ( + +   + + ), + + {listItem.equipment.seniorityString} + {listItem.equipment.blockNumber} + {listItem.equipment.hoursYtd} + + + {listItem.equipment.equipmentCode} + + + + {listItem.equipment.equipmentDetails} + {this.state.showAttachments && ( +
+ Attachments: + {listItem.equipment.equipmentAttachments && + listItem.equipment.equipmentAttachments.map( + (item, i) => ( + + + + {item.typeName} + {i + 1 < + listItem.equipment.equipmentAttachments + .length && ,} + + + ) + )} + {(!listItem.equipment.equipmentAttachments || + listItem.equipment.equipmentAttachments.length === + 0) && none} +
+ )} + + {owner && owner.organizationName} + {listItem.displayFields.primaryContactName} + + {owner && + owner.primaryContact && + owner.primaryContact.workPhoneNumber} + + + {owner && + owner.primaryContact && + owner.primaryContact.mobilePhoneNumber} + + + + {(() => { + const changeOfferWarningMessage = + "This piece of equipment is has met or " + + "exceeded its Maximum Allowed Hours for this year. Are you sure you want " + + "to edit the Offer on this equipment?"; + + const confirm = ( + + this.openHireOfferDialog( + listItem, + showAllResponseFields + ) + } + /> + ); + + if (listItem.maximumHours) { + return ( + + + + ); + } + if ( + !viewOnly && + rentalRequest.status === STATUS_IN_PROGRESS && + (listItem.offerResponse === STATUS_ASKED || + !listItem.offerResponse) + ) { + return ( + + ); + } + return this.renderStatusText(listItem); + })()} + + + + , + ]; + })} +
+ ); + })()} +
+ + + + {rentalRequest.historyEntity && ( + + )} + + {this.state.showEditDialog && ( + + )} + {this.state.showHireOfferDialog && ( + + )} + {this.state.showDocumentsDialog && ( + + )} + {this.state.showNotesDialog && ( + + )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + rentalRequest: activeRentalRequestSelector(state), + rentalRequestId: activeRentalRequestIdSelector(state), + documents: state.models.documents, + }; +} + +export default connect(mapStateToProps)(RentalRequestsDetail); diff --git a/client2/src/js/views/Roles.jsx b/client2/src/js/views/Roles.jsx new file mode 100644 index 000000000..d6e05c8ba --- /dev/null +++ b/client2/src/js/views/Roles.jsx @@ -0,0 +1,171 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; +import { LinkContainer } from 'react-router-bootstrap'; +import _ from 'lodash'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import Confirm from '../components/Confirm.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import SearchControl from '../components/SearchControl.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + +class Roles extends React.Component { + static propTypes = { + roles: PropTypes.object, + currentUser: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + + search: { + key: props.search.key || 'name', + text: props.search.text || '', + params: props.search.params || null, + }, + + ui : { + sortField: props.ui.sortField || 'name', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + componentDidMount() { + this.fetch(); + } + + fetch = () => { + this.setState({ loading: true }); + Api.searchRoles().finally(() => { + this.setState({ loading: false }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_ROLES_SEARCH, roles: this.state.search }); + if (callback) { callback(); } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_ROLES_UI, roles: this.state.ui }); + if (callback) { callback(); } + }); + }; + + delete = (role) => { + Api.deleteRole(role).then(() => { + this.fetch(); + }); + }; + + render() { + var numRoles = this.state.loading ? '...' : Object.keys(this.props.roles).length; + + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ROLES_AND_PERMISSIONS) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return ( +
You do not have permission to view this page.
+ ); + } + + return
+ Roles ({ numRoles }) + + + + + + + + + + + + + + + {(() => { + if (this.state.loading) { return
; } + + var addRoleButton = + + ; + if (Object.keys(this.props.roles).length === 0) { return No roles { addRoleButton }; } + + var roles = _.sortBy(_.filter(this.props.roles, role => { + if (!this.state.search.params) { + return true; + } + return role[this.state.search.key] && role[this.state.search.key].toLowerCase().indexOf(this.state.search.text.toLowerCase()) !== -1; + }), this.state.ui.sortField); + + if (this.state.ui.sortDesc) { + _.reverse(roles); + } + + return + { + _.map(roles, (role) => { + return + { role.name } + { role.description } + + + }> + + + + + + + + ; + }) + } + ; + })()} +
; + } +} + + +function mapStateToProps(state) { + return { + currentUser: state.user, + roles: state.models.roles, + search: state.search.roles, + ui: state.ui.roles, + }; +} + +export default connect(mapStateToProps)(Roles); diff --git a/client2/src/js/views/RolesDetail.jsx b/client2/src/js/views/RolesDetail.jsx new file mode 100644 index 000000000..50fc5cd4c --- /dev/null +++ b/client2/src/js/views/RolesDetail.jsx @@ -0,0 +1,266 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Well, Grid, Row, Col } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import { Table, Button } from 'react-bootstrap'; +import _ from 'lodash'; +import Promise from 'bluebird'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import FormInputControl from '../components/FormInputControl.jsx'; +import Spinner from '../components/Spinner.jsx'; +import Form from '../components/Form.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import ReturnButton from '../components/ReturnButton.jsx'; +import PrintButton from '../components/PrintButton.jsx'; + +import { isBlank } from '../utils/string'; + + +class RolesDetail extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + role: PropTypes.object, + rolePermissions: PropTypes.object, + permissions: PropTypes.object, + params: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + + name: '', + description: '', + + nameError: '', + descriptionError: '', + + selectedPermissionIds: [], + + isNew: props.params.roleId === '0', + }; + } + + componentDidMount() { + if (this.state.isNew) { + // Clear the role and permissions store + store.dispatch({ type: Action.UPDATE_ROLE, role: {} }); + store.dispatch({ type: Action.UPDATE_ROLE_PERMISSIONS, rolePermissions: {} }); + } else { + this.fetch(); + } + } + + fetch = () => { + var rolePromise = Api.getRole(this.props.params.roleId); + var permissionsPromise = Api.getRolePermissions(this.props.params.roleId); + + this.setState({ loading: true }); + Promise.all([rolePromise, permissionsPromise]).then(() => { + var selectedPermissionIds = _.map(this.props.rolePermissions, rolePermission => { + return rolePermission.permission.id; + }); + this.setState({ + loading: false, + name: this.props.role.name, + description: this.props.role.description, + selectedPermissionIds: selectedPermissionIds, + }); + }); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + permissionClicked = (permission) => { + var selectedPermissionIds = _.clone(this.state.selectedPermissionIds); + if (selectedPermissionIds.indexOf(permission.id) === -1) { + selectedPermissionIds.push(permission.id); + } else { + _.pull(selectedPermissionIds, permission.id); + } + this.setState({ selectedPermissionIds: selectedPermissionIds }); + }; + + isValid = () => { + this.setState({ + nameError: false, + descriptionError: false, + }); + + var valid = true; + + if (isBlank(this.state.name)) { + this.setState({ nameError: 'Name is required' }); + valid = false; + } + + if (isBlank(this.state.description)) { + this.setState({ descriptionError: 'Description is required' }); + valid = false; + } + + return valid; + }; + + didChangeRole = () => { + if (this.state.name !== this.props.role.name) { return true; } + if (this.state.description !== this.props.role.description) { return true; } + + return false; + }; + + didChangePermissions = () => { + var originalPermissionIds = _.map(this.props.rolePermissions, rolePermission => { + return rolePermission.permission.id; + }); + if (_.xor(originalPermissionIds, this.state.selectedPermissionIds).length > 0) { return true; } + + return false; + }; + + savePermissions = () => { + if (this.didChangePermissions()) { + Api.updateRolePermissions(this.props.role.id, _.map(this.state.selectedPermissionIds, id => { + return { id: id }; + })).then(() => { + this.returnToList(); + }); + } else { + this.returnToList(); + } + }; + + returnToList = () => { + this.props.router.push({ + pathname: Constant.ROLES_PATHNAME, + }); + }; + + onSave = () => { + if (this.isValid()) { + if (this.didChangeRole()) { + if (this.state.isNew) { + Api.addRole({ + name: this.state.name, + description: this.state.description, + }).then(() => { + this.savePermissions(); + }); + } else { + Api.updateRole({ ...this.props.role, ...{ + name: this.state.name, + description: this.state.description, + }}).then(() => { + this.savePermissions(); + }); + } + } else { + this.savePermissions(); + } + } + }; + + render() { + var role = this.props.role; + + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ROLES_AND_PERMISSIONS) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return ( +
You do not have permission to view this page.
+ ); + } + + return
+
+ + +
+ + {(() => { + if (this.state.loading) { return
; } + + return
+ +
; + })()} + + {(() => { + if (this.state.loading) { return
; } + + return
+ + + + + Name * + + { this.state.nameError } + + + + + Description * + + { this.state.descriptionError } + + + + +
; + })()} +
+ + + {(() => { + if (this.state.loading ) { return
; } + + var permissions = _.sortBy(this.props.permissions, 'name'); + + return + + + + + + + + { + _.map(permissions, permission => { + var selected = this.state.selectedPermissionIds.indexOf(permission.id) !== -1; + return + + + ; + }) + } + +
NameDescription
{ permission.name }{ permission.description }
; + })()} +
+ +
; + } +} + + +function mapStateToProps(state) { + return { + currentUser: state.user, + role: state.models.role, + rolePermissions: state.models.rolePermissions, + permissions: state.lookups.permissions, + }; +} + +export default connect(mapStateToProps)(RolesDetail); diff --git a/client2/src/js/views/Rollover.jsx b/client2/src/js/views/Rollover.jsx new file mode 100644 index 000000000..17a2f7d1d --- /dev/null +++ b/client2/src/js/views/Rollover.jsx @@ -0,0 +1,188 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Button, Well } from 'react-bootstrap'; + +import * as Api from '../api'; +import * as Constant from '../constants'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import CheckboxControl from '../components/CheckboxControl.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import Confirm from '../components/Confirm.jsx'; +import Spinner from '../components/Spinner.jsx'; + +import { formatDateTimeUTCToLocal } from '../utils/date'; + + +class Rollover extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + rolloverStatus: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + checkListStep1: false, + checkListStep2: false, + checkListStep3: false, + refreshStatusTimerId: null, + }; + } + + componentDidMount() { + var user = this.props.currentUser; + var status = this.props.rolloverStatus; + + Api.getRolloverStatus(this.props.currentUser.district.id).then(() => { + this.setState({ loading: false }); + + if (!user.hasPermission(Constant.PERMISSION_DISTRICT_ROLLOVER) && !status.rolloverActive) { + // redirect to home page + this.props.router.push({ pathname: '/' }); + } + + if (status.rolloverActive && this.state.refreshStatusTimerId === null) { + this.startRefreshStatusTimer(); + } + }); + } + + componentDidUpdate() { + if (this.props.rolloverStatus.rolloverActive && this.state.refreshStatusTimerId === null) { + this.startRefreshStatusTimer(); + } + } + + startRefreshStatusTimer = () => { + var refreshStatusTimerId = setInterval(this.refreshStatus, 2000); // 2 seconds + this.setState({ refreshStatusTimerId: refreshStatusTimerId }); + }; + + refreshStatus = () => { + const districtId = this.props.currentUser.district.id; + + Api.getRolloverStatus(districtId).then(() => { + const status = this.props.rolloverStatus; + + if (!status.rolloverActive && this.state.refreshStatusTimerId !== null) { + clearInterval(this.state.refreshStatusTimerId); + this.setState({ refreshStatusTimerId: null }); + } + + if (status.rolloverComplete) { + // refresh fiscal years + Api.getFiscalYears(districtId); + } + }); + }; + + initiateRollover = () => { + Api.initiateRollover(this.props.currentUser.district.id); + }; + + dismissRolloverNotice = () => { + Api.dismissRolloverMessage(this.props.currentUser.district.id); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + renderContentRolloverActive = () => { + var status = this.props.rolloverStatus; + + return ( +
+
A roll over is currently in progress.
+
+
+ { status.progressPercentage }% Complete +
+
+
+ ); + }; + + renderContentRolloverComplete = () => { + return ( +
+

The hired equipment roll over has been completed on { formatDateTimeUTCToLocal(this.props.rolloverStatus.rolloverEndDate, Constant.DATE_TIME_READABLE) }.

+

Note: Please save/print out the new seniority lists for all equipments corresponding to each local area.

+ +
+ ); + }; + + renderContent = () => { + var rolloverButtonDisabled = !this.state.checkListStep1 || !this.state.checkListStep2 || !this.state.checkListStep3 || !this.state.checkListStep4; + + return ( + + +
+ + Verify all equipment hours have been entered in the system + + + Save the seniority list (pre-roll over) + + + Take note of any equipment currently hired + + + Release all blocked rotation lists, as the hiring order may change after the roll over + +
+ +
+ Note: + The roll over is an important annual process that recalculates the seniority for each piece of equipment across the district at the start of a fiscal year. Once triggered, this process is not reversible. In case you have any questions, please contact the primary coordinator for the process before proceeding with the hired equipment roll over. +
+ +
+

Please ensure all processes corresponding to the checklist are complete before rolling over.

If you are certain all tasks have been completed, click Yes to proceed with roll over. Otherwise, click No.

}> + +
+
+
+ ); + }; + + render() { + var status = this.props.rolloverStatus; + var user = this.props.currentUser; + + return
+ { user.districtName } Roll Over + +
+ {(() => { + if (this.state.loading) { + return
; + } else if (status.rolloverActive) { + return this.renderContentRolloverActive(); + } else if (status.rolloverComplete) { + return this.renderContentRolloverComplete(); + } else { + return this.renderContent(); + } + })()} +
+
; + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + rolloverStatus: state.lookups.rolloverStatus, + }; +} + +export default connect(mapStateToProps)(Rollover); diff --git a/client2/src/js/views/SeniorityList.jsx b/client2/src/js/views/SeniorityList.jsx new file mode 100644 index 000000000..dffb8b049 --- /dev/null +++ b/client2/src/js/views/SeniorityList.jsx @@ -0,0 +1,133 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Row, Col, ButtonToolbar, Button } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../api'; +import * as Constant from '../constants'; + +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import MultiDropdown from '../components/MultiDropdown.jsx'; + +import { formatDateTimeUTCToLocal } from '../utils/date'; + + +class SeniorityList extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + localAreas: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + selectedEquipmentTypeIds: [], + selectedLocalAreaIds: [], + }; + } + + componentDidMount() { + this.fetch(); + } + + fetch = () => { + Api.getDistrictEquipmentTypes(); + }; + + updateState = (state) => { + this.setState(state); + }; + + onLocalAreasChanged = () => { + this.setState({ selectedEquipmentTypeIds: [] }); + }; + + getFilteredEquipmentTypes = (localAreaIds) => { + return _.chain(this.props.districtEquipmentTypes.data) + .filter(type => type.equipmentCount > 0 && localAreaIds.length === 0 || _.filter(type.localAreas, localArea => _.includes(localAreaIds, localArea.id) && localArea.equipmentCount > 0).length > 0) + .sortBy('districtEquipmentName') + .value(); + }; + + downloadFile = (promise, filename, mimeType) => { + promise.then((response) => { + var blob; + if (window.navigator.msSaveBlob) { + blob = window.navigator.msSaveBlob(response, filename); + } else { + blob = new Blob([response], {type: mimeType}); + } + //Create a link element, hide it, direct + //it towards the blob, and then 'click' it programatically + let a = document.createElement('a'); + a.style.cssText = 'display: none'; + document.body.appendChild(a); + //Create a DOMString representing the blob + //and point the link element towards it + let url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + //programatically click the link to trigger the download + a.click(); + //release the reference to the file by revoking the Object URL + window.URL.revokeObjectURL(url); + }); + }; + + getRotationList = () => { + const promise = Api.equipmentSeniorityListDoc(this.state.selectedLocalAreaIds, this.state.selectedEquipmentTypeIds, false); + const filename = 'SeniorityList-' + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + '.docx'; + const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; + + this.downloadFile(promise, filename, mimeType); + }; + + render() { + var localAreas = _.chain(this.props.localAreas) + .sortBy('name') + .value(); + + var districtEquipmentTypes = this.getFilteredEquipmentTypes(this.state.selectedLocalAreaIds); + + return
+ Seniority List + + + + + + + + + + + + +
; + } +} + + +function mapStateToProps(state) { + return { + currentUser: state.user, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + localAreas: state.lookups.localAreas, + }; +} + +export default connect(mapStateToProps)(SeniorityList); diff --git a/client2/src/js/views/StatusLetters.jsx b/client2/src/js/views/StatusLetters.jsx new file mode 100644 index 000000000..51a34fdad --- /dev/null +++ b/client2/src/js/views/StatusLetters.jsx @@ -0,0 +1,174 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Row, Col, ButtonToolbar, Button } from "react-bootstrap"; +import _ from "lodash"; + +import * as Api from "../api"; +import * as Constant from "../constants"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; + +import { formatDateTimeUTCToLocal } from "../utils/date"; + +class StatusLetters extends React.Component { + static propTypes = { + localAreas: PropTypes.object, + owners: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + localAreaIds: [], + ownerIds: [], + }; + } + + componentDidMount() { + Api.getOwnersLite(); + } + + updateState = (state, callback) => { + this.setState(state, () => { + if (callback) { + callback(); + } + }); + }; + + downloadFile = (promise, filename, mimeType) => { + promise.then((response) => { + var blob; + if (window.navigator.msSaveBlob) { + blob = window.navigator.msSaveBlob(response, filename); + } else { + blob = new Blob([response], { type: mimeType }); + } + //Create a link element, hide it, direct + //it towards the blob, and then 'click' it programatically + let a = document.createElement("a"); + a.style.cssText = "display: none"; + document.body.appendChild(a); + //Create a DOMString representing the blob + //and point the link element towards it + let url = window.URL.createObjectURL(blob); + a.href = url; + a.download = filename; + //programatically click the link to trigger the download + a.click(); + //release the reference to the file by revoking the Object URL + window.URL.revokeObjectURL(url); + }); + }; + + getStatusLetters = () => { + const promise = Api.getStatusLettersDoc({ + localAreas: this.state.localAreaIds, + owners: this.state.ownerIds, + }); + const filename = + "StatusLetters-" + + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + + ".docx"; + const mimeType = + "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + + this.downloadFile(promise, filename, mimeType); + }; + + getMailingLabel = () => { + const promise = Api.getMailingLabelsDoc({ + localAreas: this.state.localAreaIds, + owners: this.state.ownerIds, + }); + const filename = + "MailingLabels-" + + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + + ".docx"; + const mimeType = + "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + + this.downloadFile(promise, filename, mimeType); + }; + + matchesLocalAreaFilter = (localAreaId) => { + if (this.state.localAreaIds.length === 0) { + return true; + } + + return _.includes(this.state.localAreaIds, localAreaId); + }; + + updateLocalAreaState = (state) => { + this.updateState(state, this.filterSelectedOwners); + }; + + filterSelectedOwners = () => { + var acceptableOwnerIds = _.map(this.getFilteredOwners(), "id"); + var ownerIds = _.intersection(this.state.ownerIds, acceptableOwnerIds); + this.updateState({ ownerIds: ownerIds }); + }; + + getFilteredOwners = () => { + return _.chain(this.props.owners.data) + .filter((x) => this.matchesLocalAreaFilter(x.localAreaId)) + .sortBy("organizationName") + .value(); + }; + + render() { + var localAreas = _.sortBy(this.props.localAreas, "name"); + var owners = this.getFilteredOwners(); + + return ( +
+ Status Letters + + + + + + + + + + + + +
+ ); + } +} + +function mapStateToProps(state) { + return { + localAreas: state.lookups.localAreas, + owners: state.lookups.owners.lite, + }; +} + +export default connect(mapStateToProps)(StatusLetters); diff --git a/client2/src/js/views/TimeEntry.jsx b/client2/src/js/views/TimeEntry.jsx new file mode 100644 index 000000000..ea886b434 --- /dev/null +++ b/client2/src/js/views/TimeEntry.jsx @@ -0,0 +1,488 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Link } from "react-router"; +import { + Alert, + Row, + Col, + ButtonToolbar, + Button, + ButtonGroup, + Glyphicon, + Form, +} from "react-bootstrap"; +import _ from "lodash"; + +import TimeEntryDialog from "./dialogs/TimeEntryDialog.jsx"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import store from "../store"; + +import AddButtonContainer from "../components/ui/AddButtonContainer.jsx"; +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import Favourites from "../components/Favourites.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; +import SortTable from "../components/SortTable.jsx"; +import Spinner from "../components/Spinner.jsx"; +import PrintButton from "../components/PrintButton.jsx"; +import Authorize from "../components/Authorize.jsx"; + +import { formatDateTime } from "../utils/date"; + +class TimeEntry extends React.Component { + static propTypes = { + projects: PropTypes.object, + localAreas: PropTypes.object, + owners: PropTypes.object, + equipment: PropTypes.object, + timeEntries: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showTimeEntryDialog: false, + allowMultipleTimeEntries: false, + rentalAgreementId: null, + timeEntryDialogProjectId: null, + search: { + projectIds: props.search.projectIds || [], + localAreaIds: props.search.localAreaIds || [], + ownerIds: props.search.ownerIds || [], + equipmentIds: props.search.equipmentIds || [], + }, + ui: { + sortField: props.ui.sortField || "localAreaLabel", + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + componentDidMount() { + Api.getProjectsCurrentFiscal(); + Api.getEquipmentTs(); + Api.getOwnersLiteTs(); + + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, (f) => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.projectIds.length > 0) { + searchParams.projects = this.state.search.projectIds; + } + + if (this.state.search.localAreaIds.length > 0) { + searchParams.localAreas = this.state.search.localAreaIds; + } + + if (this.state.search.ownerIds.length > 0) { + searchParams.owners = this.state.search.ownerIds; + } + + if (this.state.search.equipmentIds.length > 0) { + searchParams.equipment = this.state.search.equipmentIds; + } + + return searchParams; + }; + + fetch = () => { + Api.searchTimeEntries(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + projectIds: [], + localAreaIds: [], + ownerIds: [], + equipmentIds: [], + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ + type: Action.UPDATE_TIME_ENTRIES_SEARCH, + timeEntries: this.state.search, + }); + store.dispatch({ type: Action.CLEAR_TIME_ENTRIES }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState( + { search: { ...this.state.search, ...state, ...{ loaded: true } } }, + () => { + store.dispatch({ + type: Action.UPDATE_TIME_ENTRIES_SEARCH, + timeEntries: this.state.search, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_TIME_ENTRIES_UI, + timeEntries: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + openTimeEntryDialog = (timeEntry) => { + this.setState({ + timeEntryDialogProjectId: timeEntry ? timeEntry.projectId : null, + rentalAgreementId: timeEntry ? timeEntry.rentalAgreementId : null, + allowMultipleTimeEntries: !timeEntry, + showTimeEntryDialog: true, + }); + }; + + closeTimeEntryDialog = () => { + this.setState({ showTimeEntryDialog: false }); + if (this.props.timeEntries.loaded) { + this.fetch(); + } + }; + + renderResults = (addTimeEntryButton) => { + if (Object.keys(this.props.timeEntries.data).length === 0) { + return ( + No time entries {addTimeEntryButton} + ); + } + + var timeEntries = _.sortBy(this.props.timeEntries.data, (timeEntry) => { + var sortValue = timeEntry[this.state.ui.sortField]; + if (typeof sortValue === "string") { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.state.ui.sortDesc) { + _.reverse(timeEntries); + } + + return ( + + {_.map(timeEntries, (entry) => { + return ( + + {entry.localAreaLabel} + {entry.ownerCode} + + + {entry.ownerName} + + + + + {entry.equipmentCode} + + + {entry.equipmentDetails} + + + {entry.provincialProjectNumber + ? entry.provincialProjectNumber + : "N/A"} + + + {entry.hours} + {formatDateTime(entry.workedDate, "YYYY-MMM-DD")} + {formatDateTime(entry.enteredDate, "YYYY-MMM-DD")} + + + + + + + ); + })} + + ); + }; + + matchesProjectFilter = (projectIds) => { + if (this.state.search.projectIds.length === 0) { + return true; + } + + return _.intersection(this.state.search.projectIds, projectIds).length > 0; + }; + + matchesLocalAreaFilter = (localAreaId) => { + if (this.state.search.localAreaIds.length === 0) { + return true; + } + + return _.includes(this.state.search.localAreaIds, localAreaId); + }; + + matchesOwnerFilter = (ownerId) => { + if (this.state.search.ownerIds.length === 0) { + return true; + } + + return _.includes(this.state.search.ownerIds, ownerId); + }; + + updateProjectSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedOwners); + }; + + updateLocalAreaSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedOwners); + }; + + updateOwnerSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedEquipment); + }; + + filterSelectedOwners = () => { + var acceptableOwnerIds = _.map(this.getFilteredOwners(), "id"); + var ownerIds = _.intersection( + this.state.search.ownerIds, + acceptableOwnerIds + ); + this.updateSearchState( + { ownerIds: ownerIds }, + this.filterSelectedEquipment + ); + }; + + filterSelectedEquipment = () => { + var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), "id"); + var equipmentIds = _.intersection( + this.state.search.equipmentIds, + acceptableEquipmentIds + ); + this.updateSearchState({ equipmentIds: equipmentIds }); + }; + + getFilteredOwners = () => { + return _.chain(this.props.owners.data) + .filter( + (x) => + this.matchesProjectFilter(x.projectIds) && + this.matchesLocalAreaFilter(x.localAreaId) + ) + .sortBy("organizationName") + .value(); + }; + + getFilteredEquipment = () => { + return _.chain(this.props.equipment.data) + .filter( + (x) => + this.matchesProjectFilter(x.projectIds) && + this.matchesOwnerFilter(x.ownerId) && + this.matchesLocalAreaFilter(x.localAreaId) + ) + .sortBy("equipmentCode") + .value(); + }; + + render() { + var resultCount = ""; + if (this.props.timeEntries.loaded) { + resultCount = "(" + Object.keys(this.props.timeEntries.data).length + ")"; + } + + var projects = _.sortBy(this.props.projects.data, "name"); + var localAreas = _.sortBy(this.props.localAreas, "name"); + var owners = this.getFilteredOwners(); + var equipment = this.getFilteredEquipment(); + + return ( +
+ + Time Entry {resultCount} + + + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.timeEntries.loading) { + return ( +
+ +
+ ); + } + + var addTimeEntryButton = ( + + + + ); + + if (this.props.timeEntries.loaded) { + return this.renderResults(addTimeEntryButton); + } + + return {addTimeEntryButton}; + })()} + {this.state.showTimeEntryDialog && ( + + )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + projects: state.lookups.projectsCurrentFiscal, + localAreas: state.lookups.localAreas, + owners: state.lookups.owners.ts, + equipment: state.lookups.equipment.ts, + timeEntries: state.models.timeEntries, + favourites: state.models.favourites.timeEntry, + search: state.search.timeEntries, + ui: state.ui.timeEntries, + }; +} + +export default connect(mapStateToProps)(TimeEntry); diff --git a/client2/src/js/views/TopNav.jsx b/client2/src/js/views/TopNav.jsx new file mode 100644 index 000000000..e18d1848b --- /dev/null +++ b/client2/src/js/views/TopNav.jsx @@ -0,0 +1,391 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import _ from "lodash"; +import { + Navbar, + Nav, + NavItem, + NavDropdown, + MenuItem, + OverlayTrigger, + Dropdown, + Popover, + Button, + Glyphicon, + ControlLabel, + FormGroup, +} from "react-bootstrap"; +import { LinkContainer } from "react-router-bootstrap"; + +import * as Constant from "../constants"; +import * as Api from "../api"; + +import Spinner from "../components/Spinner.jsx"; +import DropdownControl from "../components/DropdownControl.jsx"; + +import { formatDateTimeUTCToLocal } from "../utils/date"; +import { currentPathStartsWith } from "../utils/routes"; + +class TopNav extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + showWorkingIndicator: PropTypes.bool, + showNav: PropTypes.bool, + currentUserDistricts: PropTypes.object, + rolloverStatus: PropTypes.object, + }; + + static defaultProps = { + showNav: true, + }; + + updateUserDistrict = (state) => { + var district = _.find(this.props.currentUserDistricts.data, (district) => { + return district.district.id === state.districtId; + }); + Api.switchUserDistrict(district.id).then(() => { + window.location.reload(); + this.context.router.push({ pathname: Constant.HOME_PATHNAME }); + }); + }; + + logout = () => { + Api.logoffUser().then((logoffUrl) => { + if (logoffUrl) { + window.location.href = logoffUrl; + } + }); + }; + + dismissRolloverNotice = () => { + Api.dismissRolloverMessage(this.props.currentUser.district.id); + }; + + render() { + var userDistricts = _.map( + this.props.currentUserDistricts.data, + (district) => { + return { + ...district, + districtName: district.district.name, + id: district.district.id, + }; + } + ); + + var navigationDisabled = this.props.rolloverStatus.rolloverActive; + + var environmentClass = ""; + if (this.props.currentUser.environment === "Development") { + environmentClass = "env-dev"; + } else if (this.props.currentUser.environment === "Test") { + environmentClass = "env-test"; + } else if (this.props.currentUser.environment === "Training") { + environmentClass = "env-trn"; + } else if (this.props.currentUser.environment === "UAT") { + environmentClass = "env-uat"; + } + + return ( + + ); + } +} + +TopNav.contextTypes = { + router: PropTypes.object.isRequired, +}; + +function mapStateToProps(state) { + return { + currentUser: state.user, + showWorkingIndicator: state.ui.requests.waiting, + currentUserDistricts: state.models.currentUserDistricts, + rolloverStatus: state.lookups.rolloverStatus, + }; +} + +export default connect(mapStateToProps, null, null, { pure: false })(TopNav); diff --git a/client2/src/js/views/Users.jsx b/client2/src/js/views/Users.jsx new file mode 100644 index 000000000..df7c9a231 --- /dev/null +++ b/client2/src/js/views/Users.jsx @@ -0,0 +1,273 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, InputGroup, Form } from 'react-bootstrap'; +import { LinkContainer } from 'react-router-bootstrap'; +import _ from 'lodash'; + +import UsersEditDialog from './dialogs/UsersEditDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; +import PageHeader from '../components/ui/PageHeader.jsx'; +import SearchBar from '../components/ui/SearchBar.jsx'; +import CheckboxControl from '../components/CheckboxControl.jsx'; +import Confirm from '../components/Confirm.jsx'; +import Favourites from '../components/Favourites.jsx'; +import FormInputControl from '../components/FormInputControl.jsx'; +import MultiDropdown from '../components/MultiDropdown.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import Authorize from '../components/Authorize.jsx'; + +class Users extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + users: PropTypes.object, + user: PropTypes.object, + districts: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + showUsersEditDialog: false, + + search: { + selectedDistrictsIds: props.search.selectedDistrictsIds || [], + surname: props.search.surname || '', + hideInactive: props.search.hideInactive || true, + }, + + ui : { + sortField: props.ui.sortField || 'surname', + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = { + includeInactive: !this.state.search.hideInactive, + surname: this.state.search.surname, + }; + + if (this.state.search.selectedDistrictsIds.length > 0) { + searchParams.districts = this.state.search.selectedDistrictsIds; + } + + return searchParams; + }; + + componentDidMount() { + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchUsers(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + selectedDistrictsIds: [], + surname: '', + hideInactive: true, + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ type: Action.UPDATE_USERS_SEARCH, users: this.state.search }); + store.dispatch({ type: Action.CLEAR_USERS }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ + store.dispatch({ type: Action.UPDATE_USERS_SEARCH, users: this.state.search }); + if (callback) { callback(); } + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_USERS_UI, users: this.state.ui }); + if (callback) { callback(); } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + delete = (user) => { + Api.deleteUser(user).then(() => { + this.fetch(); + }); + }; + + openUsersEditDialog = () => { + this.setState({ showUsersEditDialog: true }); + }; + + closeUsersEditDialog = () => { + this.setState({ showUsersEditDialog: false }); + }; + + onUserSaved = (user) => { + this.closeUsersEditDialog(); + this.props.router.push({ + pathname: `${ Constant.USERS_PATHNAME }/${ user.id }`, + }); + }; + + renderResults = (addUserButton) => { + if (Object.keys(this.props.users.data).length === 0) { + return No users { addUserButton }; + } + + var users = _.sortBy(this.props.users.data, this.state.ui.sortField); + if (this.state.ui.sortDesc) { + _.reverse(users); + } + + return + { + _.map(users, (user) => { + return + { user.surname } + { user.givenName } + { user.smUserId } + { user.districtName } + + + + }> + + + + + + + + + ; + }) + } + ; + }; + + render() { + var districts = _.sortBy(this.props.districts, 'name'); + + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_USER_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return ( +
You do not have permission to view this page.
+ ); + } + + var resultCount = ''; + if (this.props.users.loaded) { + resultCount = '(' + Object.keys(this.props.users.data).length + ')'; + } + + return
+ Users { resultCount } + + + + + +
+ + + + + + Surname + + + Hide Inactive + + + + + + + + + + +
+
+ + {(() => { + if (this.props.users.loading) { + return
; + } + + var addUserButton = ; + + if (this.props.users.loaded) { + return this.renderResults(addUserButton); + } + + return { addUserButton }; + })()} + + { this.state.showUsersEditDialog && + + } +
; + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + users: state.models.users, + user: state.models.user, + districts: state.lookups.districts, + favourites: state.models.favourites.user, + search: state.search.users, + ui: state.ui.users, + }; +} + +export default connect(mapStateToProps)(Users); diff --git a/client2/src/js/views/UsersDetail.jsx b/client2/src/js/views/UsersDetail.jsx new file mode 100644 index 000000000..007ce6696 --- /dev/null +++ b/client2/src/js/views/UsersDetail.jsx @@ -0,0 +1,450 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Well, Row, Col, Alert, Label, Button, Glyphicon, Popover, FormGroup, HelpBlock, ButtonGroup } from 'react-bootstrap'; +import _ from 'lodash'; +import Promise from 'bluebird'; + +import UserRoleAddDialog from './dialogs/UserRoleAddDialog.jsx'; +import UsersEditDialog from './dialogs/UsersEditDialog.jsx'; +import DistrictEditDialog from './dialogs/DistrictEditDialog.jsx'; + +import * as Action from '../actionTypes'; +import * as Api from '../api'; +import * as Constant from '../constants'; +import store from '../store'; + +import CheckboxControl from '../components/CheckboxControl.jsx'; +import ColDisplay from '../components/ColDisplay.jsx'; +import DateControl from '../components/DateControl.jsx'; +import OverlayTrigger from '../components/OverlayTrigger.jsx'; +import SortTable from '../components/SortTable.jsx'; +import Spinner from '../components/Spinner.jsx'; +import Confirm from '../components/Confirm.jsx'; +import TableControl from '../components/TableControl.jsx'; +import Form from '../components/Form.jsx'; +import PrintButton from '../components/PrintButton.jsx'; +import ReturnButton from '../components/ReturnButton.jsx'; +import SubHeader from '../components/ui/SubHeader.jsx'; +import Authorize from '../components/Authorize.jsx'; + +import { daysFromToday, formatDateTime, today, isValidDate, toZuluTime } from '../utils/date'; +import { isBlank, notBlank } from '../utils/string'; +import { sort, caseInsensitiveSort } from '../utils/array.js'; + + +class UsersDetail extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + user: PropTypes.object, + ui: PropTypes.object, + userDistricts: PropTypes.object, + districts: PropTypes.object, + params: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + + district: {}, + + showEditDialog: false, + showUserRoleDialog: false, + showDistrictEditDialog: false, + + ui: { + // User roles + sortField: props.ui.sortField || 'roleName', + sortDesc: props.ui.sortDesc === true, + showExpiredOnly: false, + }, + }; + } + + componentDidMount() { + // if new user + if (this.props.params.userId === '0') { + // Clear the user store + store.dispatch({ type: Action.UPDATE_USER, user: { + id: 0, + active: true, + district: { id: 0, name: '' }, + groupIds: [], + + }}); + // Open editor to add new user + this.openEditDialog(); + } else { + this.fetch(); + } + } + + componentWillReceiveProps(nextProps) { + if (this.props.params.userId !== nextProps.params.userId) { + this.fetch(); + } + } + + fetch = () => { + this.setState({ loading: true }); + Promise.all([ + Api.getUser(this.props.params.userId), + Api.getUserDistricts(this.props.params.userId), + ]).then(() => { + this.setState({ loading: false }); + }); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_USER_ROLES_UI, userRoles: this.state.ui }); + if (callback) { callback(); } + }); + }; + + openEditDialog = () => { + this.setState({ showEditDialog: true }); + }; + + closeEditDialog = () => { + this.setState({ showEditDialog: false }); + }; + + onUserSaved = () => { + this.closeEditDialog(); + }; + + onCloseEdit = () => { + this.closeEditDialog(); + if (this.props.params.userId === '0') { + // Go back to user list if cancelling new user + this.props.router.push({ + pathname: Constant.USERS_PATHNAME, + }); + } + }; + + openUserRoleDialog = () => { + this.setState({ showUserRoleDialog: true }); + }; + + closeUserRoleDialog = () => { + this.setState({ showUserRoleDialog: false }); + }; + + updateUserRole = (userRole) => { + // The API call updates all of the user's user roles so we have to + // include them all in this call, modifying the one that has just + // been expired. + var userRoles = this.props.user.userRoles.map(ur => { + return { + roleId: ur.roleId, + effectiveDate: ur.effectiveDate, + expiryDate: userRole.id === ur.id ? userRole.expiryDate : ur.expiryDate, + }; + }); + + Api.updateUserRoles(this.props.user.id, userRoles); + this.closeUserRoleDialog(); + }; + + openDistrictEditDialog = () => { + this.setState({ showDistrictEditDialog: true }); + }; + + closeDistrictEditDialog = () => { + this.setState({ showDistrictEditDialog: false }); + }; + + addUserDistrict = () => { + this.setState({ district: { id: 0 }, showDistrictEditDialog: true }); + }; + + editUserDistrict = (district) => { + this.setState({ district, showDistrictEditDialog: true }); + }; + + districtSaved = (district, districts) => { + this.updateCurrentUserDistricts(districts); + this.closeDistrictEditDialog(); + }; + + deleteDistrict = (district) => { + Api.deleteUserDistrict(district).then((response) => { + this.updateCurrentUserDistricts(response.data); + }); + }; + + updateCurrentUserDistricts = (districts) => { + if (this.props.user.id === this.props.currentUser.id) { + store.dispatch({ type: Action.CURRENT_USER_DISTRICTS, currentUserDistricts: districts }); + } + }; + + render() { + const { loading } = this.state; + const { user } = this.props; + + if (!this.props.currentUser.hasPermission(Constant.PERMISSION_USER_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { + return ( +
You do not have permission to view this page.
+ ); + } + + return
+
+ + + {!loading && ( + + )} + + +
+ + +
+ +
+ +
+

User: { loading ? '...' : user.fullName }

+
+ + + + + + {(() => { + if (loading) { return
; } + + return + + { user.givenName } + + + { user.surname } + + + { user.smUserId } + + + { user.email } + + + { user.districtName } + + + { user.agreementCity } + + ; + })()} +
+ +
+ + + + + {(() => { + var addDistrictButton = ; + + if (loading) { return
; } + + if (this.props.userDistricts.data.length === 0) { return No Districts { addDistrictButton }; } + + const userDistricts = sort(this.props.userDistricts.data, ['isPrimary', 'district.name'], ['asc', 'asc'], caseInsensitiveSort); + + return ( + + { + _.map(userDistricts, (district) => { + return + { district.isPrimary && }{ district.district.name } + + { !district.isPrimary && + + + }> + + + + + + } + + ; + }) + } + + ); + })()} +
+ +
+ + + +

Access + Show Expired Only +

+ {(() => { + if (loading ) { return
; } + + var addUserRoleButton = ; + + var userRoles = _.filter(user.userRoles, userRole => { + var include = notBlank(userRole.roleName); + if (this.state.ui.showExpiredOnly) { + include = include && userRole.expiryDate && daysFromToday(userRole.expiryDate) < 0; + } + return include; + }); + if (userRoles.length === 0) { return No roles { addUserRoleButton }; } + + userRoles = _.sortBy(userRoles, this.state.ui.sortField); + if (this.state.ui.sortDesc) { + _.reverse(userRoles); + } + + var headers = [ + { field: 'roleName', title: 'Role' }, + { field: 'effectiveDateSort', title: 'Effective Date' }, + { field: 'expiryDateSort', title: 'Expiry Date' }, + { field: 'addUserRole', title: 'Add User Role', style: { textAlign: 'right' }, + node: addUserRoleButton, + }, + ]; + + return + { + _.map(userRoles, (userRole) => { + return + { userRole.roleName } + { formatDateTime(userRole.effectiveDate, Constant.DATE_FULL_MONTH_DAY_YEAR) } + { formatDateTime(userRole.expiryDate, Constant.DATE_FULL_MONTH_DAY_YEAR) } +  { daysFromToday(userRole.expiryDate) < 0 ? : '' } + + + { + userRole.expiryDate ? null : + + } + > + + + + } + + ; + }) + } + ; + })()} +
+ +
+
+ { this.state.showEditDialog && ( + + )} + { this.state.showUserRoleDialog && ( + + )} + { this.state.showDistrictEditDialog && ( + + )} +
; + } +} + +class ExpireOverlay extends React.Component { + static propTypes = { + userRole: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + hide: PropTypes.func, + }; + + constructor(props) { + super(props); + + this.state = { + expiryDate: today(), + expiryDateError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + saveUserRole = () => { + this.setState({ expiryDateError: false }); + + if (isBlank(this.state.expiryDate)) { + this.setState({ expiryDateError: 'Expiry date is required' }); + } else if (!isValidDate(this.state.expiryDate)) { + this.setState({ expiryDateError: 'Expiry date not valid' }); + } else { + this.props.onSave({ ...this.props.userRole, ...{ + expiryDate: toZuluTime(this.state.expiryDate), + roleId: this.props.userRole.role.id, + }}); + this.props.hide(); + } + }; + + render() { + var props = _.omit(this.props, 'onSave', 'hide', 'userRole'); + return +
+ + + { this.state.expiryDateError } + + +
+
; + } +} + + + +function mapStateToProps(state) { + return { + currentUser: state.user, + user: state.models.user, + ui: state.ui.userRoles, + userDistricts: state.models.userDistricts, + districts: state.lookups.districts, + }; +} + +export default connect(mapStateToProps)(UsersDetail); diff --git a/client2/src/js/views/Version.jsx b/client2/src/js/views/Version.jsx new file mode 100644 index 000000000..0d0297e2e --- /dev/null +++ b/client2/src/js/views/Version.jsx @@ -0,0 +1,256 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Well, Button, Glyphicon } from "react-bootstrap"; + +import * as Api from "../api"; +import * as Constant from "../constants"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import ColDisplay from "../components/ColDisplay.jsx"; +import Spinner from "../components/Spinner.jsx"; +import Unimplemented from "../components/Unimplemented.jsx"; +import PrintButton from "../components/PrintButton.jsx"; + +import { formatDateTime } from "../utils/date"; +import { request } from "../utils/http"; + +class Version extends React.Component { + static propTypes = { + version: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + showRawSection: false, + buildtime: "", + version: "", + commit: "", + }; + } + + componentDidMount() { + this.setState({ loading: true }); + Api.getVersion().finally(() => { + this.fetchLocal().finally(() => { + this.setState({ loading: false }); + }); + }); + } + + fetchLocal = () => { + return request("buildinfo.html", { silent: true }) + .then((xhr) => { + if (xhr.status === 200) { + const parser = new DOMParser(); + const doc = parser.parseFromString(xhr.responseText, "text/html"); + + this.setState({ + buildTime: doc.getElementById("buildtime").dataset.buildtime, + version: doc.getElementById("version").textContent, + commit: doc.getElementById("commit").textContent, + }); + } + }) + .catch((err) => { + console.error("Failed to find buildinfo: ", err); + }); + }; + + showRaw = (e) => { + if (this.state.showRawSection) { + this.setState({ showRawSection: false }); + e.target.textContent = "Show Raw Versions"; + } else { + this.setState({ showRawSection: true }); + e.target.textContent = "Hide Raw Versions"; + } + }; + + email = () => {}; + + render() { + return ( +
+ + Version +
+ + + + +
+
+ + {(() => { + if (this.state.loading) { + return ( +
+ +
+ ); + } + + var applicationVersion = {}; + if ( + this.props.version.applicationVersions && + this.props.version.applicationVersions.length > 0 + ) { + applicationVersion = this.props.version.applicationVersions[0]; + } + var databaseVersion = {}; + if ( + this.props.version.databaseVersions && + this.props.version.databaseVersions.length > 0 + ) { + databaseVersion = this.props.version.databaseVersions[0]; + } + + return ( +
+ +

Client

+
+ + MOTI Hired Equipment Tracking System + + + {formatDateTime( + this.state.buildTime, + Constant.DATE_TIME_READABLE + )} + + + {navigator.userAgent} + +
+
+ +

Application

+
+ + {applicationVersion.title} + + + {formatDateTime( + applicationVersion.fileCreationTime, + Constant.DATE_TIME_READABLE + )} + + + {applicationVersion.informationalVersion} + + + {applicationVersion.targetFramework} + + + {applicationVersion.buildVersion} + + + {applicationVersion.environment} + +
+
+ +

Database

+
+ + {databaseVersion.database} + + + {databaseVersion.server} + + + {databaseVersion.version} + + + {databaseVersion.buildVersion} + + + {databaseVersion.environment} + +
+
+ + +
{JSON.stringify(this.props.version)}
+
+
+ ); + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + version: state.version, + }; +} + +export default connect(mapStateToProps)(Version); diff --git a/client2/src/js/views/WcbCglCoverage.jsx b/client2/src/js/views/WcbCglCoverage.jsx new file mode 100644 index 000000000..ef6def6a8 --- /dev/null +++ b/client2/src/js/views/WcbCglCoverage.jsx @@ -0,0 +1,350 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { Link } from "react-router"; +import { + Alert, + Row, + Col, + ButtonToolbar, + Button, + ButtonGroup, +} from "react-bootstrap"; +import _ from "lodash"; +import Moment from "moment"; + +import * as Action from "../actionTypes"; +import * as Api from "../api"; +import * as Constant from "../constants"; +import store from "../store"; + +import PageHeader from "../components/ui/PageHeader.jsx"; +import SearchBar from "../components/ui/SearchBar.jsx"; +import DateControl from "../components/DateControl.jsx"; +import Favourites from "../components/Favourites.jsx"; +import Form from "../components/Form.jsx"; +import MultiDropdown from "../components/MultiDropdown.jsx"; +import SortTable from "../components/SortTable.jsx"; +import Spinner from "../components/Spinner.jsx"; +import PrintButton from "../components/PrintButton.jsx"; + +import { formatDateTime, toZuluTime } from "../utils/date"; + +class WcbCglCoverage extends React.Component { + static propTypes = { + localAreas: PropTypes.object, + owners: PropTypes.object, + ownersCoverage: PropTypes.object, + favourites: PropTypes.object, + search: PropTypes.object, + ui: PropTypes.object, + router: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: true, + search: { + localAreaIds: props.search.localAreaIds || [], + ownerIds: props.search.ownerIds || [], + wcbExpiry: props.search.wcbExpiry || "", + cglExpiry: props.search.cglExpiry || "", + }, + ui: { + sortField: props.ui.sortField || "localAreaLabel", + sortDesc: props.ui.sortDesc === true, + }, + }; + } + + buildSearchParams = () => { + var searchParams = {}; + + if (this.state.search.localAreaIds.length > 0) { + searchParams.localAreas = this.state.search.localAreaIds; + } + + if (this.state.search.ownerIds.length > 0) { + searchParams.owners = this.state.search.ownerIds; + } + + var wcbExpiryDate = Moment(this.state.search.wcbExpiry); + if (wcbExpiryDate && wcbExpiryDate.isValid()) { + searchParams.wcbExpiry = toZuluTime(wcbExpiryDate.startOf("day")); + } + + var cglExpiryDate = Moment(this.state.search.cglExpiry); + if (cglExpiryDate && cglExpiryDate.isValid()) { + searchParams.cglExpiry = toZuluTime(cglExpiryDate.startOf("day")); + } + + return searchParams; + }; + + componentDidMount() { + Api.getOwnersLite(); + + // If this is the first load, then look for a default favourite + if (_.isEmpty(this.props.search)) { + var defaultFavourite = _.find(this.props.favourites, (f) => f.isDefault); + if (defaultFavourite) { + this.loadFavourite(defaultFavourite); + } + } + } + + fetch = () => { + Api.searchOwnersCoverage(this.buildSearchParams()); + }; + + search = (e) => { + e.preventDefault(); + this.fetch(); + }; + + clearSearch = () => { + var defaultSearchParameters = { + localAreaIds: [], + ownerIds: [], + wcbExpiry: "", + cglExpiry: "", + }; + + this.setState({ search: defaultSearchParameters }, () => { + store.dispatch({ + type: Action.UPDATE_OWNERS_COVERAGE_SEARCH, + ownersCoverage: this.state.search, + }); + store.dispatch({ type: Action.CLEAR_OWNERS_COVERAGE }); + }); + }; + + updateSearchState = (state, callback) => { + this.setState( + { search: { ...this.state.search, ...state, ...{ loaded: true } } }, + () => { + store.dispatch({ + type: Action.UPDATE_OWNERS_COVERAGE_SEARCH, + ownersCoverage: this.state.search, + }); + if (callback) { + callback(); + } + } + ); + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state } }, () => { + store.dispatch({ + type: Action.UPDATE_OWNERS_COVERAGE_UI, + ownersCoverage: this.state.ui, + }); + if (callback) { + callback(); + } + }); + }; + + loadFavourite = (favourite) => { + this.updateSearchState(JSON.parse(favourite.value), this.fetch); + }; + + renderResults = () => { + if (Object.keys(this.props.ownersCoverage.data).length === 0) { + return No results; + } + + var ownersCoverage = _.sortBy(this.props.ownersCoverage.data, (entry) => { + var sortValue = entry[this.state.ui.sortField]; + if (typeof sortValue === "string") { + return sortValue.toLowerCase(); + } + return sortValue; + }); + + if (this.state.ui.sortDesc) { + _.reverse(ownersCoverage); + } + + return ( + + {_.map(ownersCoverage, (entry) => { + return ( + + {entry.localAreaLabel} + {entry.ownerCode} + + + {entry.organizationName} + + + {entry.primaryContactNumber} + {entry.primaryContactCell} + {entry.wcbNumber} + {formatDateTime(entry.wcbExpiryDate, "YYYY-MMM-DD")} + {entry.cglNumber} + {formatDateTime(entry.cglExpiryDate, "YYYY-MMM-DD")} + + ); + })} + + ); + }; + + matchesLocalAreaFilter = (localAreaId) => { + if (this.state.search.localAreaIds.length === 0) { + return true; + } + + return _.includes(this.state.search.localAreaIds, localAreaId); + }; + + updateLocalAreaSearchState = (state) => { + this.updateSearchState(state, this.filterSelectedOwners); + }; + + filterSelectedOwners = () => { + var acceptableOwnerIds = _.map(this.getFilteredOwners(), "id"); + var ownerIds = _.intersection( + this.state.search.ownerIds, + acceptableOwnerIds + ); + this.updateSearchState( + { ownerIds: ownerIds }, + this.filterSelectedEquipment + ); + }; + + getFilteredOwners = () => { + return _.chain(this.props.owners.data) + .filter((x) => this.matchesLocalAreaFilter(x.localAreaId)) + .sortBy("organizationName") + .value(); + }; + + render() { + var resultCount = ""; + if (this.props.ownersCoverage.loaded) { + resultCount = + "(" + Object.keys(this.props.ownersCoverage.data).length + ")"; + } + + var localAreas = _.sortBy(this.props.localAreas, "name"); + var owners = this.getFilteredOwners(); + + return ( +
+ + WCB / CGL Coverage {resultCount} + + + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + {(() => { + if (this.props.ownersCoverage.loading) { + return ( +
+ +
+ ); + } + if (this.props.ownersCoverage.loaded) { + return this.renderResults(); + } + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + localAreas: state.lookups.localAreas, + owners: state.lookups.owners.lite, + ownersCoverage: state.models.ownersCoverage, + favourites: state.models.favourites.ownersCoverage, + search: state.search.ownersCoverage, + ui: state.ui.ownersCoverage, + }; +} + +export default connect(mapStateToProps)(WcbCglCoverage); diff --git a/client2/src/js/views/dialogs/AttachmentAddDialog.jsx b/client2/src/js/views/dialogs/AttachmentAddDialog.jsx new file mode 100644 index 000000000..c3dbd89b3 --- /dev/null +++ b/client2/src/js/views/dialogs/AttachmentAddDialog.jsx @@ -0,0 +1,153 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + +class AttachmentAddDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + equipment: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + forms: [{ + typeName: '', + attachmentError: '', + }], + }; + } + + updateState = (state, index) => { + const forms = this.state.forms.slice(); + + forms[index].typeName = state.typeName; + + this.setState({forms}); + }; + + didChange = () => { + if (this.state.typeName !== '') { return true; } + + return false; + }; + + isValid = () => { + const forms = this.state.forms.slice(); + + var valid = false; + + forms.forEach((form) => { + const formIsValid = !isBlank(form.typeName); + + form.attachmentError = formIsValid ? '' : 'Attachment is required'; + + valid = formIsValid; + }); + + this.setState({forms}); + + return valid; + }; + + addInput = () => { + if (this.state.forms.length < 10) { + const forms = this.state.forms.slice(); // shallow clone + + forms.push({ + typeName: '', + attachmentError: '', + }); + + this.setState({forms}); + } + }; + + removeInput = () => { + if (this.state.forms.length > 1) { + let forms = this.state.forms.slice(); + forms.splice(forms.length - 1, 1); + this.setState({forms}); + } + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const attachmentTypeNames = this.state.forms.map((form) => form.typeName); + + const promise = Api.addPhysicalAttachments(this.props.equipment.id, attachmentTypeNames); + + promise.then(() => { + attachmentTypeNames.forEach((typeName) => { + Log.equipmentAttachmentAdded(this.props.equipment, typeName); + }); + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + const { forms } = this.state; + + return ( + +
+ { forms.map((form, i) => ( + + Attachment + this.updateState(state, i) }/> + { form.attachmentError } + + ))} +
+
+ { forms.length > 1 && ( + + )} + { forms.length < 10 && ( + + )} +
+
+ ); + } +} + +export default AttachmentAddDialog; diff --git a/client2/src/js/views/dialogs/AttachmentEditDialog.jsx b/client2/src/js/views/dialogs/AttachmentEditDialog.jsx new file mode 100644 index 000000000..b2c25c146 --- /dev/null +++ b/client2/src/js/views/dialogs/AttachmentEditDialog.jsx @@ -0,0 +1,102 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +class AttachmentEditDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + equipment: PropTypes.object.isRequired, + attachment: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + typeName: props.attachment.typeName, + concurrencyControlNumber: props.attachment.concurrencyControlNumber || 0, + attachmentError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.typeName !== '') { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + attachmentError: '', + }); + + var valid = true; + + if (this.state.typeName === '') { + this.setState({ attachmentError: 'Attachment is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const attachment = { + id: this.props.attachment.id, + typeName: this.state.typeName, + concurrencyControlNumber: this.state.concurrencyControlNumber, + equipment: { id: this.props.equipment.id }, + }; + + const promise = Api.updatePhysicalAttachment(attachment); + + promise.then(() => { + Log.equipmentAttachmentUpdated(this.props.equipment, attachment.typeName); + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + return ( + + + Attachment + + { this.state.attachmentError } + + + ); + } +} + +export default AttachmentEditDialog; diff --git a/client2/src/js/views/dialogs/CloneDialog.jsx b/client2/src/js/views/dialogs/CloneDialog.jsx new file mode 100644 index 000000000..5051e6367 --- /dev/null +++ b/client2/src/js/views/dialogs/CloneDialog.jsx @@ -0,0 +1,184 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; + +import _ from 'lodash'; +import Promise from 'bluebird'; + +import { Row, Col, Radio, Alert, FormGroup, ControlLabel } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; + +import FormDialog from '../../components/FormDialog.jsx'; +import TableControl from '../../components/TableControl.jsx'; +import DropdownControl from '../../components/DropdownControl.jsx'; +import Spinner from '../../components/Spinner.jsx'; + +import { formatDateTime } from '../../utils/date'; + +class CloneDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + rentalAgreement: PropTypes.object, + projectRentalAgreements: PropTypes.object, + equipmentRentalAgreements: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + cloneRentalAgreementError: '', + loading: false, + rentalAgreementId: '', + type: Constant.BY_PROJECT, + }; + } + + componentDidMount() { + var getProjectRentalAgreementsPromise = Api.getProjectRentalAgreements(this.props.rentalAgreement.project.id); + var getEquipmentRentalAgreementsPromise = Api.getEquipmentRentalAgreements(this.props.rentalAgreement.equipment.id); + this.setState({ loading: true }); + return Promise.all([getProjectRentalAgreementsPromise, getEquipmentRentalAgreementsPromise]).finally(() => { + this.setState({ loading: false }); + }); + } + + updateState = (e) => { + this.setState({ [e.target.name]: e.target.value }); + }; + + updateDropdownState = (state) => { + this.setState(state); + }; + + didChange = () => { + if (this.state.rentalAgreementId !== '') { return true; } + + return false; + }; + + isValid = () => { + return true; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var data = { + projectId: this.props.rentalAgreement.project.id, + agreementToCloneId: parseInt(this.state.rentalAgreementId, 10), + rentalAgreementId: this.props.rentalAgreement.id, + equipmentId: this.props.rentalAgreement.equipmentId, + }; + + const promise = this.state.type === Constant.BY_EQUIPMENT ? Api.cloneEquipmentRentalAgreement(data) : Api.cloneProjectRentalAgreement(data); + + promise.then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.onClose(); + }).catch((error) => { + if (error.status === 400 && (error.errorCode === 'HETS-11' || error.errorCode === 'HETS-12' || error.errorCode === 'HETS-13')) { + this.setState({ isSaving: false, cloneRentalAgreementError: 'There was an error cloning the rental agreement.' }); + } else { + throw error; + } + }); + } else { + this.onClose(); + } + } + }; + + onClose = () => { + this.setState({ cloneRentalAgreementError: '' }); + this.props.onClose(); + }; + + render() { + var headers = [ + { field: 'blank' }, + { field: 'equipmentId', title: 'Equipment ID' }, + { field: 'equipmentType', title: 'Equipment Type' }, + { field: 'equipmentMakeModelSize', title: 'Year Make/Model/Size' }, + { field: 'projectName', title: 'Project Name' }, + { field: 'rentalAgreementNumber', title: 'Rental Agreement #' }, + { field: 'datedOn', title: 'Dated On' }, + ]; + + var rentalAgreements = _.filter(this.state.type === Constant.BY_PROJECT ? + this.props.projectRentalAgreements.data : this.props.equipmentRentalAgreements.data, item => { + return item.id !== this.props.rentalAgreement.id; + }); + + rentalAgreements = _.reverse(_.sortBy(rentalAgreements, function(rentalAgreement) { + return rentalAgreement.datedOn; + })); + + return ( + + + + + Rental Agreements + + +

Select a rental agreement to clone...

+ {(() => { + if (this.state.loading) { return
; } + + if (!rentalAgreements || Object.keys(rentalAgreements).length === 0) { return No rental agreements.; } + + return ( + + { + _.map(rentalAgreements, (rentalAgreement) => { + return + + { rentalAgreement.equipment.equipmentCode } + { rentalAgreement.equipment.districtEquipmentType.districtEquipmentName } + {`${rentalAgreement.equipment.year} ${rentalAgreement.equipment.make}/${rentalAgreement.equipment.model}/${rentalAgreement.equipment.size}`} + { rentalAgreement.project && rentalAgreement.project.name } + { rentalAgreement.number } + { formatDateTime(rentalAgreement.datedOn, 'YYYY-MMM-DD') } + ; + }) + } + + ); + })()} + { this.state.cloneRentalAgreementError && + { this.state.cloneRentalAgreementError } + } + +
+
+ ); + } +} + +function mapStateToProps(state) { + return { + projectRentalAgreements: state.models.projectRentalAgreements, + equipmentRentalAgreements: state.models.equipmentRentalAgreements, + }; +} + +export default connect(mapStateToProps)(CloneDialog); diff --git a/client2/src/js/views/dialogs/ConditionAddEditDialog.jsx b/client2/src/js/views/dialogs/ConditionAddEditDialog.jsx new file mode 100644 index 000000000..3a38a3267 --- /dev/null +++ b/client2/src/js/views/dialogs/ConditionAddEditDialog.jsx @@ -0,0 +1,139 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; + +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Api from '../../api'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + + +class ConditionAddEditDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + condition: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + isNew: props.condition.id === 0, + + conditionId: props.condition.id, + typeCode: props.condition.conditionTypeCode || '', + description: props.condition.description || '', + concurrencyControlNumber: props.condition.concurrencyControlNumber || 0, + typeCodeError: '', + descriptionError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.isNew && this.state.typeCode !== '') { return true; } + if (this.state.isNew && this.state.description !== '') { return true; } + if (!this.state.isNew && this.state.typeCode !== this.props.condition.conditionTypeCode) { return true; } + if (!this.state.isNew && this.state.description !== this.props.condition.description) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + typeCodeError: '', + descriptionError: '', + }); + + var valid = true; + + if (this.state.typeCode === '') { + this.setState({ typeCodeError: 'Condition type code is required' }); + valid = false; + } + + if (this.state.description === '') { + this.setState({ descriptionError: 'Description is required' }); + valid = false; + } + + return valid; + }; + + onSave = () => { + this.props.onSave({ + id: this.state.conditionId, + conditionTypeCode: this.state.typeCode, + description: this.state.description, + concurrencyControlNumber: this.state.concurrencyControlNumber, + active: true, + }); + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const condition = { + id: this.state.conditionId, + conditionTypeCode: this.state.typeCode, + description: this.state.description, + concurrencyControlNumber: this.state.concurrencyControlNumber, + active: true, + district: { id: this.props.currentUser.district.id }, + }; + + const promise = this.state.isNew ? Api.addCondition(condition) : Api.updateCondition(condition); + + promise.then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + return ( + + + Type Code * + + { this.state.typeCodeError } + + + Description * + + { this.state.descriptionError } + + + ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + }; +} + +export default connect(mapStateToProps)(ConditionAddEditDialog); diff --git a/client2/src/js/views/dialogs/ConfirmDialog.jsx b/client2/src/js/views/dialogs/ConfirmDialog.jsx new file mode 100644 index 000000000..271508893 --- /dev/null +++ b/client2/src/js/views/dialogs/ConfirmDialog.jsx @@ -0,0 +1,33 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import FormDialog from '../../components/FormDialog.jsx'; + +class ConfirmDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + title: PropTypes.string, + saveText: PropTypes.string, + closeText: PropTypes.string, + children: PropTypes.node, + }; + + render() { + return ( + + { this.props.children } + + ); + } +} + +export default ConfirmDialog; diff --git a/client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx b/client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx new file mode 100644 index 000000000..c848c4589 --- /dev/null +++ b/client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx @@ -0,0 +1,86 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Grid, Row, Col, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + + +class ConfirmForceHireDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + reasonForForceHire: '', + }; + } + + componentDidMount() { + this.input && this.input.focus(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + return true; + }; + + isValid = () => { + this.setState({ + noteError: '', + }); + + var valid = true; + + if (isBlank(this.state.reasonForForceHire) ) { + this.setState({ reasonForForceHireError: 'Reason is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + this.props.onSave(this.state.reasonForForceHire); + }; + + render() { + return ( + + + +

Are you sure you want to do a Force Hire?

+ + + + + Reason for Force Hire + + { this.state.reasonForForceHireError } + + + +
+
+ ); + } +} + +export default connect()(ConfirmForceHireDialog); diff --git a/client2/src/js/views/dialogs/ContactsEditDialog.jsx b/client2/src/js/views/dialogs/ContactsEditDialog.jsx new file mode 100644 index 000000000..c115ffe70 --- /dev/null +++ b/client2/src/js/views/dialogs/ContactsEditDialog.jsx @@ -0,0 +1,273 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { connect } from 'react-redux'; + +import { Grid, Row, Col, Button, Label } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Constant from '../../constants'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank, formatPhoneNumber } from '../../utils/string'; + + +class ContactsEditDialog extends React.Component { + static propTypes = { + contact: PropTypes.object.isRequired, + parent: PropTypes.object.isRequired, + saveContact: PropTypes.func.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + defaultPrimary: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isNew: props.contact.id === 0, + + isSaving: false, + + givenName: props.contact.givenName || '', + surname: props.contact.surname || '', + role: props.contact.role || '', + notes: props.contact.notes || '', + emailAddress: props.contact.emailAddress || '', + workPhoneNumber: props.contact.workPhoneNumber || '', + mobilePhoneNumber: props.contact.mobilePhoneNumber || '', + faxPhoneNumber: props.contact.faxPhoneNumber || '', + isPrimary: props.contact.isPrimary || props.defaultPrimary || false, + + givenNameError: false, + emailAddressError: false, + workPhoneNumberError: false, + mobilePhoneNumberError: false, + faxPhoneNumberError: false, + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + makePrimary = () => { + this.setState({ isPrimary: true }); + }; + + didChange = () => { + if (this.state.givenName !== this.props.contact.givenName) { return true; } + if (this.state.surname !== this.props.contact.surname) { return true; } + if (this.state.organizationName !== this.props.contact.organizationName) { return true; } + if (this.state.role !== this.props.contact.role) { return true; } + if (this.state.notes !== this.props.contact.notes) { return true; } + if (this.state.emailAddress !== this.props.contact.emailAddress) { return true; } + if (this.state.workPhoneNumber !== this.props.contact.workPhoneNumber) { return true; } + if (this.state.mobilePhoneNumber !== this.props.contact.mobilePhoneNumber) { return true; } + if (this.state.faxPhoneNumber !== this.props.contact.faxPhoneNumber) { return true; } + if (this.state.isPrimary !== this.props.contact.isPrimary) { return true; } + + return false; + }; + + isValidPhoneNumber = (number) => { + if (isBlank(number)) { + return true; + } + return Constant.NANP_REGEX.test(number) && formatPhoneNumber(number).length <= Constant.MAX_LENGTH_PHONE_NUMBER; + }; + + isValid = () => { + this.setState({ + givenNameError: false, + emailAddressError: false, + workPhoneNumberError: false, + mobilePhoneNumberError: false, + faxPhoneNumberError: false, + }); + + var valid = true; + + if (isBlank(this.state.givenName)) { + this.setState({ givenNameError: 'Given name is required' }); + valid = false; + } + + // Check the phone numbers against the North American Numbering Plan format. We basically want to + // make sure that there's the right number of digits to make an actual phone number. Note for testers: + // an area code and an exchange code cannot start with 0 or 1. + if (!this.isValidPhoneNumber(this.state.workPhoneNumber)) { + this.setState({ workPhoneNumberError: 'Invalid phone number' }); + valid = false; + } + + if (!this.isValidPhoneNumber(this.state.mobilePhoneNumber)) { + this.setState({ mobilePhoneNumberError: 'Invalid phone number' }); + valid = false; + } + + if (!this.isValidPhoneNumber(this.state.faxPhoneNumber)) { + this.setState({ faxPhoneNumberError: 'Invalid phone number' }); + valid = false; + } + + if (!isBlank(this.state.emailAddress) && !Constant.EMAIL_REGEX.test(this.state.emailAddress)) { + // Just a simple RegEx test for X@Y.Z + this.setState({ emailAddressError: 'Invalid email' }); + valid = false; + } + + // A Primary Contact requires at least one of the phone/email fields to be filled out. + if (this.state.isPrimary && isBlank(this.state.workPhoneNumber) && isBlank(this.state.mobilePhoneNumber) && isBlank(this.state.emailAddress)) { + this.setState({ + workPhoneNumberError: 'A primary contact requires a phone number or email address', + mobilePhoneNumberError: ' ', + emailAddressError: ' ', + }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + const { isNew } = this.state; + + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const contact = { + ...this.props.contact, + givenName: this.state.givenName, + surname: this.state.surname, + role: this.state.role, + notes: this.state.notes, + emailAddress: this.state.emailAddress, + workPhoneNumber: formatPhoneNumber(this.state.workPhoneNumber), + mobilePhoneNumber: formatPhoneNumber(this.state.mobilePhoneNumber), + faxPhoneNumber: formatPhoneNumber(this.state.faxPhoneNumber), + isPrimary: this.state.isPrimary, + }; + + this.props.saveContact(this.props.parent, contact).then((savedContact) => { + this.setState({ isSaving: false }); + this.props.onSave(savedContact); + }); + + if (!isNew) { // can be closed right away if it isn't new + this.props.onClose(); + } + } + } + }; + + render() { + // Read-only if the user cannot edit the contact + var isReadOnly = !this.props.contact.canEdit && this.props.contact.id !== 0; + + const dialogTitle = ( + + Contact + { this.state.isPrimary ? + : + + } + + ); + + return ( + + + + + + Given Name * + + { this.state.givenNameError } + + + + + + + Surname + + + + + + + + Role + + + + + + + + Phone {this.state.isPrimary && *} + + { this.state.workPhoneNumberError } + + + + + + + Cell Phone {this.state.isPrimary && *} + + { this.state.mobilePhoneNumberError } + + + + + + + Fax + + { this.state.faxPhoneNumberError } + + + + + + + Email {this.state.isPrimary && *} + + { this.state.emailAddressError } + + + + + + + Notes + + + + + + + ); + } +} + +function mapStateToProps(state) { + return { + contactz: state.models.contact, + }; +} + +export default connect(mapStateToProps)(ContactsEditDialog); diff --git a/client2/src/js/views/dialogs/DistrictEditDialog.jsx b/client2/src/js/views/dialogs/DistrictEditDialog.jsx new file mode 100644 index 000000000..42c000796 --- /dev/null +++ b/client2/src/js/views/dialogs/DistrictEditDialog.jsx @@ -0,0 +1,128 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import _ from 'lodash'; +import { FormGroup, HelpBlock } from 'react-bootstrap'; + +import * as Api from '../../api'; + +import FormDialog from '../../components/FormDialog.jsx'; +import CheckboxControl from '../../components/CheckboxControl.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; + + +class DistrictEditDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + districts: PropTypes.object, + user: PropTypes.object, + district: PropTypes.object, + userDistricts: PropTypes.array, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + var isNew = props.district.id === 0; + + this.state = { + isNew: isNew, + isSaving: false, + + districtId: isNew ? 0 : props.district.district.id, + isPrimary: props.district.isPrimary || false, + + districtIdError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.isNew && this.state.districtId !== '') { return true; } + if (this.state.isNew && this.state.isPrimary !== '') { return true; } + if (!this.state.isNew && this.state.districtId !== this.props.district.district.id) { return true; } + if (!this.state.isNew && this.state.isPrimary !== this.props.district.isPrimary) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + districtIdError: '', + }); + + var valid = true; + + if (this.state.districtId === 0) { + this.setState({ districtIdError: 'District is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const district = { + id: this.props.district.id, + user: { id: this.props.user.id }, + district: { id: this.state.districtId }, + isPrimary: this.state.isPrimary, + }; + + const promise = this.state.isNew ? Api.addUserDistrict(district) : Api.editUserDistrict(district); + + promise.then((response) => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(response.data); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + var userDistrictsFiltered = _.map(this.props.userDistricts, district => { + if (this.state.isNew || district.district.id !== this.props.district.district.id) { + return district.district.id; + } + return; + }); + + var districts = _.chain(this.props.districts) + .sortBy('name') + .reject(district => { + return _.includes(userDistrictsFiltered, district.id); + } ) + .value(); + + return ( + + + + { this.state.districtIdError } + + Primary District + + ); + } +} + +export default DistrictEditDialog; diff --git a/client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx b/client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx new file mode 100644 index 000000000..0e9e224d4 --- /dev/null +++ b/client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx @@ -0,0 +1,154 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../../api'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + + +const PROHIBITED_SECTIONS = [ 1.2, 1.8, 2.3, 2.6, 3.3, 6.3, 7.4, 8.2, 9.3, 11.2, 12.2, 13.5, 13.6, 16.3 ]; + + +class DistrictEquipmentTypeAddEditDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + show: PropTypes.bool, + districtEquipmentType: PropTypes.object, + equipmentTypes: PropTypes.object, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + isNew: props.districtEquipmentType.id === 0, + + id: props.districtEquipmentType.id || 0, + equipmentTypeId: props.districtEquipmentType.equipmentType ? props.districtEquipmentType.equipmentType.id : undefined, + districtEquipmentName: props.districtEquipmentType.districtEquipmentName || '', + concurrencyControlNumber: props.districtEquipmentType.concurrencyControlNumber || 0, + equipmentTypeIdError: '', + districtEquipmentNameError: '', + }; + } + + componentDidMount() { + Api.getEquipmentTypes(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.isNew && this.state.equipmentTypeId !== undefined) { return true; } + if (this.state.isNew && this.state.districtEquipmentName !== '') { return true; } + if (!this.state.isNew && this.state.equipmentTypeId !== this.props.districtEquipmentType.equipmentType.id) { return true; } + if (!this.state.isNew && this.state.districtEquipmentName !== this.props.districtEquipmentType.districtEquipmentName) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + equipmentTypeIdError: '', + districtEquipmentNameError: '', + }); + + var valid = true; + + if (this.state.equipmentTypeId === undefined) { + this.setState({ equipmentTypeIdError: 'Blue book section is required' }); + valid = false; + } else { + var equipmentType = _.find(this.props.equipmentTypes, { id: this.state.equipmentTypeId }); + if (equipmentType && _.includes(PROHIBITED_SECTIONS, equipmentType.blueBookSection)) { + this.setState({ equipmentTypeIdError: 'Equipment types cannot be created for this blue book section' }); + valid = false; + } + } + + if (this.state.districtEquipmentName === '') { + this.setState({ districtEquipmentNameError: 'Equipment type/description is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const equipmentType = { + id: this.state.id, + equipmentType: { id: this.state.equipmentTypeId }, + districtEquipmentName: this.state.districtEquipmentName, + concurrencyControlNumber: this.state.concurrencyControlNumber, + district: { id: this.props.currentUser.district.id }, + }; + + const promise = equipmentType.id !== 0 ? Api.updateDistrictEquipmentType(equipmentType) : Api.addDistrictEquipmentType(equipmentType); + + promise.then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + var equipmentTypes = _.sortBy(this.props.equipmentTypes.data, 'blueBookSection'); + + return ( + + + Blue Book Section * + + { this.state.equipmentTypeIdError } + + + Equipment Type/Description * + + { this.state.districtEquipmentNameError } + + + ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + equipmentTypes: state.lookups.equipmentTypes, + }; +} + +export default connect(mapStateToProps)(DistrictEquipmentTypeAddEditDialog); diff --git a/client2/src/js/views/dialogs/DocumentsListDialog.jsx b/client2/src/js/views/dialogs/DocumentsListDialog.jsx new file mode 100644 index 000000000..921ec5827 --- /dev/null +++ b/client2/src/js/views/dialogs/DocumentsListDialog.jsx @@ -0,0 +1,217 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { connect } from 'react-redux'; + +import { Alert, Button, ButtonGroup, Glyphicon, ProgressBar, HelpBlock } from 'react-bootstrap'; + +import _ from 'lodash'; + +import { request, buildApiPath } from '../../utils/http'; + +import * as Action from '../../actionTypes'; +import * as Api from '../../api'; +import * as Constant from '../../constants'; +import store from '../../store'; + +import DeleteButton from '../../components/DeleteButton.jsx'; +import ModalDialog from '../../components/ModalDialog.jsx'; +import SortTable from '../../components/SortTable.jsx'; +import Spinner from '../../components/Spinner.jsx'; +import FilePicker from '../../components/FilePicker.jsx'; +import Authorize from '../../components/Authorize.jsx'; + +import { formatDateTime } from '../../utils/date'; + + +class DocumentsListDialog extends React.Component { + static propTypes = { + parent: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + + documents: PropTypes.object, + users: PropTypes.object, + ui: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + documents: [], + uploadInProgress: false, + percentUploaded: 0, + showAttachmentDialog: false, + ui : { + sortField: props.ui.sortField || 'timestampSort', + sortDesc: props.ui.sortDesc !== false, + }, + uploadError: '', + }; + } + + componentDidMount() { + this.setState({ loading: true }); + Api.getUsers().then(() => { + return this.formatDocuments(); + }).finally(() => { + this.setState({ loading: false }); + }); + } + + getUserName = (smUserId) => { + var user = _.find(this.props.users, user => { return user.smUserId === smUserId; }); + return user ? user.name : smUserId; + }; + + updateUIState = (state, callback) => { + this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ + store.dispatch({ type: Action.UPDATE_DOCUMENTS_UI, documents: this.state.ui }); + if (callback) { callback(); } + }); + }; + + fetch = () => { + this.setState({ loading: true }); + return this.props.parent.getDocumentsPromise(this.props.parent.id).then(() => { + this.formatDocuments(); + }).finally(() => { + this.setState({ loading: false }); + }); + }; + + formatDocuments = () => { + var documents = _.map(this.props.documents, document => { + return { + ...document, + userName: this.getUserName(document.lastUpdateUserid), + formattedTimestamp: formatDateTime(document.lastUpdateTimestamp, Constant.DATE_TIME_LOG), + }; + }); + this.setState({ + documents: documents, + }); + }; + + deleteDocument = (document) => { + Api.deleteDocument(document).then(() => { + this.props.parent.documentDeleted(this.props.parent, document); + return this.fetch(); + }); + }; + + downloadDocument = (document) => { + // Get path to the document and open it in a new browser window to initiate download. + window.open(Api.getDownloadDocumentURL(document)); + }; + + uploadFiles = (files) => { + this.setState({ uploadError: '' }); + + var invalidFiles = _.filter(files, file => file.size > Constant.MAX_ATTACHMENT_FILE_SIZE); + if (invalidFiles.length > 0) { + this.setState({ uploadError: 'One of the selected files is too large.' }); + return; + } + + this.setState({ uploadInProgress: true, percentUploaded: 0 }); + + var options = { + method: 'POST', + files: [...files], + onUploadProgress: (percentComplete) => { + var percent = Math.round(percentComplete); + this.setState({ percentUploaded: percent }); + }, + }; + + this.uploadPromise = request(buildApiPath(this.props.parent.uploadDocumentPath), options).then(() => { + _.map(files, ((file) => { + this.props.parent.documentAdded(this.props.parent, file.name); + })); + this.setState({ uploadInProgress: false, percentUploaded: null }); + this.fetch(); + }, (err) => { + this.setState({ uploadInProgress: false, fileUploadError: err }); + }); + }; + + render() { + var parent = this.props.parent; + + return ( + Documents for { parent.name } } + footer={ } + > +
+ {this.state.uploadInProgress ? + + : + +
+ +
Select one or more files{ parent.name ? ` to attach to ${ parent.name }` : null }
+ The maximum size of each file is { Constant.MAX_ATTACHMENT_FILE_SIZE_READABLE }. + { this.state.uploadError &&
{ this.state.uploadError }
} +
+
+ } +
+ {(() => { + if (this.state.loading) { return
; } + + var numDocuments = Object.keys(this.state.documents).length; + + if (numDocuments === 0) { return No documents; } + + var documents = _.sortBy(this.state.documents, this.state.ui.sortField); + if (this.state.ui.sortDesc) { + _.reverse(documents); + } + + var headers = [ + { field: 'timestampSort', title: 'Uploaded On' }, + { field: 'userName', title: 'Uploaded By' }, + { field: 'fileName', title: 'File Name' }, + { field: 'fileSize', title: 'File Size' }, + { field: 'attachDocument', title: 'Attach Document', style: { textAlign: 'right' } }, + ]; + + return + { + _.map(documents, (document) => { + return + { document.formattedTimestamp } + { document.userName } + { document.fileName } + { document.fileSizeDisplay } + + + + + + + ; + }) + } + ; + })()} +
+
+
+ ); + } +} + +function mapStateToProps(state) { + return { + documents: state.models.documents, + users: state.lookups.users, + ui: state.ui.documents, + }; +} + +export default connect(mapStateToProps)(DocumentsListDialog); diff --git a/client2/src/js/views/dialogs/EquipmentAddDialog.jsx b/client2/src/js/views/dialogs/EquipmentAddDialog.jsx new file mode 100644 index 000000000..23ef503ff --- /dev/null +++ b/client2/src/js/views/dialogs/EquipmentAddDialog.jsx @@ -0,0 +1,419 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { FormGroup, HelpBlock, ControlLabel } from "react-bootstrap"; +import _ from "lodash"; + +import * as Api from "../../api"; +import * as Constant from "../../constants"; + +import FormDialog from "../../components/FormDialog.jsx"; +import FilterDropdown from "../../components/FilterDropdown.jsx"; +import FormInputControl from "../../components/FormInputControl.jsx"; + +import { isBlank, notBlank } from "../../utils/string"; +import { isValidYear } from "../../utils/date"; + +class EquipmentAddDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object.isRequired, + owner: PropTypes.object.isRequired, + localAreas: PropTypes.object.isRequired, + districtEquipmentTypes: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + localAreaId: props.owner.localArea.id || 0, + equipmentTypeId: 0, + licencePlate: "", + serialNumber: "", + make: "", + model: "", + year: "", + size: "", + type: "", + licencedGvw: "", + legalCapacity: "", + pupLegalCapacity: "", + localAreaError: "", + equipmentTypeError: "", + serialNumberError: "", + duplicateSerialNumberWarning: false, + makeError: "", + modelError: "", + yearError: "", + }; + } + + componentDidMount() { + Api.getDistrictEquipmentTypes(); + } + + componentDidUpdate(prevProps, prevState) { + if (!_.isEqual(this.state.serialNumber, prevState.serialNumber)) { + this.setState({ + duplicateSerialNumberWarning: false, + serialNumberError: "", + }); + } + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.localAreaId !== 0) { + return true; + } + if (this.state.equipmentTypeId !== 0) { + return true; + } + if (this.state.serialNumber !== "") { + return true; + } + if (this.state.licencePlate !== "") { + return true; + } + if (this.state.make !== "") { + return true; + } + if (this.state.model !== "") { + return true; + } + if (this.state.year !== "") { + return true; + } + if (this.state.size !== "") { + return true; + } + if (this.state.type !== "") { + return true; + } + if (this.state.licencedGvw !== "") { + return true; + } + if (this.state.legalCapacity !== "") { + return true; + } + if (this.state.pupLegalCapacity !== "") { + return true; + } + + return false; + }; + + isValid = () => { + this.setState({ + localAreaError: "", + equipmentTypeError: "", + serialNumberError: "", + makeError: "", + modelError: "", + yearError: "", + }); + + var valid = true; + + if (this.state.localAreaId === 0) { + this.setState({ + localAreaError: "Service area / local area is required.", + }); + valid = false; + } + + if (this.state.equipmentTypeId === 0) { + this.setState({ equipmentTypeError: "Equipment type is required." }); + valid = false; + } + + if (isBlank(this.state.make)) { + this.setState({ makeError: "Make is required." }); + valid = false; + } + + if (isBlank(this.state.model)) { + this.setState({ modelError: "Model is required." }); + valid = false; + } + + if (isBlank(this.state.year)) { + this.setState({ yearError: "Year is required." }); + valid = false; + } else if (notBlank(this.state.year) && !isValidYear(this.state.year)) { + this.setState({ yearError: "This is not a valid year." }); + valid = false; + } + + if (isBlank(this.state.serialNumber)) { + this.setState({ serialNumberError: "Serial number is required." }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.state.duplicateSerialNumberWarning) { + // proceed regardless of duplicates + this.setState({ duplicateSerialNumberWarning: false }); + return this.saveEquipment(); + } + + this.setState({ isSaving: true }); + + return Api.equipmentDuplicateCheck(0, this.state.serialNumber).then( + (response) => { + this.setState({ isSaving: false }); + + if (response.data.length > 0) { + const equipmentCodes = response.data.map((district) => { + return district.duplicateEquipment.equipmentCode; + }); + var districts = _.chain(response.data) + .map((district) => district.districtName) + .uniq() + .value(); + const districtsPlural = + districts.length === 1 ? "district" : "districts"; + this.setState({ + serialNumberError: `Serial number is currently in use for the equipment ${equipmentCodes.join( + ", " + )}, in the following ${districtsPlural}: ${districts.join(", ")}`, + duplicateSerialNumberWarning: true, + }); + return null; + } else { + this.setState({ duplicateSerialNumberWarning: false }); + return this.saveEquipment(); + } + } + ); + } + }; + + saveEquipment = () => { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const equipment = { + owner: { id: this.props.owner.id }, + localArea: { id: this.state.localAreaId }, + districtEquipmentType: { id: this.state.equipmentTypeId }, + licencePlate: this.state.licencePlate, + serialNumber: this.state.serialNumber, + make: this.state.make, + model: this.state.model, + year: this.state.year, + size: this.state.size, + type: this.state.type, + licencedGvw: this.state.licencedGvw, + legalCapacity: this.state.legalCapacity, + pupLegalCapacity: this.state.pupLegalCapacity, + status: Constant.EQUIPMENT_STATUS_CODE_PENDING, + }; + + return Api.addEquipment(equipment).then((savedEquipment) => { + this.setState({ isSaving: false }); + this.props.onSave(savedEquipment); + }); + } + }; + + render() { + var owner = this.props.owner; + + var localAreas = _.sortBy(this.props.localAreas, "name"); + + var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) + .filter((type) => type.district.id === this.props.currentUser.district.id) + .sortBy("districtEquipmentName") + .value(); + + var equipment = _.find(districtEquipmentTypes, (equipment) => { + return equipment.id === this.state.equipmentTypeId; + }); + + var isDumpTruck = equipment && equipment.equipmentType.isDumpTruck; + + return ( + + + Owner +

{owner.organizationName}

+
+ + + Service Area - Local Area * + + + {this.state.localAreaError} + + + + Equipment Type * + + + {this.state.equipmentTypeError} + + + + Make * + + + {this.state.makeError} + + + + Model * + + + {this.state.modelError} + + + + Year * + + + {this.state.yearError} + + + Size + + + + Type + + + + Licence Number + + + + + Serial Number * + + + {this.state.serialNumberError} + + {isDumpTruck && ( +
+ + Licenced GVW + + + + Truck Legal Capacity + + + + Pup Legal Capacity + + +
+ )} +
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + localAreas: state.lookups.localAreas, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + }; +} + +export default connect(mapStateToProps)(EquipmentAddDialog); diff --git a/client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx b/client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx new file mode 100644 index 000000000..f99d81d07 --- /dev/null +++ b/client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx @@ -0,0 +1,98 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + + +class EquipmentChangeStatusDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + status: PropTypes.string.isRequired, + equipment: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + onStatusChanged: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + saving: false, + comment: '', + commentError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + isValid = () => { + this.setState({ + commentError: '', + }); + + var valid = true; + + if (isBlank(this.state.comment)) { + this.setState({ commentError: 'Comment is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + this.setState({isSaving: true}); + const status = { + id: this.props.equipment.id, + status: this.props.status, + statusComment: this.state.comment, + }; + + Api.changeEquipmentStatus(status).then(() => { + this.setState({isSaving: false}); + this.props.onStatusChanged(); + Log.equipmentStatusModified(this.props.equipment, status.status, status.statusComment); + }).catch((error) => { + if (error.status === 400 && (error.errorCode === 'HETS-39' || error.errorCode === 'HETS-41')) { + this.setState({ commentError: error.errorDescription }); + } else { + throw error; + } + }); + } + }; + + render() { + var maxLength = Constant.MAX_LENGTH_STATUS_COMMENT; + + return ( + + + Comment + + {this.state.commentError} +

Maximum { maxLength } characters.

+
+
+ ); + } +} + +export default EquipmentChangeStatusDialog; diff --git a/client2/src/js/views/dialogs/EquipmentEditDialog.jsx b/client2/src/js/views/dialogs/EquipmentEditDialog.jsx new file mode 100644 index 000000000..85f892a68 --- /dev/null +++ b/client2/src/js/views/dialogs/EquipmentEditDialog.jsx @@ -0,0 +1,510 @@ +import PropTypes from "prop-types"; +import React from "react"; + +import { connect } from "react-redux"; + +import _ from "lodash"; + +import { + Grid, + Row, + Col, + FormGroup, + HelpBlock, + ControlLabel, +} from "react-bootstrap"; + +import * as Api from "../../api"; +import * as Log from "../../history"; + +import FormDialog from "../../components/FormDialog.jsx"; +import FormInputControl from "../../components/FormInputControl.jsx"; +import FilterDropdown from "../../components/FilterDropdown.jsx"; + +import { isBlank, notBlank } from "../../utils/string"; +import { isValidYear } from "../../utils/date"; + +class EquipmentEditDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + equipment: PropTypes.object.isRequired, + localAreas: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + isNew: props.equipment.id === 0, + + localAreaId: props.equipment.localArea.id || 0, + equipmentTypeId: props.equipment.districtEquipmentTypeId || null, + serialNumber: props.equipment.serialNumber || "", + make: props.equipment.make || "", + size: props.equipment.size || "", + model: props.equipment.model || "", + year: props.equipment.year || "", + licencePlate: props.equipment.licencePlate || "", + type: props.equipment.type || "", + licencedGvw: props.equipment.licencedGvw || "", + legalCapacity: props.equipment.legalCapacity || "", + pupLegalCapacity: props.equipment.pupLegalCapacity || "", + + localAreaError: "", + localAreaSeniorityChangeWarning: false, + equipmentTypeError: "", + equipmentTypeSeniorityChangeWarning: false, + serialNumberError: "", + duplicateSerialNumberWarning: false, + makeError: "", + modelError: "", + yearError: "", + }; + } + + componentDidMount() { + Api.getDistrictEquipmentTypes(); + } + + componentDidUpdate(prevProps, prevState) { + if (!_.isEqual(this.state.serialNumber, prevState.serialNumber)) { + this.setState({ + duplicateSerialNumberWarning: false, + serialNumberError: "", + }); + } + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.localAreaId !== this.props.equipment.localArea.id) { + return true; + } + if (this.state.equipmentTypeId !== 0) { + return true; + } + if (this.state.serialNumber !== this.props.equipment.serialNumber) { + return true; + } + if (this.state.make !== this.props.equipment.make) { + return true; + } + if (this.state.size !== this.props.equipment.size) { + return true; + } + if (this.state.model !== this.props.equipment.model) { + return true; + } + if (this.state.year !== this.props.equipment.year) { + return true; + } + if (this.state.licencePlate !== this.props.equipment.licencePlate) { + return true; + } + if (this.state.type !== this.props.equipment.type) { + return true; + } + if (this.state.licencedGvw !== this.props.equipment.licencedGvw) { + return true; + } + if (this.state.legalCapacity !== this.props.equipment.legalCapacity) { + return true; + } + if (this.state.pupLegalCapacity !== this.props.equipment.pupLegalCapacity) { + return true; + } + + return false; + }; + + isValid = () => { + this.setState({ + localAreaError: "", + equipmentTypeError: "", + serialNumberError: "", + makeError: "", + modelError: "", + yearError: "", + }); + + var valid = true; + + if (this.state.equipmentTypeId === 0) { + this.setState({ equipmentTypeError: "Equipment type is required." }); + valid = false; + } + + if (isBlank(this.state.serialNumber)) { + this.setState({ serialNumberError: "Serial number is required" }); + valid = false; + } + + if (isBlank(this.state.make)) { + this.setState({ makeError: "Make is required." }); + valid = false; + } + + if (isBlank(this.state.model)) { + this.setState({ modelError: "Model is required." }); + valid = false; + } + + if (isBlank(this.state.year)) { + this.setState({ yearError: "Year is required." }); + valid = false; + } else if (notBlank(this.state.year) && !isValidYear(this.state.year)) { + this.setState({ yearError: "This is not a valid year." }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + if (this.state.duplicateSerialNumberWarning) { + // proceed regardless of duplicates + this.setState({ duplicateSerialNumberWarning: false }); + return this.saveEquipment(); + } + + return Api.equipmentDuplicateCheck( + this.props.equipment.id, + this.state.serialNumber + ).then((response) => { + if (response.data.length > 0) { + const equipmentCodes = response.data.map((district) => { + return district.duplicateEquipment.equipmentCode; + }); + var districts = _.chain(response.data) + .map((district) => district.districtName) + .uniq() + .value(); + const districtsPlural = + districts.length === 1 ? "district" : "districts"; + this.setState({ + serialNumberError: `Serial number is currently in use for the equipment ${equipmentCodes.join( + ", " + )}, in the following ${districtsPlural}: ${districts.join(", ")}`, + duplicateSerialNumberWarning: true, + }); + return null; + } else { + this.setState({ duplicateSerialNumberWarning: false }); + return this.saveEquipment(); + } + }); + } else { + this.props.onClose(); + } + } + }; + + saveEquipment = () => { + this.setState({ isSaving: true }); + + const equipment = { + ...this.props.equipment, + localArea: { id: this.state.localAreaId }, + districtEquipmentTypeId: this.state.equipmentTypeId, + serialNumber: this.state.serialNumber, + make: this.state.make, + size: this.state.size, + model: this.state.model, + year: this.state.year, + licencePlate: this.state.licencePlate, + type: this.state.type, + licencedGvw: this.state.licencedGvw, + legalCapacity: this.state.legalCapacity, + pupLegalCapacity: this.state.pupLegalCapacity, + }; + + const promise = Api.updateEquipment(equipment); + + promise.then(() => { + Log.equipmentModified(this.props.equipment); + this.setState({ isSaving: false }); + if (this.props.onSave) { + this.props.onSave(); + } + this.props.onClose(); + }); + }; + + onLocalAreaChanged() { + if (this.state.localAreaId !== this.props.equipment.localArea.id) { + this.setState({ + localAreaError: + "This action will change the seniority of the equipment.", + localAreaSeniorityChangeWarning: true, + }); + } else { + this.setState({ + localAreaError: "", + localAreaSeniorityChangeWarning: false, + }); + } + } + + onEquipmentTypeChanged() { + if ( + this.state.equipmentTypeId !== + this.props.equipment.districtEquipmentTypeId + ) { + this.setState({ + equipmentTypeError: + "This action will change the seniority of the equipment.", + equipmentTypeSeniorityChangeWarning: true, + }); + } else { + this.setState({ + equipmentTypeError: "", + equipmentTypeSeniorityChangeWarning: false, + }); + } + } + + render() { + var equipment = this.props.equipment; + + var localAreas = _.sortBy(this.props.localAreas, "name"); + + var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) + .filter((type) => type.district.id === this.props.currentUser.district.id) + .sortBy("districtEquipmentName") + .value(); + + const saveWarning = + this.state.duplicateSerialNumberWarning || + this.state.localAreaSeniorityChangeWarning || + this.state.equipmentTypeSeniorityChangeWarning; + + return ( + + + + + + Service Area - Local Area + + this.updateState(state, this.onLocalAreaChanged) + } + items={localAreas} + className="full-width" + /> + {this.state.localAreaError} + + + + + + + + Equipment Type * + + + this.updateState(state, this.onEquipmentTypeChanged) + } + /> + {this.state.equipmentTypeError} + + + + + + + + Make * + + + {this.state.makeError} + + + + + + + + Model * + + + {this.state.modelError} + + + + + + + + Year * + + + {this.state.yearError} + + + + + + + Size + + + + + + + + Type + + + + + + + + Licence Number + + + + + + + + + Serial Number * + + + {this.state.serialNumberError} + + + + {equipment.isDumpTruck && ( +
+ + + + Licenced GVW + + + + + + + + Truck Legal Capacity + + + + + + + + Pup Legal Capacity + + + + +
+ )} +
+
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + localAreas: state.lookups.localAreas, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + }; +} + +export default connect(mapStateToProps)(EquipmentEditDialog); diff --git a/client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx b/client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx new file mode 100644 index 000000000..7f4e6f8dc --- /dev/null +++ b/client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx @@ -0,0 +1,134 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Grid, Row, Col } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + + +class EquipmentRentalRatesEditDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + rentalAgreement: PropTypes.object.isRequired, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + equipmentRate: props.rentalAgreement.equipmentRate || 0, + ratePeriod: props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY, + rateComment: props.rentalAgreement.rateComment || '', + + equipmentRateError: '', + ratePeriodError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.equipmentRate !== this.props.rentalAgreement.equipmentRate) { return true; } + if (this.state.ratePeriod !== this.props.rentalAgreement.ratePeriod) { return true; } + if (this.state.rateComment !== this.props.rentalAgreement.rateComment) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + equipmentRateError: '', + ratePeriodError: '', + }); + + var valid = true; + + if (isBlank(this.state.equipmentRate) ) { + this.setState({ equipmentRateError: 'Pay rate is required' }); + valid = false; + } else if (this.state.equipmentRate < 0) { + this.setState({ equipmentRateError: 'Pay rate not valid' }); + valid = false; + } + + if (isBlank(this.state.ratePeriod)) { + this.setState({ ratePeriodError: 'Period is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const rentalAgreement = { + ...this.props.rentalAgreement, + equipmentRate: this.state.equipmentRate, + ratePeriod: this.state.ratePeriod, + rateComment: this.state.rateComment, + }; + + Api.updateRentalAgreement(rentalAgreement).then(() => { + if (this.props.onSave) { this.props.onSave(); } + }); + } + + this.props.onClose(); + } + }; + + render() { + // Read-only if the user cannot edit the rental agreement + var isReadOnly = !this.props.rentalAgreement.canEdit && this.props.rentalAgreement.id !== 0; + var ratePeriods = [ Constant.RENTAL_RATE_PERIOD_HOURLY, Constant.RENTAL_RATE_PERIOD_DAILY, Constant.RENTAL_RATE_PERIOD_WEEKLY, Constant.RENTAL_RATE_PERIOD_MONTHLY, Constant.RENTAL_RATE_PERIOD_NEGOTIATED ]; + + return ( + + + + + + Pay Rate * + + { this.state.equipmentRateError } + + + + + Period * + + { this.state.ratePeriodError } + + + + + Comment + + + + + + + ); + } +} + +export default EquipmentRentalRatesEditDialog; diff --git a/client2/src/js/views/dialogs/EquipmentTransferDialog.jsx b/client2/src/js/views/dialogs/EquipmentTransferDialog.jsx new file mode 100644 index 000000000..306b20469 --- /dev/null +++ b/client2/src/js/views/dialogs/EquipmentTransferDialog.jsx @@ -0,0 +1,493 @@ +import PropTypes from "prop-types"; +import React from "react"; + +import { connect } from "react-redux"; + +import { + Button, + Row, + Col, + FormGroup, + ControlLabel, + HelpBlock, + Checkbox, +} from "react-bootstrap"; + +import _ from "lodash"; + +import * as Api from "../../api"; + +import DropdownControl from "../../components/DropdownControl.jsx"; +import FormInputControl from "../../components/FormInputControl.jsx"; +import ModalDialog from "../../components/ModalDialog.jsx"; +import Spinner from "../../components/Spinner.jsx"; +import TableControl from "../../components/TableControl.jsx"; + +import { isBlank } from "../../utils/string"; + +const STAGE_SELECT_OWNER = 1; +const STAGE_SELECT_EQUIPMENT = 2; +const STAGE_CONFIRM = 3; +const STAGE_COMPLETE = 4; + +const OPTION_EQUIPMENT_ONLY = { id: 1, name: "Transfer Equipment Only" }; +const OPTION_EQUIPMENT_AND_SENIORITY = { + id: 2, + name: "Transfer Equipment and Seniority", +}; + +class EquipmentTransferDialog extends React.Component { + static propTypes = { + equipment: PropTypes.object.isRequired, + owners: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + stage: STAGE_SELECT_OWNER, + donorOwnerCode: "", + recipientOwnerCode: "", + seniorityOption: 1, + donorOwnerCodeError: "", + recipientOwnerCodeError: "", + seniorityOptionError: "", + selectedEquipmentIds: [], + selectAllEquipment: false, + waitingForResponse: false, + equipmentTransferError: "", + }; + } + + componentDidMount() { + Api.getOwnersLite(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + getOwner = (code) => { + var owner = _.find(this.props.owners.data, { ownerCode: code }); + return owner; + }; + + validateOwnerCode = (code, errorState) => { + if (isBlank(code)) { + this.setState({ [errorState]: "This owner code is required" }); + return false; + } + + if (this.getOwner(code) === undefined) { + this.setState({ + [errorState]: "This owner code is either not valid or not approved", + }); + return false; + } + + return true; + }; + + validateSelectOwner = () => { + this.setState({ + donorOwnerCodeError: "", + recipientOwnerCodeError: "", + seniorityOptionError: "", + }); + + var valid = this.validateOwnerCode( + this.state.donorOwnerCode, + "donorOwnerCodeError" + ); + valid &= this.validateOwnerCode( + this.state.recipientOwnerCode, + "recipientOwnerCodeError" + ); + + if (!valid) { + return false; + } + + if (this.state.donorOwnerCode === this.state.recipientOwnerCode) { + this.setState({ + recipientOwnerCodeError: "The owner codes must be different", + }); + return false; + } + + var donor = this.getOwner(this.state.donorOwnerCode); + var recipient = this.getOwner(this.state.recipientOwnerCode); + + if ( + this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id && + donor.localAreaId !== recipient.localAreaId + ) { + this.setState({ + seniorityOptionError: + "Both Transfer From and Transfer To Owners/Companies should be from the same local area", + }); + return false; + } + + return true; + }; + + renderSelectOwner = () => { + var seniorityOptions = [ + OPTION_EQUIPMENT_ONLY, + OPTION_EQUIPMENT_AND_SENIORITY, + ]; + + return ( +
+ + + + Transfer Equipment From (Owner Code) * + + + + + Action * + + + + + Transfer Equipment To (Owner Code) * + + + + + + + + {this.state.donorOwnerCodeError} + + + + + + {this.state.seniorityOptionError} + + + + + + {this.state.recipientOwnerCodeError} + + + +
+ ); + }; + + handleEquipmentCheckedChange = (e, id) => { + var checked = e.target.checked; + + var selectedEquipmentIds = [...this.state.selectedEquipmentIds]; + if (checked && !_.includes(selectedEquipmentIds, id)) { + selectedEquipmentIds.push(id); + } else { + _.remove(selectedEquipmentIds, (x) => x === id); + } + + this.setState({ selectedEquipmentIds: selectedEquipmentIds }); + }; + + handleSelectAllEquipmentCheckedChange = (e) => { + var checked = e.target.checked; + + var selectedEquipmentIds = checked + ? _.map(this.props.equipment.data, (x) => x.id) + : []; + + this.setState({ + selectedEquipmentIds: selectedEquipmentIds, + selectAllEquipment: checked, + }); + }; + + validateSelectEquipment = () => { + return this.state.selectedEquipmentIds.length > 0; + }; + + renderSelectEquipment = () => { + if (this.props.equipment.loading) { + return ( +
+ +
+ ); + } + + var equipmentList = this.props.equipment.data; + + var selectAllCheckbox = ( + + Select All + + ); + + var headers = [ + { field: "", node: selectAllCheckbox }, + { field: "equipmentCode", title: "Equip. ID" }, + { field: "equipmentType", title: "Equip. Type" }, + { field: "details", title: "Make/Model/Size/Year" }, + { field: "attachmentCount", title: "Attachments" }, + ]; + + return ( + + {_.map(equipmentList, (equipment) => { + return ( + + + + this.handleEquipmentCheckedChange(e, equipment.id) + } + /> + + {equipment.equipmentCode} + {equipment.districtEquipmentType.districtEquipmentName} + {equipment.details} + + {_.map( + equipment.equipmentAttachments, + (a) => a.description + ).join(", ")} + + + ); + })} + + ); + }; + + renderConfirm = () => { + return ( +
+

+ This action will transfer all selected equipment from the first + owner/company to the second owner/company. +

+
    +
  • + The piece(s) of equipment from the first company will be archived. +
  • + {this.state.seniorityOption === OPTION_EQUIPMENT_ONLY.id && ( +
  • + The piece(s) of equipment will be added to the “Transfer To” + owner/company as new equipment. +
  • + )} + {this.state.seniorityOption === OPTION_EQUIPMENT_ONLY.id && ( +
  • All previous seniority data will be lost.
  • + )} + {this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id && ( +
  • + The piece(s) of equipment will be added to the “Transfer To” + owner/company while retaining their seniority. +
  • + )} +
+ {!this.state.waitingForResponse &&

Do you want to continue?

} + {this.state.waitingForResponse && ( +

+ Please wait while the equipment is transferred. This may take some + time. +

+ )} +
+ ); + }; + + renderComplete = () => { + return ( +
+ {this.state.equipmentTransferError && ( +
+ Error: {this.state.equipmentTransferError} +
+ )} + {this.state.equipmentTransferError && ( +

The selected equipment has not been transferred.

+ )} + {!this.state.equipmentTransferError && ( +

The selected equipment has been successfully transferred.

+ )} +
+ ); + }; + + render() { + var content = null; + var transferText = "Transfer"; + var transferEnabled = false; + var transferFunc = function () {}; + + if (!this.props.owners.loaded) { + return ( +
+ +
+ ); + } + + switch (this.state.stage) { + case STAGE_SELECT_OWNER: + content = this.renderSelectOwner(); + transferEnabled = + !isBlank(this.state.donorOwnerCode) && + !isBlank(this.state.recipientOwnerCode); + transferFunc = function () { + if (this.validateSelectOwner()) { + var ownerId = this.getOwner(this.state.donorOwnerCode).id; + Api.getOwnerEquipment(ownerId); + + this.setState({ stage: STAGE_SELECT_EQUIPMENT }); + } + }; + break; + case STAGE_SELECT_EQUIPMENT: + content = this.renderSelectEquipment(); + transferEnabled = this.state.selectedEquipmentIds.length > 0; + transferFunc = function () { + if (this.validateSelectEquipment()) { + this.setState({ stage: STAGE_CONFIRM }); + } + }; + break; + case STAGE_CONFIRM: + content = this.renderConfirm(); + transferText = + this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id + ? "Transfer Equipment and Seniority" + : "Transfer Equipment Only"; + transferEnabled = true; + transferFunc = function () { + this.setState({ waitingForResponse: true }); + + var donorOwnerId = this.getOwner(this.state.donorOwnerCode).id; + var recipientOwnerId = this.getOwner( + this.state.recipientOwnerCode + ).id; + var equipment = _.filter(this.props.equipment.data, (x) => + _.includes(this.state.selectedEquipmentIds, x.id) + ); + var includeSeniority = + this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id; + + Api.transferEquipment( + donorOwnerId, + recipientOwnerId, + equipment, + includeSeniority + ) + .catch((error) => { + if ( + error.status === 400 && + (error.errorCode === "HETS-31" || + error.errorCode === "HETS-32" || + error.errorCode === "HETS-33" || + error.errorCode === "HETS-34") + ) { + this.setState({ + equipmentTransferError: error.errorDescription, + }); + } else { + throw error; + } + }) + .finally(() => { + this.setState({ + waitingForResponse: false, + stage: STAGE_COMPLETE, + }); + }); + }; + break; + case STAGE_COMPLETE: + content = this.renderComplete(); + break; + default: + break; + } + + var displayTransferButton = + this.state.stage !== STAGE_COMPLETE && + this.state.waitingForResponse !== true; + + return ( + + + {displayTransferButton && ( + + )} + + } + > + {content} + + ); + } +} + +function mapStateToProps(state) { + return { + equipment: state.models.ownerEquipment, + owners: state.lookups.owners.lite, + }; +} + +export default connect(mapStateToProps)(EquipmentTransferDialog); diff --git a/client2/src/js/views/dialogs/ErrorDialog.jsx b/client2/src/js/views/dialogs/ErrorDialog.jsx new file mode 100644 index 000000000..18179d7cf --- /dev/null +++ b/client2/src/js/views/dialogs/ErrorDialog.jsx @@ -0,0 +1,123 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button } from 'react-bootstrap'; +import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; + +import ModalDialog from '../../components/ModalDialog.jsx'; +import {closeErrorDialog} from '../../actions'; + +class ErrorDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + title: PropTypes.string, + apiError: PropTypes.object, + appError: PropTypes.object, + closeErrorDialog: PropTypes.func.isRequired, + }; + + closeDialog = () => { + this.props.closeErrorDialog(); + }; + + reloadButtonClicked = () => { + window.location.reload(); + }; + + render() { + const {apiError, appError, show} = this.props; + + var modalTitle = 'Unexpected Error'; + var errorMessage = 'An error occured'; + var details = null; + var shouldReload = false; + var buttonText = 'Close'; + + if (appError) { + errorMessage = appError.message; + + if (appError.unrecoverable) { + shouldReload = true; + buttonText = 'Reload'; + } + } else if (apiError) { + // NOTE: If we get a status code of `null` we only know that the request has failed. We will + // guess that it is a SiteMinder timeout that failed the request. What has happened is that + // the original request will get a 302 and the browser will make a subsequent request to + // https://logontest7.gov.bc.ca/clp-cgi/int/logon.cgi. The request will fail because of CORS + // and the browser will erase any response data for security so we can't inspect any headers + // or response data. + const possibleSMError = apiError.status === 401 || apiError.status === 403 || apiError.status === null; + shouldReload = true; + + if (possibleSMError) { + modalTitle = 'Session expired'; + errorMessage = 'It looks like your session has expired. You will need to log in again.'; + buttonText = 'Log in'; + } else { + modalTitle = 'Server Error'; + errorMessage = apiError.message; + buttonText = 'Reload'; + + if (apiError.json) { + if (apiError.json.error) { + errorMessage = Error message: {errorMessage}; + } + + details = ( +
+

+ A HTTP {apiError.method.toUpperCase()} request to + {apiError.path} + returned a + {apiError.status} + status code. +

+
+

Response body:

+
+                  {JSON.stringify(apiError.json, null, 2)}
+                
+
+
+ ); + } + } + } + + const footer = ( + + + + ); + + return ( + {modalTitle}} + footer={footer} + onClose={this.closeDialog}> +
{errorMessage}
+ {details} +
+ ); + } +} + +function mapStateToProps(state) { + return { + showSessionTimeoutDialog: state.ui.showSessionTimeoutDialog, + appError: state.ui.appError, + apiError: state.ui.requests.error, + }; +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators({ + closeErrorDialog, + }, dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(ErrorDialog); diff --git a/client2/src/js/views/dialogs/HireOfferEditDialog.jsx b/client2/src/js/views/dialogs/HireOfferEditDialog.jsx new file mode 100644 index 000000000..b0610c0f9 --- /dev/null +++ b/client2/src/js/views/dialogs/HireOfferEditDialog.jsx @@ -0,0 +1,465 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { + Grid, + Row, + Col, + Radio, + FormGroup, + ControlLabel, + HelpBlock, +} from "react-bootstrap"; +import _ from "lodash"; + +import * as Api from "../../api"; +import * as Constant from "../../constants"; + +import ConfirmForceHireDialog from "../dialogs/ConfirmForceHireDialog.jsx"; +import ConfirmDialog from "../dialogs/ConfirmDialog.jsx"; + +import CheckboxControl from "../../components/CheckboxControl.jsx"; +import DropdownControl from "../../components/DropdownControl.jsx"; +import FormDialog from "../../components/FormDialog.jsx"; +import FormInputControl from "../../components/FormInputControl.jsx"; + +import { today, toZuluTime, formatDateTime } from "../../utils/date"; +import { isBlank } from "../../utils/string"; + +const STATUS_YES = "Yes"; +const STATUS_NO = "No"; +const STATUS_ASKED = "Asked"; +const STATUS_FORCE_HIRE = "Force Hire"; + +const refusalReasons = [ + Constant.HIRING_REFUSAL_EQUIPMENT_NOT_AVAILABLE, + Constant.HIRING_REFUSAL_EQUIPMENT_NOT_SUITABLE, + Constant.HIRING_REFUSAL_NO_RESPONSE, + Constant.HIRING_REFUSAL_MAXIMUM_HOURS_REACHED, + Constant.HIRING_REFUSAL_MAINTENANCE_CONTRACTOR, + Constant.HIRING_REFUSAL_OTHER, +]; + +class HireOfferEditDialog extends React.Component { + static displayName = "HireOfferEditDialog"; + + static propTypes = { + hireOffer: PropTypes.object.isRequired, + showAllResponseFields: PropTypes.bool.isRequired, + rentalRequest: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = this.buildInitialState(); + } + + buildInitialState() { + return { + isSaving: false, + + isForceHire: this.props.hireOffer.isForceHire || false, + wasAsked: this.props.hireOffer.wasAsked || false, + askedDateTime: this.props.hireOffer.askedDateTime || "", + offerResponse: this.props.hireOffer.offerResponse || "", + offerStatus: this.props.hireOffer.offerResponse || "", + offerRefusalReason: this.props.hireOffer.offerRefusalReason, + offerResponseDatetime: this.props.hireOffer.offerResponseDatetime || "", + offerResponseNote: this.props.hireOffer.offerResponseNote || "", + note: this.props.hireOffer.note || "", + + offerResponseError: "", + offerResponseNoteError: "", + offerRefusalReasonError: "", + + showConfirmForceHireDialog: false, + showConfirmMaxHoursHireDialog: false, + + equipmentVerifiedActive: false, + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + offerStatusChanged = (value) => { + this.setState({ + offerStatus: value, + offerResponse: value, + offerResponseDatetime: value !== STATUS_ASKED ? today() : null, + isForceHire: value === STATUS_FORCE_HIRE, + wasAsked: STATUS_ASKED, + askedDateTime: value === STATUS_ASKED ? today() : null, + equipmentVerifiedActive: + value === STATUS_YES || value === STATUS_FORCE_HIRE ? true : false, + }); + }; + + didChange = () => { + if (this.state.isForceHire !== this.props.hireOffer.isForceHire) { + return true; + } + if (this.state.wasAsked !== this.props.hireOffer.wasAsked) { + return true; + } + if (this.state.askedDateTime !== this.props.hireOffer.askedDateTime) { + return true; + } + if (this.state.offerResponse !== this.props.hireOffer.offerResponse) { + return true; + } + if ( + this.state.offerRefusalReason !== this.props.hireOffer.offerRefusalReason + ) { + return true; + } + if ( + this.state.offerResponseDatetime !== + this.props.hireOffer.offerResponseDatetime + ) { + return true; + } + if ( + this.state.offerResponseNote !== this.props.hireOffer.offerResponseNote + ) { + return true; + } + if (this.state.note !== this.props.hireOffer.note) { + return true; + } + + return false; + }; + + isValid = () => { + this.setState({ + offerResponseError: "", + offerRefusalReasonError: "", + offerResponseNoteError: "", + rentalAgreementError: "", + }); + + var valid = true; + + if (isBlank(this.state.offerResponse)) { + this.setState({ offerResponseError: "A response is required" }); + valid = false; + } + + if ( + this.state.offerResponse === STATUS_NO && + isBlank(this.state.offerRefusalReason) + ) { + this.setState({ + offerRefusalReasonError: "A refusal reason is required", + }); + valid = false; + } + + if ( + this.state.offerStatus === STATUS_NO && + this.state.offerRefusalReason === Constant.HIRING_REFUSAL_OTHER && + isBlank(this.state.offerResponseNote) + ) { + this.setState({ offerResponseNoteError: "Note is required" }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var isDumpTruck = + this.props.hireOffer.equipment.districtEquipmentType.equipmentType + .isDumpTruck; + var hoursYtd = this.props.hireOffer.equipment.hoursYtd; + + if ( + this.state.offerStatus !== STATUS_NO && + !isDumpTruck && + hoursYtd >= 300 + ) { + this.openConfirmMaxHoursHireDialog(); + } else if ( + this.state.offerStatus !== STATUS_NO && + isDumpTruck && + hoursYtd >= 600 + ) { + this.openConfirmMaxHoursHireDialog(); + } else if (this.state.offerStatus === STATUS_FORCE_HIRE) { + this.openConfirmForceHireDialog(); + } else { + this.saveHireOffer(); + } + } else { + this.props.onClose(); + } + } + }; + + onCancelMaxHoursHire = () => { + if (this.state.offerResponse === STATUS_FORCE_HIRE) { + this.setState(this.buildInitialState()); + } else { + this.offerStatusChanged(STATUS_NO); + this.setState({ + offerRefusalReason: Constant.HIRING_REFUSAL_MAXIMUM_HOURS_REACHED, + }); + } + this.closeConfirmMaxHoursHireDialog(); + }; + + onConfirmMaxHoursHire = () => { + if (this.state.offerStatus === STATUS_FORCE_HIRE) { + return this.openConfirmForceHireDialog(); + } + + this.saveHireOffer(); + }; + + saveHireOffer = () => { + var promise = Promise.resolve(); + + if (this.state.equipmentVerifiedActive) { + // Update Equipment's last verified date + const equipment = { + ...this.props.hireOffer.equipment, + lastVerifiedDate: toZuluTime(today()), + }; + + promise = Api.updateEquipment(equipment); + } + + promise.then(() => { + const hireOffer = { + ..._.omit(this.props.hireOffer, "displayFields", "rentalAgreement"), + isForceHire: this.state.isForceHire, + wasAsked: this.state.wasAsked ? true : false, + askedDateTime: + this.state.offerResponse === STATUS_ASKED + ? formatDateTime(new Date()) + : toZuluTime(this.state.askedDateTime), + offerResponse: this.state.offerResponse, + offerResponseDatetime: toZuluTime(this.state.offerResponseDatetime), + offerRefusalReason: this.state.offerRefusalReason, + offerResponseNote: this.state.offerResponseNote, + note: this.state.note, + }; + + Api.updateRentalRequestRotationList( + hireOffer, + this.props.rentalRequest + ).then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { + this.props.onSave(hireOffer); + } + }); + }); + }; + + onConfirmForceHire = (reasonForForceHire) => { + this.setState( + { note: reasonForForceHire, showConfirmForceHireDialog: false }, + this.saveHireOffer + ); + }; + + openConfirmForceHireDialog = () => { + this.setState({ showConfirmForceHireDialog: true }); + }; + + closeConfirmForceHireDialog = () => { + this.setState({ showConfirmForceHireDialog: false, isSaving: false }); + }; + + openConfirmMaxHoursHireDialog = () => { + this.setState({ showConfirmMaxHoursHireDialog: true }); + }; + + closeConfirmMaxHoursHireDialog = () => { + this.setState({ showConfirmMaxHoursHireDialog: false, isSaving: false }); + }; + + render() { + // Read-only if the user cannot edit the rental agreement + var isReadOnly = + !this.props.rentalRequest.canEdit && this.props.rentalRequest.id !== 0; + + return ( + + + + + Response + + + + this.offerStatusChanged(STATUS_YES)} + checked={this.state.offerStatus === STATUS_YES} + disabled={ + !this.props.showAllResponseFields && + !this.props.hireOffer.offerResponse + } + > + Yes + + + + + + + + this.offerStatusChanged(STATUS_NO)} + checked={this.state.offerStatus === STATUS_NO} + disabled={ + !this.props.showAllResponseFields && + !this.props.hireOffer.offerResponse + } + > + No + + + + + {this.state.offerStatus === STATUS_NO && ( + + + + {/*TODO - use lookup list*/} + Refusal Reason + + + {this.state.offerRefusalReasonError} + + + + + )} + + + + + this.offerStatusChanged(STATUS_FORCE_HIRE) + } + checked={this.state.offerStatus === STATUS_FORCE_HIRE} + > + Force Hire + + + + + + + + this.offerStatusChanged(STATUS_ASKED)} + checked={this.state.offerStatus === STATUS_ASKED} + disabled={ + !this.props.showAllResponseFields && + !this.props.hireOffer.offerResponse + } + > + Asked + + + + + {this.state.offerResponseError} + + + + + + Note + + {this.state.offerResponseNoteError} + + + + + + + + Verified Active + + + + + + {this.state.showConfirmForceHireDialog && ( + + )} + {this.state.showConfirmMaxHoursHireDialog && ( + +

+ Equipment/Dump Truck has already reached the maximum hours for the + year. Do you still want to hire this Equipment/Dump Truck? +

+
+ )} +
+ ); + } +} + +function mapStateToProps() { + return {}; +} + +export default connect(mapStateToProps)(HireOfferEditDialog); diff --git a/client2/src/js/views/dialogs/NotesAddDialog.jsx b/client2/src/js/views/dialogs/NotesAddDialog.jsx new file mode 100644 index 000000000..5c2dee2ca --- /dev/null +++ b/client2/src/js/views/dialogs/NotesAddDialog.jsx @@ -0,0 +1,106 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import * as Constant from '../../constants'; + +import { isBlank } from '../../utils/string'; + +class NotesAddDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onUpdate: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + note: PropTypes.object, + }; + + constructor(props) { + super(props); + + this.state = { + noteId: props.note.id || 0, + note: props.note.text || '', + concurrencyControlNumber: props.note.concurrencyControlNumber || 0, + noteError: '', + isNoLongerRelevant: false, + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.props.note.text !== this.state.note) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + noteError: '', + }); + + var valid = true; + + if (isBlank(this.state.note)) { + this.setState({ noteError: 'Note is required' }); + valid = false; + } + + return valid; + }; + + onFormSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + // If note id === 0 then you are adding a new note, otherwise you are updating an existing note + if (this.state.noteId === 0) { + this.props.onSave({ + id: 0, + text: this.state.note, + isNoLongerRelevant: false, + createDate: new Date().toISOString(), + }); + } else { + this.props.onUpdate({ + id: this.state.noteId, + text: this.state.note, + concurrencyControlNumber: this.state.concurrencyControlNumber, + isNoLongerRelevant: false, + }); + } + } else { + this.props.onClose(); + } + } + }; + + render() { + const { noteId } = this.state; + var maxLength = Constant.MAX_LENGTH_NOTE_TEXT; + + return ( + + + Note + + { this.state.noteError } +

Maximum { maxLength } characters.

+
+
+ ); + } +} + +export default NotesAddDialog; diff --git a/client2/src/js/views/dialogs/NotesDialog.jsx b/client2/src/js/views/dialogs/NotesDialog.jsx new file mode 100644 index 000000000..813a815cb --- /dev/null +++ b/client2/src/js/views/dialogs/NotesDialog.jsx @@ -0,0 +1,156 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { ButtonGroup, Button, Glyphicon, Alert } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import NotesAddDialog from './NotesAddDialog.jsx'; +import ModalDialog from '../../components/ModalDialog.jsx'; +import TableControl from '../../components/TableControl.jsx'; +import DeleteButton from '../../components/DeleteButton.jsx'; +import EditButton from '../../components/EditButton.jsx'; +import Authorize from '../../components/Authorize.jsx'; + +import { formatDateTimeUTCToLocal } from '../../utils/date'; + + +class NotesDialog extends React.Component { + static propTypes = { + id: PropTypes.string.isRequired, + show: PropTypes.bool, + notes: PropTypes.array, + // Api call to get notes for particular entity + getNotes: PropTypes.func.isRequired, + // Api function to call on save + saveNote: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + note: {}, + notes: props.notes || [], + }; + } + + componentWillReceiveProps(nextProps) { + if (!_.isEqual(this.props.notes, nextProps.notes)) { + this.setState({ notes: nextProps.notes }); + } + } + + openNotesAddDialog = () => { + this.setState({ showNotesAddDialog : true }); + }; + + closeNotesAddDialog = () => { + this.setState({ + note: {}, + showNotesAddDialog: false, + }); + }; + + onNoteAdded = (note) => { + this.setState({ notes: this.state.notes.concat([note]) }); + this.props.saveNote(this.props.id, note).then(() => { + this.props.getNotes(this.props.id); + }); + this.closeNotesAddDialog(); + }; + + onNoteUpdated = (note) => { + const noteId = note.id; + const updatedNotes = this.state.notes.map((_note) => { + return _note.id === noteId ? {..._note, ...note} : _note; + }); + + this.setState({ notes: updatedNotes }); + Api.updateNote(note).then(() => { + this.props.getNotes(this.props.id); + }); + this.closeNotesAddDialog(); + }; + + deleteNote = (note) => { + const noteId = note.id; + const updatedNotes = this.state.notes.filter((note) => { + return note.id !== noteId; + }); + + this.setState({ notes: updatedNotes }); + Api.deleteNote(note.id).then(() => { + this.props.getNotes(this.props.id); + }); + }; + + editNote = (note) => { + this.setState({ + note: note, + showNotesAddDialog: true, + }); + }; + + onClose = () => { + this.props.onClose(); + }; + + render() { + const notes = _.orderBy(this.state.notes, ['createDate'], ['desc']); + var headers = [ + { field: 'date', title: 'Date' }, + { field: 'note', title: 'Note' }, + { field: 'blank' }, + ]; + + const showNoNotesMessage = !notes || notes.length === 0; + + return ( + Notes}> + + { + notes.map((note) => { + return ( + + { formatDateTimeUTCToLocal(note.createDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } + { note.text } + + + + + + + + ); + }) + } + + {showNoNotesMessage && ( + No notes + )} + + + + { this.state.showNotesAddDialog && ( + + )} + + ); + } +} + +export default NotesDialog; diff --git a/client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx b/client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx new file mode 100644 index 000000000..910e47fe3 --- /dev/null +++ b/client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx @@ -0,0 +1,138 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { FormGroup, HelpBlock, ControlLabel, Row, Col } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + +class OvertimeRateEditDialog extends React.Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + overtimeRateType: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + rateId: props.overtimeRateType.id, + rateType: props.overtimeRateType.rateType || '', + description: props.overtimeRateType.description || '', + value: props.overtimeRateType.rate || 0, + concurrencyControlNumber: props.overtimeRateType.concurrencyControlNumber || 0, + descriptionError: '', + valueError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.description !== this.props.overtimeRateType.description) { return true; } + if (this.state.value !== this.props.overtimeRateType.value) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + descriptionError: '', + valueError: '', + }); + + var valid = true; + + if (isBlank(this.state.description)) { + this.setState({ descriptionError: 'Description is required' }); + valid = false; + } + + var moneyRegex = new RegExp(Constant.MONEY_REGEX); + if (isBlank(this.state.value)) { + this.setState({ valueError: 'Value is required' }); + valid = false; + } else if (this.state.value < 0) { + this.setState({ valueError: 'Value must be positive' }); + valid = false; + } else if (!moneyRegex.test(this.state.value)) { + this.setState({ valueError: 'Value must have at most 2 digits after the decimal' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var rateType = { + id: this.state.rateId, + rateType: this.state.rateType, + description: this.state.description, + rate: this.state.value.toFixed(2), + periodType: Constant.RENTAL_RATE_PERIOD_HOURLY, + concurrencyControlNumber: this.state.concurrencyControlNumber, + active: true, + }; + + const promise = Api.updateOvertimeRateType(rateType); + + promise.then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + return ( + + + + + Description * + + { this.state.descriptionError } + + + + + Value * +
+ $ + + per hour +
+ { this.state.valueError } +
+ +
+
+ ); + } +} + +export default OvertimeRateEditDialog; diff --git a/client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx b/client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx new file mode 100644 index 000000000..3095bd539 --- /dev/null +++ b/client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx @@ -0,0 +1,160 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; +import { OWNER_STATUS_CODE_APPROVED } from '../../constants'; + +const ARCHIVE_WARNING_MESSAGE = 'This action will archive the owner and all their equipment and remove them from the seniority list.'; + +class ChangeStatusDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + status: PropTypes.string.isRequired, + owner: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + onStatusChanged: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + comment: '', + commentError: '', + statusError: '', + archiveWarning: props.status === Constant.OWNER_STATUS_CODE_ARCHIVED ? ARCHIVE_WARNING_MESSAGE : '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + return true; + }; + + isValid = () => { + this.setState({ + commentError: '', + statusError: '', + }); + + var valid = true; + + if (isBlank(this.state.comment)) { + this.setState({ commentError: 'Comment is required' }); + valid = false; + } + + if (this.props.owner && this.props.status === OWNER_STATUS_CODE_APPROVED && (this.statusRequirements()).length > 0) { + this.setState({ statusError: this.statusRequirements() }); + valid = false; + } + + return valid; + }; + + statusRequirements = () => { + const { owner } = this.props; + var requirements = []; + + if (!owner.primaryContact) { + requirements.push('Primary contact'); + } + if (isBlank(owner.workSafeBCPolicyNumber)) { + requirements.push('WorkSafeBC policy number'); + } + if (!owner.address1 || !owner.city || !owner.province || !owner.province) { + requirements.push('Company address'); + } + if (!owner.meetsResidency) { + requirements.push('Meets residency'); + } + + return requirements; + }; + + formSubmitted = () => { + if (this.isValid()) { + this.setState({isSaving: true}); + const status = { + id: this.props.owner.id, + status: this.props.status, + statusComment: this.state.comment, + }; + var currentStatus = this.props.owner.status; + var equipmentList = { ...this.props.owner.equipmentList }; + + return Api.changeOwnerStatus(status).then(() => { + this.setState({isSaving: false}); + this.props.onStatusChanged(status); + Log.ownerModifiedStatus(this.props.owner, status.status, status.statusComment); + // If owner status goes from approved to unapproved/archived or unapproved to archived + // this will change all it's equipment statuses. This should be reflected in the equipment history. + if ( + (currentStatus === Constant.OWNER_STATUS_CODE_APPROVED || currentStatus === Constant.OWNER_STATUS_CODE_PENDING) + && (status.status === Constant.OWNER_STATUS_CODE_PENDING || status.status === Constant.OWNER_STATUS_CODE_ARCHIVED) + ) { + _.map(equipmentList, equipment => { + if (equipment.status !== status.status) { + Log.equipmentStatusModified(equipment, status.status, status.statusComment); + } + }); + } + }).catch((error) => { + if (error.status === 400 && error.errorCode === 'HETS-40') { + this.setState({ commentError: error.errorDescription }); + } else { + throw error; + } + }); + } + }; + + render() { + var statusErrorText = this.state.statusError && this.state.statusError.length <= 1 ? 'The following is also required:' : 'The following are also required:'; + var maxLength = Constant.MAX_LENGTH_STATUS_COMMENT; + + const archiving = this.props.status === Constant.OWNER_STATUS_CODE_ARCHIVED; + + return ( + + + Comment + + {this.state.commentError} +

Maximum { maxLength } characters.

+ {this.state.statusError && statusErrorText} +
    + { + _.map(this.state.statusError, (error) => { + return
  • {error}
  • ; + }) + } +
+
+ { archiving &&
{ this.state.archiveWarning }
} +
+
+ ); + } +} + +export default ChangeStatusDialog; diff --git a/client2/src/js/views/dialogs/OwnersAddDialog.jsx b/client2/src/js/views/dialogs/OwnersAddDialog.jsx new file mode 100644 index 000000000..690f56616 --- /dev/null +++ b/client2/src/js/views/dialogs/OwnersAddDialog.jsx @@ -0,0 +1,589 @@ +import PropTypes from "prop-types"; +import React from "react"; +import { connect } from "react-redux"; +import { FormGroup, HelpBlock, ControlLabel } from "react-bootstrap"; +import _ from "lodash"; + +import * as Constant from "../../constants"; +import * as Api from "../../api"; +import * as Log from "../../history"; + +import FormDialog from "../../components/FormDialog.jsx"; +import CheckboxControl from "../../components/CheckboxControl.jsx"; +import DropdownControl from "../../components/DropdownControl.jsx"; +import FilterDropdown from "../../components/FilterDropdown.jsx"; +import FormInputControl from "../../components/FormInputControl.jsx"; + +import { isBlank, onlyLetters } from "../../utils/string"; + +const HELP_TEXT = { + prefix: + "This field must include only letters, up to 7 characters and be unique across all owners", + residency: + "You have not indicated the owner meets the Residency requirements of the HETS Program. If that is the case, the owner may not be registered in this local area until they have met this requirement. If this check was missed inadvertently, return and activate the checkbox. If the owner does not meet the residency requirement, return and cancel from the Add Owner popup.", +}; + +class OwnersAddDialog extends React.Component { + static propTypes = { + owners: PropTypes.object, + currentUser: PropTypes.object, + localAreas: PropTypes.object, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + name: "", + doingBusinessAs: "", + givenName: "", + surname: "", + address1: "", + address2: "", + city: "", + province: "BC", + postalCode: "", + ownerCode: "", + // localAreaId: defaultLocalAreaId.id || 0, + localAreaId: 0, + isMaintenanceContractor: false, + meetsResidency: true, + registeredCompanyNumber: "", + workSafeBCPolicyNumber: "", + primaryContactPhone: "", + primaryContactGivenName: "", + primaryContactSurname: "", + primaryContactRole: "", + status: Constant.OWNER_STATUS_CODE_APPROVED, + + nameError: "", + ownerGivenNameError: "", + ownerSurameError: "", + address1Error: "", + cityError: "", + provinceError: "", + postalCodeError: "", + ownerCodeError: "", + localAreaError: "", + residencyError: "", + workSafeBCPolicyNumberError: "", + primaryContactPhoneError: "", + }; + } + + componentDidMount() { + Api.getOwnersLite(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.organizationName !== "") { + return true; + } + if (this.state.doingBusinessAs !== "") { + return true; + } + if (this.state.givenName !== "") { + return true; + } + if (this.state.surname !== "") { + return true; + } + if (this.state.address1 !== "") { + return true; + } + if (this.state.address2 !== "") { + return true; + } + if (this.state.city !== "") { + return true; + } + if (this.state.province !== "BC") { + return true; + } + if (this.state.postalCode !== "") { + return true; + } + if (this.state.ownerCode !== "") { + return true; + } + if (this.state.localAreaId !== 0) { + return true; + } + if (this.state.registeredCompanyNumber !== "") { + return true; + } + if (this.state.workSafeBCPolicyNumber !== "") { + return true; + } + if (this.state.primaryContactGivenName !== "") { + return true; + } + if (this.state.primaryContactSurname !== "") { + return true; + } + if (this.state.primaryContactPhone !== "") { + return true; + } + if (this.state.primaryContactRole !== "") { + return true; + } + if (this.state.status !== Constant.OWNER_STATUS_CODE_APPROVED) { + return true; + } + + return false; + }; + + isValid = () => { + // Clear out any previous errors + var valid = true; + + this.setState({ + nameError: "", + address1Error: "", + cityError: "", + provinceError: "", + postalCodeError: "", + ownerCodeError: "", + localAreaError: "", + residencyError: "", + workSafeBCPolicyNumberError: "", + primaryContactGivenNameError: "", + primaryContactPhoneError: "", + }); + + if (isBlank(this.state.name)) { + this.setState({ nameError: "Name is required" }); + valid = false; + } else { + // Does the name already exist? + var nameIgnoreCase = this.state.name.toLowerCase().trim(); + var other = _.find( + this.props.owners.data, + (other) => + other.organizationName.toLowerCase().trim() === nameIgnoreCase + ); + if (other) { + this.setState({ + nameError: "This company name already exists in the system", + }); + valid = false; + } + } + + if (isBlank(this.state.givenName)) { + this.setState({ ownerGivenNameError: "Owner first name is required" }); + valid = false; + } + + if (isBlank(this.state.surname)) { + this.setState({ ownerSurameError: "Owner last name is required" }); + valid = false; + } + + if (isBlank(this.state.address1)) { + this.setState({ address1Error: "Address line 1 is required" }); + valid = false; + } + + if (isBlank(this.state.city)) { + this.setState({ cityError: "City is required" }); + valid = false; + } + + if (isBlank(this.state.province)) { + this.setState({ provinceError: "Province is required" }); + valid = false; + } + + if (isBlank(this.state.postalCode)) { + this.setState({ postalCodeError: "Postal code is required" }); + valid = false; + } else if (!Constant.POSTAL_CODE_REGEX.test(this.state.postalCode)) { + this.setState({ postalCodeError: "Invalid postal code" }); + valid = false; + } + + if (isBlank(this.state.ownerCode)) { + this.setState({ ownerCodeError: "Owner code is required" }); + valid = false; + } else { + var code = this.state.ownerCode.toLowerCase().trim(); + + // Must only include letters, up to 7 characters + if (!onlyLetters(code) || code.length > 7) { + this.setState({ + ownerCodeError: + "This owner code must only include letters, up to 7 characters, and has to be unique to each owner", + }); + valid = false; + } + } + + if (this.state.localAreaId === 0) { + this.setState({ + localAreaError: "Service area / local area is required", + }); + valid = false; + } + + if (this.state.meetsResidency === false) { + this.setState({ residencyError: HELP_TEXT.residency }); + valid = false; + } + + if (isBlank(this.state.workSafeBCPolicyNumber)) { + this.setState({ workSafeBCPolicyNumberError: "WCB number is required" }); + valid = false; + } + + if (isBlank(this.state.primaryContactGivenName)) { + this.setState({ primaryContactGivenNameError: "First name is required" }); + valid = false; + } + + if (isBlank(this.state.primaryContactPhone)) { + this.setState({ primaryContactPhoneError: "Phone number is required" }); + valid = false; + } else if (!Constant.NANP_REGEX.test(this.state.primaryContactPhone)) { + this.setState({ primaryContactPhoneError: "Invalid phone number" }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var owner = { + organizationName: this.state.name, + doingBusinessAs: this.state.doingBusinessAs, + givenName: this.state.givenName, + surname: this.state.surname, + address1: this.state.address1, + address2: this.state.address2, + city: this.state.city, + province: this.state.province, + postalCode: this.state.postalCode, + ownerCode: this.state.ownerCode, + localArea: { id: this.state.localAreaId }, + isMaintenanceContractor: this.state.isMaintenanceContractor, + meetsResidency: this.state.meetsResidency, + registeredCompanyNumber: this.state.registeredCompanyNumber, + workSafeBCPolicyNumber: this.state.workSafeBCPolicyNumber, + primaryContactGivenName: this.state.primaryContactGivenName, + primaryContactSurname: this.state.primaryContactSurname, + primaryContactPhone: this.state.primaryContactPhone, + primaryContactRole: this.state.primaryContactRole, + status: this.state.status, + }; + + const promise = Api.addOwner(owner); + + promise.then((newOwner) => { + Log.ownerAdded(newOwner); + this.setState({ isSaving: false }); + if (this.props.onSave) { + this.props.onSave(newOwner); + } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + // Constrain the local area drop downs to those in the District of the current logged in user + var localAreas = _.chain(this.props.localAreas).sortBy("name").value(); + + return ( + + + + Company Name * + + + {this.state.nameError} + + + Doing Business As + + + + + Owner First Name * + + + {this.state.ownerGivenNameError} + + + + Owner Last Name * + + + {this.state.ownerSurameError} + + + + Address Line 1 * + + + {this.state.address1Error} + + + Address Line 2 + + + + + City * + + + {this.state.cityError} + + + + Province * + + + {this.state.provinceError} + + + + Postal Code * + + + {this.state.postalCodeError} + + + + Owner Code * + + + {this.state.ownerCodeError || HELP_TEXT.prefix} + + + + Service Area - Local Area * + + + {this.state.localAreaError} + + + + WCB Number * + + + {this.state.workSafeBCPolicyNumberError} + + + + Primary Contact First Name * + + + {this.state.primaryContactGivenNameError} + + + Primary Contact Last Name + + + + + Primary Contact Phone * + + + {this.state.primaryContactPhoneError} + + + Primary Contact Role + + + + Status + + + + Registered BC Company Number + + + + + Maintenance Contractor + + + + + Meets Residency + + {this.state.residencyError} + + + ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + owners: state.lookups.owners.lite, + localAreas: state.lookups.localAreas, + }; +} + +export default connect(mapStateToProps)(OwnersAddDialog); diff --git a/client2/src/js/views/dialogs/OwnersEditDialog.jsx b/client2/src/js/views/dialogs/OwnersEditDialog.jsx new file mode 100644 index 000000000..fad95c515 --- /dev/null +++ b/client2/src/js/views/dialogs/OwnersEditDialog.jsx @@ -0,0 +1,267 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import CheckboxControl from '../../components/CheckboxControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + + +class OwnersEditDialog extends React.Component { + static propTypes = { + owner: PropTypes.object, + owners: PropTypes.object, + localAreas: PropTypes.object, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + var owner = props.owner; + + this.state = { + organizationName: owner.organizationName || '', + givenName: owner.givenName || '', + surname: owner.surname || '', + address1: owner.address1 || '', + address2: owner.address2 || '', + city: owner.city || '', + province: owner.province || '', + postalCode: owner.postalCode || '', + localAreaId: owner.localArea.id || 0, + isMaintenanceContractor: owner.isMaintenanceContractor || false, + doingBusinessAs: owner.doingBusinessAs || '', + registeredCompanyNumber: owner.registeredCompanyNumber || '', + status: owner.status || '', + + address1Error: '', + cityError: '', + provinceError: '', + postalCodeError: '', + organizationNameError: '', + localAreaError: '', + localAreaSeniorityChangeWarning: false, + }; + } + + componentDidMount() { + Api.getOwnersLite(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + var owner = this.props.owner; + + if (this.state.organizationName !== owner.organizationName) { return true; } + if (this.state.givenName !== owner.givenName) { return true; } + if (this.state.surname !== owner.surname) { return true; } + if (this.state.address1 !== owner.address1) { return true; } + if (this.state.address2 !== owner.address2) { return true; } + if (this.state.city !== owner.city) { return true; } + if (this.state.province !== owner.province) { return true; } + if (this.state.postalCode !== owner.postalCode) { return true; } + if (this.state.localAreaId !== owner.localArea.id) { return true; } + if (this.state.doingBusinessAs !== owner.doingBusinessAs) { return true; } + if (this.state.registeredCompanyNumber !== owner.registeredCompanyNumber) { return true; } + if (this.state.isMaintenanceContractor !== owner.isMaintenanceContractor) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + companyAddressError: '', + organizationNameError: '', + localAreaError: '', + }); + + var valid = true; + var owner = this.props.owner; + var orgName = this.state.organizationName; + + if (isBlank(orgName)) { + this.setState({ organizationNameError: 'Company name is required' }); + valid = false; + } else if (orgName !== owner.organizationName) { + // Does the name already exist? + var nameIgnoreCase = orgName.toLowerCase().trim(); + var otherOwners = _.reject(this.props.owners.data, { id: owner.id }); + var other = _.find(otherOwners, other => other.organizationName.toLowerCase().trim() === nameIgnoreCase); + if (other) { + this.setState({ organizationNameError: 'This company name already exists in the system' }); + valid = false; + } + } + + if (isBlank(this.state.address1)) { + this.setState({ address1Error: 'Address line 1 is required' }); + valid = false; + } + + if (isBlank(this.state.city)) { + this.setState({ cityError: 'City is required' }); + valid = false; + } + + if (isBlank(this.state.province)) { + this.setState({ provinceError: 'Province is required' }); + valid = false; + } + + if (isBlank(this.state.postalCode)) { + this.setState({ postalCodeError: 'Postal code is required' }); + valid = false; + } else if (!Constant.POSTAL_CODE_REGEX.test(this.state.postalCode)) { + this.setState({ postalCodeError: 'Invalid postal code' }); + valid = false; + } + + if (this.state.localAreaId === 0) { + this.setState({ localAreaError: 'Service area / local area is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const owner = { + ...this.props.owner, + organizationName: this.state.organizationName, + givenName: this.state.givenName, + surname: this.state.surname, + address1: this.state.address1, + address2: this.state.address2, + city: this.state.city, + province: this.state.province, + postalCode: this.state.postalCode, + localArea: { id: this.state.localAreaId }, + isMaintenanceContractor: this.state.isMaintenanceContractor, + doingBusinessAs: this.state.doingBusinessAs, + registeredCompanyNumber: this.state.registeredCompanyNumber, + status: this.state.status, + }; + + Api.updateOwner(owner).then(() => { + if (this.props.onSave) { this.props.onSave(); } + }); + } + + this.props.onClose(); + } + }; + + onLocalAreaChanged() { + if (this.state.localAreaId !== this.props.owner.localArea.id) { + this.setState({ + localAreaError: 'This action will change the local area and seniority of all the equipment for this owner.', + localAreaSeniorityChangeWarning: true, + }); + } else { + this.setState({ + localAreaError: '', + localAreaSeniorityChangeWarning: false, + }); + } + } + + render() { + var owner = this.props.owner; + var localAreas = _.sortBy(this.props.localAreas, 'name'); + + const saveWarning = this.state.localAreaSeniorityChangeWarning; + + return ( + + + Owner Code +

{ owner.ownerCode }

+
+ + Company Name * + + { this.state.organizationNameError } + + + Doing Business As + + + + Owner First Name + + + + Owner Last Name + + + + Address Line 1 * + + { this.state.address1Error } + + + Address Line 2 + + + + City * + + { this.state.cityError } + + + Province * + + { this.state.provinceError } + + + Postal Code * + + { this.state.postalCodeError } + + + Service Area - Local Area * + this.updateState(state, this.onLocalAreaChanged) } className="full-width" /> + { this.state.localAreaError } + + + Registered BC Company Number + + + + Maintenance Contractor + +
+ ); + } +} + +function mapStateToProps(state) { + return { + owners: state.lookups.owners.lite, + localAreas: state.lookups.localAreas, + }; +} + +export default connect(mapStateToProps)(OwnersEditDialog); diff --git a/client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx b/client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx new file mode 100644 index 000000000..122da07b6 --- /dev/null +++ b/client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx @@ -0,0 +1,158 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormGroup, ControlLabel, HelpBlock, Row, Col } from 'react-bootstrap'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import DateControl from '../../components/DateControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isValidDate, toZuluTime } from '../../utils/date'; +import { notBlank, isBlank } from '../../utils/string'; + + +class OwnersPolicyEditDialog extends React.Component { + static propTypes = { + owner: PropTypes.object, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + var owner = props.owner; + + this.state = { + workSafeBCPolicyNumber: owner.workSafeBCPolicyNumber || '', + workSafeBCExpiryDate: owner.workSafeBCExpiryDate || '', + cglCompanyName: owner.cglCompanyName || '', + cglPolicyNumber: owner.cglPolicyNumber || '', + cglEndDate: owner.cglEndDate || '', + + workSafeBCPolicyNumberError: '', + workSafeBCExpiryDateError: '', + cglEndDateError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + var owner = this.props.owner; + + if (this.state.workSafeBCPolicyNumber !== owner.workSafeBCPolicyNumber) { return true; } + if (this.state.workSafeBCExpiryDate !== owner.workSafeBCExpiryDate) { return true; } + if (this.state.cglCompanyName !== owner.cglCompanyName) { return true; } + if (this.state.cglPolicyNumber !== owner.cglPolicyNumber) { return true; } + if (this.state.cglEndDate !== owner.cglEndDate) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + workSafeBCPolicyNumberError: '', + workSafeBCExpiryDateError: '', + cglEndDateError: '', + }); + + var valid = true; + + if (isBlank(this.state.workSafeBCPolicyNumber)) { + this.setState({ workSafeBCPolicyNumberError: 'WBC is required' }); + valid = false; + } + + if (notBlank(this.state.workSafeBCExpiryDate) && !isValidDate(this.state.workSafeBCExpiryDate)) { + this.setState({ workSafeBCExpiryDateError: 'Date not valid' }); + valid = false; + } + + if (notBlank(this.state.cglEndDate) && !isValidDate(this.state.cglEndDate)) { + this.setState({ cglEndDateError: 'Date not valid' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const owner = { + ...this.props.owner, + workSafeBCPolicyNumber: this.state.workSafeBCPolicyNumber, + workSafeBCExpiryDate: toZuluTime(this.state.workSafeBCExpiryDate), + cglCompanyName: this.state.cglCompanyName, + cglPolicyNumber: this.state.cglPolicyNumber, + cglEndDate: toZuluTime(this.state.cglEndDate), + }; + + Api.updateOwner(owner).then(() => { + if (this.props.onSave) { this.props.onSave(); } + }); + } + + this.props.onClose(); + } + }; + + render() { + return ( + + + + + WCB Number * + + { this.state.workSafeBCPolicyNumberError } + + + + + WCB Expiry Date + + { this.state.workSafeBCExpiryDateError } + + + + + + + CGL Insurance Company + + + + + + + + CGL Policy Number + + + + + + CGL Policy End Date + + { this.state.cglEndDateError } + + + + + ); + } +} + +export default OwnersPolicyEditDialog; diff --git a/client2/src/js/views/dialogs/ProjectsAddDialog.jsx b/client2/src/js/views/dialogs/ProjectsAddDialog.jsx new file mode 100644 index 000000000..51e08c592 --- /dev/null +++ b/client2/src/js/views/dialogs/ProjectsAddDialog.jsx @@ -0,0 +1,266 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import _ from 'lodash'; +import { FormGroup, HelpBlock, ControlLabel, FormControl, Grid, Row, Col } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank, notBlank } from '../../utils/string'; + +class ProjectsAddDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + projects: PropTypes.object, + fiscalYears: PropTypes.array, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + name: '', + fiscalYear: _.first(_.takeRight(props.fiscalYears, 2)), + provincialProjectNumber: '', + responsibilityCentre: '', + serviceLine: '', + stob: '', + product: '', + businessFunction: '', + workActivity: '', + costType: '', + information: '', + + nameError: '', + fiscalYearError: '', + provincialProjectNumberError: '', + }; + } + + componentDidMount() { + Api.getProjects(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + return notBlank(this.state.name) || + notBlank(this.state.fiscalYear) || + notBlank(this.state.provincialProjectNumber) || + notBlank(this.state.responsibilityCentre) || + notBlank(this.state.serviceLine) || + notBlank(this.state.stob) || + notBlank(this.state.product) || + notBlank(this.state.businessFunction) || + notBlank(this.state.workActivity) || + notBlank(this.state.costType) || + notBlank(this.state.information); + }; + + isValid = () => { + // Clear out any previous errors + var valid = true; + + this.setState({ + nameError: '', + fiscalYearError: '', + provincialProjectNumberError: '', + }); + + const { name, fiscalYear, provincialProjectNumber } = this.state; + + if (isBlank(name)) { + this.setState({ nameError: 'Project name is required' }); + valid = false; + } + + if (isBlank(fiscalYear)) { + this.setState({ fiscalYearError: 'Fiscal year is required' }); + valid = false; + } + + if (isBlank(provincialProjectNumber)) { + this.setState({ provincialProjectNumberError: 'Provincial project number is required' }); + valid = false; + } + + if (!valid) { + return false; + } + + const duplicateProject = _.find(this.props.projects.data, project => { + return project.name.toLowerCase().trim() === name.toLowerCase().trim() && + project.fiscalYear.toLowerCase().trim() === fiscalYear.toLowerCase().trim() && + project.provincialProjectNumber.toLowerCase().trim() === provincialProjectNumber.toLowerCase().trim(); + }); + + if (duplicateProject) { + this.setState({ nameError: 'A project with the same name and project number exists for the selected fiscal year.'}); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var project = { + name: this.state.name, + fiscalYear: this.state.fiscalYear, + provincialProjectNumber: this.state.provincialProjectNumber, + district: { id: this.props.currentUser.district.id }, + status: Constant.PROJECT_STATUS_CODE_ACTIVE, + responsibilityCentre: this.state.responsibilityCentre, + serviceLine: this.state.serviceLine, + stob: this.state.stob, + product: this.state.product, + businessFunction: this.state.businessFunction, + workActivity: this.state.workActivity, + costType: this.state.costType, + information: this.state.information, + }; + + const promise = Api.addProject(project); + + promise.then((newProject) => { + Log.projectAdded(newProject); + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(newProject); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + return ( + + + + + + Project Name * + + { this.state.nameError } + + + + + + + District + { this.props.currentUser.district.name } + + + + + Fiscal Year * + + { this.state.fiscalYearError } + + + + + + + Provincial Project Number * + + { this.state.provincialProjectNumberError } + + + + + Responsibility Centre + + + + + + + + Service Line + + + + + + STOB + + + + + + + + Product + + + + + + Business Function + + + + + + + + Work Activity + + + + + + Cost Type + + + + + + + + Project Information + + + + + + + ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + projects: state.lookups.projects, + fiscalYears: state.lookups.fiscalYears, + }; +} + +export default connect(mapStateToProps)(ProjectsAddDialog); diff --git a/client2/src/js/views/dialogs/ProjectsEditDialog.jsx b/client2/src/js/views/dialogs/ProjectsEditDialog.jsx new file mode 100644 index 000000000..6b3236f63 --- /dev/null +++ b/client2/src/js/views/dialogs/ProjectsEditDialog.jsx @@ -0,0 +1,267 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { connect } from 'react-redux'; + +import { Grid, Row, Col, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import _ from 'lodash'; + +import * as Action from '../../actionTypes'; +import * as Api from '../../api'; +import * as Log from '../../history'; +import store from '../../store'; + +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; +import Form from '../../components/Form.jsx'; + +import { isBlank } from '../../utils/string'; + +class ProjectsEditDialog extends React.Component { + static propTypes = { + fiscalYears: PropTypes.array, + project: PropTypes.object, + projects: PropTypes.object, + + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + name: props.project.name || '', + fiscalYear: props.project.fiscalYear || _.first( _.takeRight(props.fiscalYears, 2)), + provincialProjectNumber: props.project.provincialProjectNumber || '', + responsibilityCentre: props.project.responsibilityCentre || '', + serviceLine: props.project.serviceLine || '', + stob: props.project.stob || '', + product: props.project.product || '', + businessFunction: props.project.businessFunction || '', + workActivity: props.project.workActivity || '', + costType: props.project.costType || '', + projectInformation: props.project.information || '', + concurrencyControlNumber: props.project.concurrencyControlNumber || 0, + nameError: '', + fiscalYearError: '', + provincialProjectNumberError: '', + }; + } + + componentDidMount() { + Api.getProjects(); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + var project = this.props.project; + + if (this.state.name !== project.name) { return true; } + if (this.state.fiscalYear !== project.fiscalYear) { return true; } + if (this.state.provincialProjectNumber !== project.provincialProjectNumber) { return true; } + if (this.state.responsibilityCentre !== project.responsibilityCentre) { return true; } + if (this.state.serviceLine !== project.serviceLine) { return true; } + if (this.state.stob !== project.stob) { return true; } + if (this.state.product !== project.product) { return true; } + if (this.state.businessFunction !== project.businessFunction) { return true; } + if (this.state.workActivity !== project.workActivity) { return true; } + if (this.state.costType !== project.costType) { return true; } + if (this.state.projectInformation !== project.information) { return true; } + + return false; + }; + + isValid = () => { + var valid = true; + + this.setState({ + nameError: '', + fiscalYearError: '', + provincialProjectNumberError: '', + }); + + const { name, fiscalYear, provincialProjectNumber } = this.state; + + if (isBlank(name)) { + this.setState({ nameError: 'Project name is required' }); + valid = false; + } + + if (isBlank(fiscalYear)) { + this.setState({ fiscalYearError: 'Fiscal year is required' }); + valid = false; + } + + if (isBlank(provincialProjectNumber)) { + this.setState({ provincialProjectNumberError: 'Provincial project number is required' }); + valid = false; + } + + if (!valid) { + return false; + } + + const duplicateProject = _.find(this.props.projects.data, project => { + return project.id !== this.props.project.id && + project.name.toLowerCase().trim() === name.toLowerCase().trim() && + project.fiscalYear.toLowerCase().trim() === fiscalYear.toLowerCase().trim() && + project.provincialProjectNumber.toLowerCase().trim() === provincialProjectNumber.toLowerCase().trim(); + }); + + if (duplicateProject) { + this.setState({ nameError: 'A project with the same name and project number exists for the selected fiscal year.'}); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const project = { + ...this.props.project, + id: this.props.project.id, + district: this.props.project.district, + name: this.state.name, + fiscalYear: this.state.fiscalYear, + provincialProjectNumber: this.state.provincialProjectNumber, + responsibilityCentre: this.state.responsibilityCentre, + serviceLine: this.state.serviceLine, + stob: this.state.stob, + product: this.state.product, + businessFunction: this.state.businessFunction, + workActivity: this.state.workActivity, + costType: this.state.costType, + information: this.state.projectInformation, + concurrencyControlNumber: this.state.concurrencyControlNumber, + }; + + store.dispatch({ type: Action.UPDATE_PROJECT, project }); + + Log.projectModified(this.props.project); + + Api.updateProject(project); + } + + this.props.onClose(); + } + }; + + render() { + // TODO: Restrict Information box resize + return ( + +
+ + + + + Project Name * + + { this.state.nameError } + + + + + + + Fiscal Year * + + { this.state.fiscalYearError } + + + + + Provincial Project Number * + + { this.state.provincialProjectNumberError } + + + + + + + Responsibility Centre + + + + + + + + Service Line + + + + + + STOB + + + + + + + + Product + + + + + + Business Function + + + + + + + + Work Activity + + + + + + Cost Type + + + + + + + + Project Information + + + + + +
+
+ ); + } +} + +function mapStateToProps(state) { + return { + fiscalYears: state.lookups.fiscalYears, + projects: state.lookups.projects, + }; +} + +export default connect(mapStateToProps)(ProjectsEditDialog); diff --git a/client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx b/client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx new file mode 100644 index 000000000..2e8c47ad0 --- /dev/null +++ b/client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx @@ -0,0 +1,109 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Grid, Row, Col, FormGroup, ControlLabel } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import CheckboxControl from '../../components/CheckboxControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + + +class RentalAgreementOvertimeNotesDialog extends React.Component { + static propTypes = { + show: PropTypes.bool.isRequired, + rentalAgreement: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + overtime: _.some(props.rentalAgreement.overtimeRates, 'active'), + overtimeRates: props.rentalAgreement.overtimeRates || [], + note: props.rentalAgreement.note || '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + return true; + }; + + isValid = () => { + return true; + }; + + formSubmitted = () => { + const { onSave, onClose } = this.props; + if (this.isValid()) { + if (this.didChange()) { + const rentalAgreement = { + ...this.props.rentalAgreement, + overtimeRates: this.state.overtimeRates, + note: this.state.note, + }; + + Api.updateRentalAgreement(rentalAgreement).then(() => { + if (onSave) { onSave(); } + }); + } + + onClose(); + } + }; + + overtimeCheckboxChanged = (e) => { + var active = e.target.checked; + + var overtimeRates = _.map(this.state.overtimeRates, rate => ({ ...rate, active: active })); + + this.setState({ overtimeRates: overtimeRates }); + }; + + render() { + const maxNoteLength = Constant.MAX_LENGTH_RENTAL_AGREEMENT_NOTE; + const rates = _.orderBy(this.state.overtimeRates, ['rate']); + + return ( + + + + + Overtime Rates +
+ + { + _.map(rates, rate => rate.comment).join(', ') + } + +
+ + + + Notes/Special Instructions + +

Maximum { maxNoteLength } characters.

+
+ +
+
+
+ ); + } +} + +export default RentalAgreementOvertimeNotesDialog; diff --git a/client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx b/client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx new file mode 100644 index 000000000..fbc8bc9c4 --- /dev/null +++ b/client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx @@ -0,0 +1,150 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Row, Col } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Api from '../../api'; + +import DateControl from '../../components/DateControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isValidDate } from '../../utils/date'; +import { isBlank, notBlank } from '../../utils/string'; + + +class RentalAgreementsEditDialog extends React.Component { + static propTypes = { + rentalAgreement: PropTypes.object.isRequired, + show: PropTypes.bool, + owner: PropTypes.object, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + estimateStartWork: props.rentalAgreement.estimateStartWork || '', + estimateHours: props.rentalAgreement.estimateHours || 0, + datedOn: props.rentalAgreement.datedOn || '', + agreementCity: props.rentalAgreement.agreementCity || '', + + estimateStartWorkError: '', + estimateHoursError: '', + datedOnError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.estimateStartWork !== this.props.rentalAgreement.estimateStartWork) { return true; } + if (this.state.estimateHours !== this.props.rentalAgreement.estimateHours) { return true; } + if (this.state.datedOn !== this.props.rentalAgreement.datedOn) { return true; } + if (this.state.note !== this.props.rentalAgreement.note) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + estimateStartWorkError: '', + estimateHoursError: '', + datedOnError: '', + }); + + var valid = true; + + if (notBlank(this.state.estimateStartWork) && !isValidDate(this.state.estimateStartWork)) { + this.setState({ estimateStartWorkError: 'Date not valid' }); + valid = false; + } + + if (notBlank(this.state.datedOn) && !isValidDate(this.state.datedOn)) { + this.setState({ datedOnError: 'Date not valid' }); + valid = false; + } + + if (isBlank(this.state.estimateHours)) { + this.setState({ estimateHoursError: 'Estimated hours are required' }); + valid = false; + } else if (this.state.estimateHours < 1) { + this.setState({ estimateHoursError: 'Estimated hours not valid' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const rentalAgreement = { + ...this.props.rentalAgreement, + estimateStartWork: this.state.estimateStartWork, + estimateHours: this.state.estimateHours, + datedOn: this.state.datedOn, + agreementCity: this.state.agreementCity, + }; + + Api.updateRentalAgreement(rentalAgreement).then(() => { + if (this.props.onSave) { this.props.onSave(); } + }); + } + + this.props.onClose(); + } + }; + + render() { + // Read-only if the user cannot edit the rental agreement + var isReadOnly = !this.props.rentalAgreement.canEdit && this.props.rentalAgreement.id !== 0; + + return ( + + + + + Estimated Commencement + + { this.state.estimateStartWorkError } + + + + + Estimated Period Hours * + + { this.state.estimateHoursError } + + + + + + + Dated On + + { this.state.datedOnError } + + + + + Dated At + + + + + + ); + } +} + +export default RentalAgreementsEditDialog; diff --git a/client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx b/client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx new file mode 100644 index 000000000..b7304b936 --- /dev/null +++ b/client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx @@ -0,0 +1,210 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../../api'; + +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; +import { NON_STANDARD_CONDITION } from '../../constants'; + + +class RentalConditionsEditDialog extends React.Component { + static propTypes = { + show: PropTypes.bool.isRequired, + rentalAgreementId: PropTypes.number.isRequired, + rentalCondition: PropTypes.object.isRequired, + rentalConditions: PropTypes.object.isRequired, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isNew: props.rentalCondition.id === 0, + + forms: [{ + conditionName: props.rentalCondition.conditionName || '', + comment: props.rentalCondition.comment || '', + + conditionNameError: '', + commentError: '', + }], + concurrencyControlNumber: props.rentalCondition.concurrencyControlNumber || 0, + }; + } + + componentDidMount() { + Api.getRentalConditions(); + } + + updateState = (value) => { + let property = Object.keys(value)[0]; + let stateValue = _.values(value)[0]; + let number = property.match(/\d+/g)[0]; + let stateName = property.match(/[a-zA-Z]+/g)[0]; + let state = { [stateName]: stateValue }; + const updatedForms = this.state.forms.slice(); + updatedForms.splice(number, 1, { ...updatedForms[number], ...state}); + this.setState({ forms: updatedForms }); + }; + + didChange = () => { + return true; + }; + + isValid = () => { + const forms = this.state.forms.slice(); + + forms.forEach((form, i) => { + let state = { + ...form, + conditionNameError: '', + commentError: '', + }; + forms[i] = state; + }); + + let valid = true; + + forms.forEach((form, i) => { + if (form.conditionName === NON_STANDARD_CONDITION && isBlank(form.comment)) { + forms[i] = { ...form, commentError: 'Comment is required for non-standard conditions.' }; + valid = false; + } + + if (isBlank(form.conditionName)) { + forms[i] = { ...form, conditionNameError: 'Rental condition is required' }; + valid = false; + } + }); + + this.setState({ forms }); + + return valid; + }; + + formSubmitted = () => { + const { rentalAgreementId, onSave, onClose } = this.props; + + if (this.isValid()) { + if (this.didChange()) { + const forms = this.state.forms; + const conditions = forms.map((form) => { + return { + id: this.props.rentalCondition.id || 0, + rentalAgreement: { id: rentalAgreementId }, + conditionName: form.conditionName, + comment: form.conditionName === NON_STANDARD_CONDITION ? form.comment : '', + concurrencyControlNumber: this.state.concurrencyControlNumber, + }; + }); + + (this.state.isNew ? Api.addRentalConditions(rentalAgreementId, conditions) : Api.updateRentalCondition(_.first(conditions))).then(() => { + if (onSave) { onSave(); } + }); + } + onClose(); + } + }; + + addInput = () => { + if (this.state.forms.length < 10) { + const forms = this.state.forms.slice(); + forms.push({ + conditionName: '', + comment: '', + conditionNameError: '', + commentError: '', + }); + + this.setState({ forms }); + } + }; + + removeInput = () => { + if (this.state.forms.length > 1) { + const forms = this.state.forms.slice(); + forms.pop(); + this.setState({ forms }); + } + }; + + render() { + // Read-only if the user cannot edit the rental agreement + var isReadOnly = !this.props.rentalCondition.canEdit && this.props.rentalCondition.id !== 0; + var conditions = _.map([ ...this.props.rentalConditions.data, { description: NON_STANDARD_CONDITION } ], 'description'); + + return ( + +
+ { this.state.forms.map((form, i) => ( +
+
+ + Conditions * + {/*TODO - use lookup list*/} + + { form.conditionNameError } + +
+ { form.conditionName === NON_STANDARD_CONDITION && ( +
+ + Comment * + + { form.commentError } + +
+ )} +
+ ))} +
+
+ { this.state.isNew && this.state.forms.length > 1 && ( + + )} + { this.state.isNew && this.state.forms.length < 10 && ( + + )} +
+
+ ); + } +} + + +function mapStateToProps(state) { + return { + rentalConditions: state.lookups.rentalConditions, + }; +} + +export default connect(mapStateToProps)(RentalConditionsEditDialog); diff --git a/client2/src/js/views/dialogs/RentalRatesEditDialog.jsx b/client2/src/js/views/dialogs/RentalRatesEditDialog.jsx new file mode 100644 index 000000000..77b8ecd21 --- /dev/null +++ b/client2/src/js/views/dialogs/RentalRatesEditDialog.jsx @@ -0,0 +1,258 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { Row, Col } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + +const ratePeriods = [ + Constant.RENTAL_RATE_PERIOD_HOURLY, + Constant.RENTAL_RATE_PERIOD_DAILY, + Constant.RENTAL_RATE_PERIOD_WEEKLY, + Constant.RENTAL_RATE_PERIOD_MONTHLY, + Constant.RENTAL_RATE_PERIOD_NEGOTIATED, +]; + +class RentalRatesEditDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + rentalRate: PropTypes.object.isRequired, + rentalAgreement: PropTypes.object, + provincialRateTypes: PropTypes.array, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + const ratePeriod = props.rentalRate.id === 0 ? + props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY : + props.rentalRate.ratePeriod; + + this.state = { + isNew: props.rentalRate.id === 0, + + forms: [{ + isIncludedInTotal: props.rentalRate.isIncludedInTotal || false, + rateType: {}, + rate: props.rentalRate.rate || 0.0, + ratePeriod: ratePeriod, + uiRatePeriod: props.rentalRate.set ? Constant.RENTAL_RATE_PERIOD_SET : ratePeriod, + set: props.rentalRate.set || false, + comment: props.rentalRate.comment || '', + + componentNameError: '', + rateError: '', + commentError: '', + }], + concurrencyControlNumber: props.rentalRate.concurrencyControlNumber || 0, + }; + } + + updateState = (value) => { + let property = Object.keys(value)[0]; + let stateValue = _.values(value)[0]; + let number = property.match(/\d+/g)[0]; + let stateName = property.match(/[a-zA-Z]+/g)[0]; + let state = { [stateName]: stateValue }; + const updatedForms = this.state.forms.slice(); + updatedForms.splice(number, 1, { ...updatedForms[number], ...state}); + this.setState({ forms: updatedForms }); + }; + + updateUiRatePeriod = (value, index) => { + const uiRatePeriod = _.values(value)[0]; + const updatedForms = this.state.forms.slice(); + const state = { + uiRatePeriod: uiRatePeriod, + set: uiRatePeriod === Constant.RENTAL_RATE_PERIOD_SET, + ratePeriod: uiRatePeriod === Constant.RENTAL_RATE_PERIOD_SET ? this.props.rentalAgreement.ratePeriod : uiRatePeriod, + }; + updatedForms.splice(index, 1, { ...updatedForms[index], ...state}); + this.setState({ forms: updatedForms }); + }; + + didChange = () => { + return true; + }; + + isValid = () => { + const forms = this.state.forms.slice(); + + forms.forEach((form, i) => { + let state = { + ...form, + rateError: '', + commentError: '', + }; + forms[i] = state; + }); + + let valid = true; + + forms.forEach((form, i) => { + if (isBlank(form.comment)) { + forms[i] = { ...forms[i], commentError: 'Comment is required.' }; + valid = false; + } + + if (isBlank(form.rate) ) { + forms[i] = { ...forms[i], rateError: 'Pay rate is required' }; + valid = false; + } else if (form.rate < 0) { + forms[i] = { ...forms[i], rateError: 'Pay rate not valid' }; + valid = false; + } + }); + + this.setState({ forms }); + + return valid; + }; + + formSubmitted = () => { + const { rentalAgreement, onSave, onClose } = this.props; + + if (this.isValid()) { + if (this.didChange()) { + const forms = this.state.forms; + const rates = forms.map((form) => { + return { + id: this.props.rentalRate.id || 0, + rentalAgreement: { id: this.props.rentalRate.rentalAgreement.id }, + rate: form.rate, + ratePeriod: form.ratePeriod, + comment: form.comment, + set: form.set, + isIncludedInTotal: this.props.rentalRate.isIncludedInTotal, + concurrencyControlNumber: this.state.concurrencyControlNumber, + }; + }); + + (this.state.isNew ? Api.addRentalRates(rentalAgreement.id, rates) : Api.updateRentalRate(_.first(rates))).then(() => { + if (onSave) { onSave(); } + }); + } + + onClose(); + } + }; + + addInput = () => { + if (this.state.forms.length < 10) { + const forms = this.state.forms.slice(); + + const ratePeriod = this.props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY; + + forms.push({ + isIncludedInTotal: this.props.rentalRate.isIncludedInTotal || false, + rate: this.props.rentalRate.rate || 0.0, + ratePeriod: ratePeriod, + uiRatePeriod: this.props.rentalRate.set ? Constant.RENTAL_RATE_PERIOD_SET : ratePeriod, + set: this.props.rentalRate.set || false, + comment: this.props.rentalRate.comment || '', + + rateError: '', + commentError: '', + }); + + this.setState({ forms }); + } + }; + + removeInput = () => { + if (this.state.forms.length > 1) { + const forms = this.state.forms.slice(); + forms.pop(); + this.setState({ forms }); + } + }; + + renderForm(form, i) { + // Read-only if the user cannot edit the rental agreement + const isReadOnly = !this.props.rentalRate.canEdit && this.props.rentalRate.id !== 0; + + const uiRatePeriods = _.concat(ratePeriods, Constant.RENTAL_RATE_PERIOD_SET); + + const ratePeriodElement = this.props.rentalRate.isIncludedInTotal ? + <> + Period +
{ form.uiRatePeriod }
+ + : + + Period * + this.updateUiRatePeriod(state, i) } + items={ uiRatePeriods } /> + ; + + return ( +
+ + + + Rate * + + { form.rateError } + + + + { ratePeriodElement } + + + + Comment * + + { form.commentError } + + + +
+ ); + } + + render() { + var status = this.props.rentalRate.isIncludedInTotal ? 'Included' : 'As-Needed'; + + return ( + +
+ { this.state.forms.map((form, i) => this.renderForm(form, i))} +
+
+ { this.state.isNew && this.state.forms.length > 1 && ( + + )} + { this.state.isNew && this.state.forms.length < 10 && ( + + )} +
+
+ ); + } +} + +export default RentalRatesEditDialog; diff --git a/client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx b/client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx new file mode 100644 index 000000000..7b10bff13 --- /dev/null +++ b/client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx @@ -0,0 +1,336 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { FormGroup, HelpBlock, ControlLabel, Alert } from 'react-bootstrap'; +import _ from 'lodash'; +import Moment from 'moment'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; + +import DateControl from '../../components/DateControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isValidDate, today } from '../../utils/date'; +import { isBlank } from '../../utils/string'; + + +class RentalRequestsAddDialog extends React.Component { + static propTypes = { + currentUser: PropTypes.object, + localAreas: PropTypes.object, + districtEquipmentTypes: PropTypes.object, + projects: PropTypes.object, + project: PropTypes.object, + onRentalAdded: PropTypes.func, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + viewOnly: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + savingError: '', + projectId: props.project ? props.project.id : 0, + localAreaId: 0, + equipmentTypeId: 0, + count: 1, + expectedHours: '', + expectedStartDate: today(), + expectedEndDate: '', + rentalRequestAttachments: [], + + projectError: '', + localAreaError: '', + equipmentTypeError: '', + countError: '', + expectedHoursError: '', + expectedStartDateError: '', + expectedEndDateError: '', + }; + } + + componentDidMount() { + Api.getDistrictEquipmentTypes(); + if (this.canChangeProject()) { + Api.getProjectsCurrentFiscal(); + } + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateEquipmentTypeState = (state) => { + var selectedEquipment =_.find(this.props.districtEquipmentTypes.data, { id: state.equipmentTypeId }); + var isDumpTruck = selectedEquipment.equipmentType.isDumpTruck; + var expectedHours = isDumpTruck ? 600 : 300; + this.setState({ ...state, expectedHours }); + }; + + didChange = () => { + if (this.state.projectId !== 0) { return true; } + if (this.state.localAreaId !== 0) { return true; } + if (this.state.equipmentTypeId !== 0) { return true; } + if (this.state.count !== 1) { return true; } + if (this.state.expectedHours !== '') { return true; } + if (this.state.expectedStartDate !== today()) { return true; } + if (this.state.expectedEndDate !== '') { return true; } + if (this.state.rentalRequestAttachments !== '') { return true; } + + return false; + }; + + isValid = () => { + // Clear out any previous errors + var valid = true; + this.setState({ + projectError: '', + localAreaError: '', + equipmentTypeError: '', + countError: '', + expectedHoursError: '', + expectedStartDateError: '', + expectedEndDateError: '', + }); + + if (this.state.projectId === 0 && !this.props.viewOnly) { + this.setState({ projectError: 'Project is required' }); + valid = false; + } + + if (this.state.localAreaId === 0) { + this.setState({ localAreaError: 'Local area is required' }); + valid = false; + } + + if (this.state.equipmentTypeId === 0) { + this.setState({ equipmentTypeError: 'Equipment type is required' }); + valid = false; + } + + // all fields for view-only requests have now been validated + if (this.props.viewOnly) { + return valid; + } + + if (isBlank(this.state.count)) { + this.setState({ countError: 'Equipment quantity is required' }); + valid = false; + } else if (this.state.count < 1) { + this.setState({ countError: 'Equipment quantity not valid' }); + valid = false; + } + + if (isBlank(this.state.expectedHours)) { + this.setState({ expectedHoursError: 'Estimated hours are required' }); + valid = false; + } else if (this.state.expectedHours < 1) { + this.setState({ expectedHoursError: 'Estimated hours not valid' }); + valid = false; + } + + if (isBlank(this.state.expectedStartDate)) { + this.setState({ expectedStartDateError: 'Start date is required' }); + valid = false; + } else if (!isValidDate(this.state.expectedStartDate)) { + this.setState({ expectedStartDateError: 'Date not valid' }); + valid = false; + } + + if (Moment(this.state.expectedEndDate).isBefore(this.state.expectedStartDate)) { + this.setState({ expectedEndDateError: 'End date must be later than the start date' }); + valid = false; + } + + return valid; + }; + + onLocalAreaSelected = (localArea) => { + // clear the selected equipment type if it's not included in the types for the new local area + var districtEquipmentTypes = this.getFilteredEquipmentTypes(localArea.id); + if (_.filter(districtEquipmentTypes, type => type.id === this.state.equipmentTypeId).length === 0) { + this.setState({ equipmentTypeId: 0 }); + } + }; + + onProjectSelected = () => { + // TODO Restrict the available local areas to a project service area + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({isSaving: true}); + + const { rentalRequestAttachments } = this.state; + + var request = { + project: { id: this.state.projectId }, + localArea: { id: this.state.localAreaId }, + districtEquipmentType: { id: this.state.equipmentTypeId }, + equipmentCount: this.state.count, + status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, + expectedHours: this.state.expectedHours, + expectedStartDate: this.state.expectedStartDate, + expectedEndDate: this.state.expectedEndDate, + rentalRequestAttachments: [{ + id: 0, + attachment: rentalRequestAttachments.length === 0 ? undefined : rentalRequestAttachments, + }], + }; + + Api.addRentalRequest(request, this.props.viewOnly).then((response) => { + this.setState({ isSaving: false }); + + this.props.onRentalAdded(response); + this.props.onClose(); + }).catch((error) => { + this.setState({ isSaving: false }); + if (error.status === 400 && error.errorCode === 'HETS-28') { + this.setState({ savingError: error.errorDescription }); + } else { + throw error; + } + }); + } + } + }; + + getFilteredEquipmentTypes = (localAreaId) => { + return _.chain(this.props.districtEquipmentTypes.data) + .filter(type => type.equipmentCount > 0 && !localAreaId || _.filter(type.localAreas, localArea => localArea.id === localAreaId && localArea.equipmentCount > 0).length > 0) + .sortBy('districtEquipmentName') + .value(); + }; + + canChangeProject = () => { + return !this.props.project && !this.props.viewOnly; + }; + + renderForm = () => { + const { project } = this.props; + + // Constrain the local area drop downs to those in the District of the current logged in user + var localAreas = _.chain(this.props.localAreas) + .sortBy('name') + .value(); + + var districtEquipmentTypes = this.getFilteredEquipmentTypes(this.state.localAreaId); + + var projects = _.sortBy(this.props.projects.data, 'name'); + + const hasPickedLocalArea = Boolean(this.state.localAreaId); + + return ( +
+ + Project {!project && !this.props.viewOnly && (*)} + { this.canChangeProject() ? ( + + ) :
{project ? project.name : 'Request - View Only' }
+ } + { this.state.projectError } +
+ + Local Area * + + { this.state.localAreaError } + + + Equipment Type * + + { this.state.equipmentTypeError } + + { !this.props.viewOnly && ( + + Quantity * + + { this.state.countError } + + )} + { !this.props.viewOnly && ( + + Attachment(s) + + + )} + { !this.props.viewOnly && ( + + Expected Hours * + + { this.state.expectedHoursError } + + )} + { !this.props.viewOnly && ( + + Start Date * + + { this.state.expectedStartDateError } + + )} + { !this.props.viewOnly && ( + + End Date + + { this.state.expectedEndDateError } + + )} + { this.state.savingError && + { this.state.savingError } + } +
+ ); + }; + + render() { + const { isSaving } = this.state; + const { show, onClose } = this.props; + + return ( + + { this.renderForm()} + + ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + localAreas: state.lookups.localAreas, + districtEquipmentTypes: state.lookups.districtEquipmentTypes, + projects: state.lookups.projectsCurrentFiscal, + }; +} + +export default connect(mapStateToProps)(RentalRequestsAddDialog); diff --git a/client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx b/client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx new file mode 100644 index 000000000..89db7d75a --- /dev/null +++ b/client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx @@ -0,0 +1,175 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { FormGroup, HelpBlock, ControlLabel, FormControl } from 'react-bootstrap'; +import Moment from 'moment'; + +import * as Api from '../../api'; +import * as Log from '../../history'; + +import DateControl from '../../components/DateControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isValidDate } from '../../utils/date'; +import { isBlank } from '../../utils/string'; + + +class RentalRequestsEditDialog extends React.Component { + static propTypes = { + rentalRequest: PropTypes.object.isRequired, + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + const rentalRequest = props.rentalRequest; + + this.state = { + equipmentCount: rentalRequest.equipmentCount || 0, + expectedHours: rentalRequest.expectedHours || 0, + expectedStartDate: rentalRequest.expectedStartDate || '', + expectedEndDate: rentalRequest.expectedEndDate || '', + rentalRequestAttachments: rentalRequest.rentalRequestAttachments && rentalRequest.rentalRequestAttachments[0] ? rentalRequest.rentalRequestAttachments[0].attachment : '', + rentalRequestAttachmentId: rentalRequest.rentalRequestAttachments && rentalRequest.rentalRequestAttachments[0] ? rentalRequest.rentalRequestAttachments[0].id : undefined, + + equipmentCountError: '', + expectedHoursError: '', + expectedStartDateError: '', + expectedEndDateError: '', + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.equipmentCount !== this.props.rentalRequest.equipmentCount) { return true; } + if (this.state.expectedHours !== this.props.rentalRequest.expectedHours) { return true; } + if (this.state.expectedStartDate !== this.props.rentalRequest.expectedStartDate) { return true; } + if (this.state.expectedEndDate !== this.props.rentalRequest.expectedEndDate) { return true; } + if (this.state.rentalRequestAttachments !== this.props.rentalRequest.rentalRequestAttachments) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + equipmentCountError: '', + expectedHoursError: '', + expectedStartDateError: '', + expectedEndDateError: '', + }); + + var valid = true; + + if (isBlank(this.state.equipmentCount)) { + this.setState({ equipmentCountError: 'Quantity is required' }); + valid = false; + } else if (this.state.equipmentCount < 1) { + this.setState({ equipmentCountError: 'Quantity not valid' }); + valid = false; + } else if (this.state.equipmentCount < this.props.rentalRequest.yesCount) { + this.setState({ equipmentCountError: 'Quantity can not be less than number of equipment already hired' }); + valid = false; + } + + if (isBlank(this.state.expectedHours)) { + this.setState({ expectedHoursError: 'Estimated hours are required' }); + valid = false; + } else if (this.state.expectedHours < 1) { + this.setState({ expectedHoursError: 'Estimated hours not valid' }); + valid = false; + } + + if (isBlank(this.state.expectedStartDate)) { + this.setState({ expectedStartDateError: 'Start date is required' }); + valid = false; + } else if (!isValidDate(this.state.expectedStartDate)) { + this.setState({ expectedStartDateError: 'Date not valid' }); + valid = false; + } + + if (Moment(this.state.expectedEndDate).isBefore(this.state.expectedStartDate)) { + this.setState({ expectedEndDateError: 'End date must be later than the start date' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + const rentalRequest = { + ...this.props.rentalRequest, + equipmentCount: this.state.equipmentCount, + expectedHours: this.state.expectedHours, + expectedStartDate: this.state.expectedStartDate, + expectedEndDate: this.state.expectedEndDate, + rentalRequestAttachments: [{ + id: this.state.rentalRequestAttachmentId, + attachment: this.state.rentalRequestAttachments, + }], + }; + + Api.updateRentalRequest(rentalRequest).then(() => { + Log.rentalRequestModified(this.props.rentalRequest); + if (this.props.onSave) { this.props.onSave(); } + }); + } + + this.props.onClose(); + } + }; + + render() { + // Read-only if the user cannot edit the rental agreement + var isReadOnly = !this.props.rentalRequest.canEdit && this.props.rentalRequest.id !== 0; + // var numRequestAttachments = Object.keys(this.props.rentalRequest.rentalRequestAttachments || []).length; + // var requestAttachments = (this.props.rentalRequest.rentalRequestAttachments || []).join(', '); + + return ( + + + Equipment Type + { this.props.rentalRequest.equipmentTypeName } + + + Attachment(s) + + + + Quantity * + + { this.state.equipmentCountError } + + + Expected Hours * + + { this.state.expectedHoursError } + + + Start Date * + + { this.state.expectedStartDateError } + + + End Date * + + { this.state.expectedEndDateError } + + + ); + } +} + +export default RentalRequestsEditDialog; diff --git a/client2/src/js/views/dialogs/SeniorityEditDialog.jsx b/client2/src/js/views/dialogs/SeniorityEditDialog.jsx new file mode 100644 index 000000000..13df4dfe8 --- /dev/null +++ b/client2/src/js/views/dialogs/SeniorityEditDialog.jsx @@ -0,0 +1,230 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { Grid, Row, Col } from 'react-bootstrap'; +import { FormControl, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; + +import * as Api from '../../api'; +import * as Log from '../../history'; + +import FormDialog from '../../components/FormDialog.jsx'; +import DateControl from '../../components/DateControl.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { daysFromToday, isValidDate, toZuluTime, today } from '../../utils/date'; +import { isBlank, formatHours } from '../../utils/string'; + +class SeniorityEditDialog extends React.Component { + static propTypes = { + equipment: PropTypes.object, + + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + isNew: props.equipment.id === 0, + + hoursYtd: props.equipment.hoursYtd, + serviceHoursLastYear: props.equipment.serviceHoursLastYear, + serviceHoursTwoYearsAgo: props.equipment.serviceHoursTwoYearsAgo, + serviceHoursThreeYearsAgo: props.equipment.serviceHoursThreeYearsAgo, + approvedDate: props.equipment.approvedDate || today(), + yearsRegistered: props.equipment.yearsOfService, + isSeniorityOverridden: props.equipment.isSeniorityOverridden, + seniorityOverrideReason: props.equipment.seniorityOverrideReason, + + approvedDateError: null, + serviceHoursLastYearError: null, + serviceHoursTwoYearsAgoError: null, + serviceHoursThreeYearsAgoError: null, + yearsRegisteredError: null, + overrideReasonError: null, + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.serviceHoursLastYear !== this.props.equipment.serviceHoursLastYear) { return true; } + if (this.state.serviceHoursTwoYearsAgo !== this.props.equipment.serviceHoursTwoYearsAgo) { return true; } + if (this.state.serviceHoursThreeYearsAgo !== this.props.equipment.serviceHoursThreeYearsAgo) { return true; } + if (this.state.approvedDate !== this.props.equipment.approvedDate) { return true; } + if (this.state.yearsRegistered !== this.props.equipment.yearsRegistered) { return true; } + if (this.state.isSeniorityOverridden !== this.props.equipment.isSeniorityOverridden) { return true; } + if (this.state.seniorityOverrideReason !== this.props.equipment.seniorityOverrideReason) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + approvedDateError: null, + serviceHoursLastYearError: null, + serviceHoursTwoYearsAgoError: null, + serviceHoursThreeYearsAgoError: null, + yearsRegisteredError: null, + overrideReasonError: null, + }); + + var valid = true; + // Validate service hours + if (isBlank(this.state.serviceHoursLastYear)) { + this.setState({ serviceHoursLastYearError: 'Service hours are required' }); + valid = false; + } + + if (isBlank(this.state.serviceHoursTwoYearsAgo)) { + this.setState({ serviceHoursTwoYearsAgoError: 'Service hours are required' }); + valid = false; + } + + if (isBlank(this.state.serviceHoursThreeYearsAgo)) { + this.setState({ serviceHoursThreeYearsAgoError: 'Service hours are required' }); + valid = false; + } + + // Validate registered date + if (isBlank(this.state.approvedDate)) { + this.setState({ approvedDateError: 'Registered date is required' }); + valid = false; + } else if (!isValidDate(this.state.approvedDate)) { + this.setState({ approvedDateError: 'Registered date not valid' }); + valid = false; + } else if (daysFromToday(this.state.approvedDate) > 0) { + this.setState({ approvedDateError: 'Registration date must be today or earlier' }); + valid = false; + } + + if (this.didChange() && (isBlank(this.state.seniorityOverrideReason) || (this.state.seniorityOverrideReason === this.props.equipment.seniorityOverrideReason))) { + this.setState({ overrideReasonError: 'A new reason must be provided each time seniority is manually overriden' }); + valid = false; + } + + if (this.state.yearsRegistered < 0) { + this.setState({ yearsRegisteredError: 'Years registered must be an integer greater than 0.' }); + valid = false; + } + + return valid; + }; + + seniorityOverrriden = () => { + this.setState({ isSeniorityOverridden: true }); + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const equipment = { + ...this.props.equipment, + serviceHoursLastYear: (this.state.serviceHoursLastYear || 0).toFixed(2), + serviceHoursTwoYearsAgo: (this.state.serviceHoursTwoYearsAgo || 0).toFixed(2), + serviceHoursThreeYearsAgo: (this.state.serviceHoursThreeYearsAgo || 0).toFixed(2), + approvedDate: toZuluTime(this.state.approvedDate), + yearsOfService: this.state.yearsRegistered, + isSeniorityOverridden: this.state.isSeniorityOverridden, + seniorityOverrideReason: this.state.seniorityOverrideReason, + }; + + const promise = Api.updateEquipment(equipment); + + promise.then(() => { + Log.equipmentSeniorityModified(this.props.equipment); + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + return ( + + + + + + Hours YTD + { formatHours(this.state.hoursYtd) } + + + + + + + Hours { this.props.equipment.yearMinus1 } * + + { this.state.serviceHoursLastYearError } + + + + + + + Hours { this.props.equipment.yearMinus2 } * + + { this.state.serviceHoursTwoYearsAgoError } + + + + + + + Hours { this.props.equipment.yearMinus3 } * + + { this.state.serviceHoursThreeYearsAgoError } + + + + + + + Registered Date * + + { this.state.approvedDateError } + + + + + + + Years Registered + + { this.state.yearsRegisteredError } + + + + + + + Override Reason * + + { this.state.overrideReasonError } + + + + + + ); + } +} + +export default SeniorityEditDialog; diff --git a/client2/src/js/views/dialogs/TimeEntryDialog.jsx b/client2/src/js/views/dialogs/TimeEntryDialog.jsx new file mode 100644 index 000000000..b073338ea --- /dev/null +++ b/client2/src/js/views/dialogs/TimeEntryDialog.jsx @@ -0,0 +1,555 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Grid, Row, Col, FormGroup, ControlLabel, HelpBlock, Button, Glyphicon } from 'react-bootstrap'; +import _ from 'lodash'; +import Moment from 'moment'; + +import * as Api from '../../api'; + +import FormDialog from '../../components/FormDialog.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; +import DateControl from '../../components/DateControl.jsx'; +import DeleteButton from '../../components/DeleteButton.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; +import Spinner from '../../components/Spinner.jsx'; + +import { isBlank, formatHours } from '../../utils/string'; +import { formatDateTime } from '../../utils/date'; + +class TimeEntryDialog extends React.Component { + static propTypes = { + onClose: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired, + multipleEntryAllowed: PropTypes.bool.isRequired, + rentalAgreementId: PropTypes.number, + rentalAgreementTimeRecords: PropTypes.object, + project: PropTypes.object, + projectId: PropTypes.number, + projects: PropTypes.object.isRequired, + equipment: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + isSaving: false, + loaded: false, + rentalAgreementId: props.rentalAgreementId, + equipmentId: null, + projectId: props.projectId || null, + projectFiscalYearStartDate: props.project ? props.project.fiscalYearStartDate : null, + equipmentIdError: '', + projectIdError: '', + selectingAgreement: props.rentalAgreementId ? false : true, + showAllTimeRecords: false, + numberOfInputs: 1, + timeEntry: { + 1: { + hours: '', + date: '', + errorHours: '', + errorDate: '', + }, + }, + }; + } + + resetStateToSelectAgreement = (clearSelections) => { + this.setState({ + rentalAgreementId: null, + equipmentId: clearSelections ? null : this.state.equipmentId, + projectId: clearSelections ? null : this.state.projectId, + projectFiscalYearStartDate: clearSelections ? null : this.state.projectFiscalYearStartDate, + selectingAgreement: true, + showAllTimeRecords: false, + numberOfInputs: 1, + timeEntry: { + 1: { + hours: '', + date: '', + errorHours: '', + errorDate: '', + }, + }, + }); + }; + + componentDidMount() { + if (this.state.selectingAgreement) { + Api.getProjectsCurrentFiscal(); + Api.getEquipmentLite(); + } else { + this.setState({ loaded: false }); + Promise.all([ + !this.props.project ? this.fetchProject(this.props.projectId) : null, + this.fetchTimeRecords(), + ]).then(() => { + this.setState({ loaded: true }); + }); + } + } + + fetchTimeRecords = () => { + return Api.getRentalAgreementTimeRecords(this.state.rentalAgreementId); + }; + + fetchProject = (projectId) => { + return Api.getProject(projectId).then((project) => { + this.setState({projectFiscalYearStartDate: project.fiscalYearStartDate}); + }); + }; + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + validateSelectAgreement = () => { + var valid = true; + + this.setState({ equipmentIdError: '', projectIdError: '' }); + + if (isBlank(this.state.equipmentId)) { + this.setState({ equipmentIdError: 'Equipment ID is required' }); + valid = false; + } + + if (isBlank(this.state.projectId)) { + this.setState({ projectIdError: 'Project is required' }); + valid = false; + } + + return valid; + }; + + selectAgreementFormSubmitted = () => { + if (this.validateSelectAgreement()) { + this.setState({ isSaving: true }); + + Api.getLatestRentalAgreement(this.state.equipmentId, this.state.projectId).then((agreement) => { + this.setState({ loaded: false, rentalAgreementId: agreement.id }); + return Promise.all([ this.fetchProject(this.state.projectId), this.fetchTimeRecords() ]).then(() => { + this.setState({ isSaving: false, selectingAgreement: false, loaded: true }); + }); + }).catch((error) => { + this.setState({ isSaving: false }); + if (error.status === 400 && error.errorCode === 'HETS-35') { + this.setState({ projectIdError: error.errorDescription }); + } else { + throw error; + } + }); + } + }; + + updateTimeEntryState = (value) => { + let property = Object.keys(value)[0]; + let stateValue = _.values(value)[0]; + let number = property.match(/\d+/g)[0]; + let stateName = property.match(/[a-zA-Z]+/g)[0]; + let state = { [stateName]: stateValue }; + let updatedState = { ...this.state.timeEntry, [number]: { ...this.state.timeEntry[number], ...state } }; + this.setState({ timeEntry: updatedState }); + }; + + didChange = () => { + // todo + return true; + }; + + isValid = () => { + let timeEntry = { ...this.state.timeEntry }; + + let timeEntryResetObj = timeEntry; + Object.keys(timeEntry).forEach((key) => { + let state = { ...timeEntry[key], errorHours: '', errorDate: '' }; + timeEntryResetObj[key] = state; + }); + + this.setState({ timeEntry: timeEntryResetObj }); + let valid = true; + + let timeEntryErrorsObj = timeEntry; + Object.keys(timeEntry).forEach((key) => { + if (isBlank(timeEntry[key].hours)) { + let state = { ...timeEntry[key], errorHours: 'Hours are required' }; + timeEntryErrorsObj[key] = state; + valid = false; + } + if (isBlank(timeEntry[key].date)) { + let state = { ...timeEntry[key], errorDate: 'Date is required' }; + timeEntryErrorsObj[key] = state; + valid = false; + } else { + var date = Moment.utc(timeEntry[key].date); + if (this.isBeforeFiscalStartDate(date)) { + let state = { ...timeEntry[key], errorDate: 'Date must be in the current fiscal year' }; + timeEntryErrorsObj[key] = state; + valid = false; + } else if (this.isInFuture(date)) { + let state = { ...timeEntry[key], errorDate: 'Date must not be in the future' }; + timeEntryErrorsObj[key] = state; + valid = false; + } else if (!this.isSaturdayOrMarch31st(date)) { + let state = { ...timeEntry[key], errorDate: 'Date must be a Saturday or March 31st' }; + timeEntryErrorsObj[key] = state; + valid = false; + } + Object.keys(timeEntry).forEach((otherKey) => { + if (key !== otherKey && timeEntry[key].date === timeEntry[otherKey].date) { + let state = { ...timeEntry[key], errorDate: 'Time record for this date already exists' }; + timeEntryErrorsObj[key] = state; + valid = false; + } + }); + Object.keys(this.props.rentalAgreementTimeRecords.timeRecords).forEach((index) => { + var existingDate = Moment.utc(this.props.rentalAgreementTimeRecords.timeRecords[index].workedDate); + if (date.isSame(existingDate)) { + let state = { ...timeEntry[key], errorDate: 'Time record for this date already exists' }; + timeEntryErrorsObj[key] = state; + valid = false; + } + }); + } + }); + this.setState({ timeEntry: timeEntryErrorsObj }); + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + var timeEntry = { ...this.state.timeEntry }; + Object.keys(timeEntry).forEach((key) => { + timeEntry[key].hours = (timeEntry[key].hours || 0).toFixed(2); + }); + + const promise = Api.addRentalAgreementTimeRecords(this.state.rentalAgreementId, timeEntry); + + promise.then(() => { + this.setState({ isSaving: false }); + if (this.props.multipleEntryAllowed) { + this.resetStateToSelectAgreement(true); + } else { + this.props.onClose(); + } + }); + } else { + this.props.onClose(); + } + } + }; + + onClose = () => { + if (this.props.multipleEntryAllowed) { + this.resetStateToSelectAgreement(false); + } else { + this.props.onClose(); + } + }; + + onEquipmentSelected = () => { + this.setState({ projectId: null }); + }; + + getFilteredProjects = () => { + const projects = this.props.projects.data; + + if (this.state.equipmentId) { + var equipment = this.props.equipment.data[this.state.equipmentId] || null; + if (equipment) { + return _.intersectionWith(projects, equipment.projectIds, (p, pid) => p.id === pid); + } + } + + return projects; + }; + + addTimeEntryInput = () => { + if (this.state.numberOfInputs < 10) { + let numberOfInputs = Object.keys(this.state.timeEntry).length; + this.setState({ + numberOfInputs: this.state.numberOfInputs + 1, + timeEntry: { + ...this.state.timeEntry, + [numberOfInputs + 1]: { + hours: '', + date: '', + errorHours: '', + errorDate: '', + }, + }, + }); + } + }; + + removeTimeEntryInput = () => { + if (this.state.numberOfInputs > 1) { + let numberOfInputs = Object.keys(this.state.timeEntry).length; + let timeEntry = { ...this.state.timeEntry }; + delete timeEntry[numberOfInputs]; + this.setState({ + numberOfInputs: this.state.numberOfInputs - 1, + timeEntry: timeEntry, + }); + } + }; + + deleteTimeRecord = (timeRecord) => { + Api.deleteTimeRecord(timeRecord.id).then(() => { + Api.getRentalAgreementTimeRecords(this.state.rentalAgreementId); + }); + }; + + showAllTimeRecords = () => { + this.setState({ showAllTimeRecords: !this.state.showAllTimeRecords }); + }; + + getHoursYtdClassName = () => { + var equipment = this.props.rentalAgreementTimeRecords; + + if (equipment.hoursYtd > (0.85 * equipment.maximumHours)) { + return true; + } + + return false; + }; + + isBeforeFiscalStartDate = (date) => { + return date.isBefore(Moment(this.state.projectFiscalYearStartDate)); + } + + isInFuture = (date) => { + // The next Saturday is allowed but not after + return date.isAfter(Moment().day(6)); + } + + isSaturdayOrMarch31st = (date) => { + return date.day() === 6 || date.month() === 2 && date.date() === 31; + } + + isValidDate = (current) => { + if (this.isBeforeFiscalStartDate(current)) { + return false; + } + + if (this.isInFuture(current)) { + return false; + } + + return this.isSaturdayOrMarch31st(current); + }; + + render() { + if (this.state.selectingAgreement) { + return this.renderSelectAgreement(); + } else { + return this.renderEditDialog(); + } + } + + renderSelectAgreement = () => { + var equipment = _.sortBy(this.props.equipment.data, 'equipmentCode'); + var projects = this.getFilteredProjects(); + + return ( + + + + + + Equipment ID * + + { this.state.equipmentIdError } + + + + + Project * + + { this.state.projectIdError } + + + + + + ); + }; + + renderTimeRecordItem = (timeRecord) => { + return ( + + +
{ formatDateTime(timeRecord.workedDate, 'YYYY-MMM-DD') }
+ + +
{ formatHours(timeRecord.hours) }
+ + + this.deleteTimeRecord(timeRecord) }/> + +
+ ); + }; + + renderEditDialog = () => { + const rentalAgreementTimeRecords = this.props.rentalAgreementTimeRecords; + var sortedTimeRecords = _.sortBy(rentalAgreementTimeRecords.timeRecords, 'workedDate').reverse(); + + return ( + + + {(() => { + if (!this.state.loaded) { return
; } + + return ( +
+ + +
Equipment ID
+
{ rentalAgreementTimeRecords.equipmentCode }
+ + +
YTD Hours
+
+ { formatHours(rentalAgreementTimeRecords.hoursYtd) }{ this.getHoursYtdClassName() } +
+ + +
Project
+
{ rentalAgreementTimeRecords.projectName }
+ + +
Project Number
+
{ rentalAgreementTimeRecords.provincialProjectNumber }
+ +
+
+ +
Week Ending
+
Hours
+
+ { (sortedTimeRecords.length === 0) && + +
No time records have been added yet.
+
+ } + + { (sortedTimeRecords.length > 0) && !this.state.showAllTimeRecords ? + + {this.renderTimeRecordItem(sortedTimeRecords[0])} + + : + + +
    + { _.map(sortedTimeRecords, timeRecord => ( +
  • + {this.renderTimeRecordItem(timeRecord)} +
  • + ))} +
+ +
+ } +
+ { (sortedTimeRecords.length > 1) && + + } +
+ ); + })()} +
+ { Object.keys(this.state.timeEntry).map(key => { + return ( + + + + Week Ending + + { this.state.timeEntry[key].errorDate } + + + + + Hours + + { this.state.timeEntry[key].errorHours } + + + + ); + })} + + + { this.state.numberOfInputs < 10 && ( + + )} + { this.state.numberOfInputs > 1 && ( + + )} + + +
+
+ ); + }; +} + +function mapStateToProps(state) { + return { + rentalAgreementTimeRecords: state.models.rentalAgreementTimeRecords, + projects: state.lookups.projectsCurrentFiscal, + equipment: state.lookups.equipment.ts, + }; +} + +export default connect(mapStateToProps)(TimeEntryDialog); diff --git a/client2/src/js/views/dialogs/UserRoleAddDialog.jsx b/client2/src/js/views/dialogs/UserRoleAddDialog.jsx new file mode 100644 index 000000000..f6957d4e6 --- /dev/null +++ b/client2/src/js/views/dialogs/UserRoleAddDialog.jsx @@ -0,0 +1,178 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { Grid, Row, Col } from 'react-bootstrap'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Api from '../../api'; +import * as Constant from '../../constants'; + +import DateControl from '../../components/DateControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import DropdownControl from '../../components/DropdownControl.jsx'; +import Spinner from '../../components/Spinner.jsx'; + +import { isValidDate, toZuluTime } from '../../utils/date'; +import { isBlank, notBlank } from '../../utils/string'; + + +class UserRoleAddDialog extends React.Component { + static propTypes = { + show: PropTypes.bool, + user: PropTypes.object, + roles: PropTypes.object, + currentUser: PropTypes.object, + onSave: PropTypes.func, + onClose: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + isSaving: false, + + roleId: 0, + effectiveDate: '', + expiryDate: '', + + roleIdError: '', + effectiveDateError: '', + expiryDateError: '', + }; + } + + componentDidMount() { + this.setState({ loading: true }); + Api.getRoles().then(() => { + this.setState({ loading: false }); + }); + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + didChange = () => { + if (this.state.roleId !== 0) { return true; } + if (notBlank(this.state.effectiveDate)) { return true; } + if (notBlank(this.state.expiryDate)) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + roleIdError: false, + effectiveDateError: false, + expiryDateError: false, + }); + + var valid = true; + if (!this.state.roleId) { + this.setState({ roleIdError: 'Role is required' }); + valid = false; + } + + if (isBlank(this.state.effectiveDate)) { + this.setState({ effectiveDateError: 'Effective date is required' }); + valid = false; + } else if (!isValidDate(this.state.effectiveDate)) { + this.setState({ effectiveDateError: 'Effective date not valid' }); + valid = false; + } + + if (notBlank(this.state.expiryDate) && !isValidDate(this.state.expiryDate)) { + this.setState({ expiryDateError: 'Expiry date not valid' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const userRole = { + roleId: this.state.roleId, + effectiveDate: toZuluTime(this.state.effectiveDate), + expiryDate: toZuluTime(this.state.expiryDate), + }; + + Api.addUserRole(this.props.user.id, userRole).then(() => { + this.setState({ isSaving: false }); + if (this.props.onSave) { this.props.onSave(); } + this.props.onClose(); + }); + + } else { + this.props.onClose(); + } + } + }; + + render() { + var isAdministrator = _.some(this.props.currentUser.userRoles, { roleName: Constant.ADMINISTRATOR_ROLE }); + + var filteredRoles = isAdministrator ? this.props.roles : _.reject(this.props.roles, { name: Constant.ADMINISTRATOR_ROLE }); + + var roles = _.sortBy(filteredRoles, 'name'); + + return ( + + {(() => { + if (this.state.loading) { return
; } + + return ( + + + + + Role * + + { this.state.roleIdError } + + + + + Effective Date * + + { this.state.effectiveDateError } + + + + + Expiry Date + + { this.state.expiryDateError } + + + + + ); + })()} +
+ ); + } +} + +function mapStateToProps(state) { + return { + currentUser: state.user, + roles: state.lookups.roles, + }; +} + +export default connect(mapStateToProps)(UserRoleAddDialog); diff --git a/client2/src/js/views/dialogs/UsersEditDialog.jsx b/client2/src/js/views/dialogs/UsersEditDialog.jsx new file mode 100644 index 000000000..fc90d7ba7 --- /dev/null +++ b/client2/src/js/views/dialogs/UsersEditDialog.jsx @@ -0,0 +1,227 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { connect } from 'react-redux'; +import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; +import _ from 'lodash'; + +import * as Constant from '../../constants'; +import * as Api from '../../api'; + +import DropdownControl from '../../components/DropdownControl.jsx'; +import FormDialog from '../../components/FormDialog.jsx'; +import FilterDropdown from '../../components/FilterDropdown.jsx'; +import FormInputControl from '../../components/FormInputControl.jsx'; + +import { isBlank } from '../../utils/string'; + + +class UsersEditDialog extends React.Component { + static propTypes = { + user: PropTypes.object.isRequired, + districts: PropTypes.object, + + onSave: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + show: PropTypes.bool, + isNew: PropTypes.bool, + }; + + static defaultProps = { + isNew: false, + }; + + constructor(props) { + super(props); + + var isNew = props.isNew; + + this.state = { + isNew: isNew, + + isSaving: false, + + active: !isNew ? props.user.active === true : false, + givenName: !isNew ? props.user.givenName : '', + surname: !isNew ? props.user.surname : '', + smUserId: !isNew ? props.user.smUserId : '', + email: !isNew ? props.user.email : '', + districtId: !isNew ? props.user.district.id : 0, + agreementCity: !isNew ? props.user.agreementCity : '', + + status: !isNew && props.user.active ? Constant.USER_STATUS_ACTIVE : Constant.USER_STATUS_ARCHIVED, + + givenNameError: false, + surnameError: false, + smUserIdError: false, + emailError: false, + districtIdError: false, + }; + } + + updateState = (state, callback) => { + this.setState(state, callback); + }; + + updateStatus = (state, callback) => { + this.setState({ + status: state.status, + active: state.status === Constant.USER_STATUS_ACTIVE, + }, callback); + }; + + didChange = () => { + if (this.props.isNew) { return true; } + if (this.state.active !== this.props.user.active) { return true; } + if (this.state.givenName !== this.props.user.givenName) { return true; } + if (this.state.surname !== this.props.user.surname) { return true; } + if (this.state.smUserId !== this.props.user.smUserId) { return true; } + if (this.state.email !== this.props.user.email) { return true; } + if (this.state.districtId !== this.props.user.districtId) { return true; } + if (this.state.agreementCity !== this.props.user.agreementCity) { return true; } + + return false; + }; + + isValid = () => { + this.setState({ + givenNameError: false, + surnameError: false, + smUserIdError: false, + emailError: false, + districtIdError: false, + }); + + var valid = true; + + if (isBlank(this.state.givenName)) { + this.setState({ givenNameError: 'Given Name is required' }); + valid = false; + } + + if (isBlank(this.state.surname)) { + this.setState({ surnameError: 'Surname is required' }); + valid = false; + } + + if (isBlank(this.state.smUserId)) { + this.setState({ smUserIdError: 'User ID is required' }); + valid = false; + } + + if (isBlank(this.state.email)) { + this.setState({ emailError: 'E-mail address is required' }); + valid = false; + } + + if (this.state.districtId === 0) { + this.setState({ districtIdError: 'District is required' }); + valid = false; + } + + return valid; + }; + + formSubmitted = () => { + if (this.isValid()) { + if (this.didChange()) { + this.setState({ isSaving: true }); + + const user = { + ...this.props.user, + active: this.state.active, + givenName: this.state.givenName, + surname: this.state.surname, + smUserId: this.state.smUserId, + email: this.state.email, + district: { id: this.state.districtId }, + agreementCity: this.state.agreementCity, + }; + + const isNewUser = this.state.isNew; + const addOrUpdateUser = isNewUser ? Api.addUser : Api.updateUser; + + addOrUpdateUser(user).then((userResponse) => { + this.setState({ isSaving: false }); + + // Make sure we get the new user's ID + if (isNewUser) { + user.id = userResponse.id; + } + + // Let the parent page component know that the user has been saved + this.props.onSave(user); + }, (err) => { + this.setState({ isSaving: false }); + + if (err.errorCode === 'HETS-38') { + this.setState({ smUserIdError: err.errorDescription }); + } else { + this.props.onClose(); + throw err; + } + }); + } else { + this.props.onClose(); + } + } + }; + + render() { + var districts = _.sortBy(this.props.districts, 'name'); + + return ( + + + Given Name * + + { this.state.givenNameError } + + + Surname * + + { this.state.surnameError } + + + User ID * + + { this.state.smUserIdError } + + + Status + + + + E-mail * + + { this.state.emailError } + + + District * + + { this.state.districtIdError } + + + Location + + + + ); + } +} + +function mapStateToProps(state) { + return { + districts: state.lookups.districts, + }; +} + +export default connect(mapStateToProps)(UsersEditDialog); diff --git a/client2/src/logo.svg b/client2/src/logo.svg new file mode 100644 index 000000000..9dfc1c058 --- /dev/null +++ b/client2/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client2/src/reportWebVitals.js b/client2/src/reportWebVitals.js new file mode 100644 index 000000000..5253d3ad9 --- /dev/null +++ b/client2/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/client2/src/sass/components/all.scss b/client2/src/sass/components/all.scss new file mode 100644 index 000000000..a8a6b3e7f --- /dev/null +++ b/client2/src/sass/components/all.scss @@ -0,0 +1,21 @@ +@import './badge-label'; +@import './clone-dialog'; +@import './date-control'; +@import './dropdown-control'; +@import './form-dialog'; +@import './favourites'; +@import './file-upload'; +@import './filter-dropdown'; +@import './form-input-control'; +@import './history'; +@import './link-control'; +@import './multi-dropdown'; +@import './return-button'; +@import './print-button'; +@import './search-control'; +@import './sort-table'; + +@import './ui/add-button-container'; +@import './ui/page-header'; +@import './ui/subheader'; +@import './ui/search-bar'; diff --git a/client2/src/sass/components/badge-label.scss b/client2/src/sass/components/badge-label.scss new file mode 100644 index 000000000..e538943d6 --- /dev/null +++ b/client2/src/sass/components/badge-label.scss @@ -0,0 +1,5 @@ +.badge-label { + border-radius: 1em; + font-size: 100%; + margin: 0 .2em; +} diff --git a/client2/src/sass/components/clone-dialog.scss b/client2/src/sass/components/clone-dialog.scss new file mode 100644 index 000000000..1337494fd --- /dev/null +++ b/client2/src/sass/components/clone-dialog.scss @@ -0,0 +1,18 @@ +#clone-dialog { + .radio { + margin: 0; + } + + .table tr > td { + vertical-align: middle; + } + + .dropdown-control { + position: relative; + max-width: 225px; + + .dropdown-menu { + width: 100%; + } + } +} diff --git a/client2/src/sass/components/date-control.scss b/client2/src/sass/components/date-control.scss new file mode 100644 index 000000000..d1442d37b --- /dev/null +++ b/client2/src/sass/components/date-control.scss @@ -0,0 +1,38 @@ +.date-control { + .rdt { + display: inline; + } + + .rdtPicker { + top: 34px; + } + + .form-control { + margin: 0; + width: 102px !important; + } + + .input-group-btn { + float: left; + } + + label { + float: left; + margin-top: 7px; + margin-right: 5px; + font-weight: normal; + } + + .btn { + padding-top: 5px; + } +} + +.has-error .date-control { + .btn { + color: #a94442; + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } +} diff --git a/client2/src/sass/components/dropdown-control.scss b/client2/src/sass/components/dropdown-control.scss new file mode 100644 index 000000000..dcaf37132 --- /dev/null +++ b/client2/src/sass/components/dropdown-control.scss @@ -0,0 +1,72 @@ +.dropdown-control { + .dropdown-toggle { + max-width: 200px; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 22px; + + .caret { + position: absolute; + top: 50%; + right: 10px; + } + } + + &.full-width { + .dropdown-menu { + width: 100%; + } + } + + .dropdown-menu { + padding: 0; + + ul { + margin: 0; + padding: 0; + list-style: none; + max-height: 262px; + overflow-y: auto; + } + + li { + margin: 0; + } + + a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; + } + + a:hover, + a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; + } + } +} + +.form-group .dropdown-control { + display: flex; + + .btn { + width: 100%; + max-width: none; + text-align: left; + } +} + +.has-error .dropdown-control { + .btn { + color: #a94442; + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } +} diff --git a/client2/src/sass/components/favourites.scss b/client2/src/sass/components/favourites.scss new file mode 100644 index 000000000..410917649 --- /dev/null +++ b/client2/src/sass/components/favourites.scss @@ -0,0 +1,40 @@ +.favourites { + .dropdown-toggle { + width: 105px; + } + + .dropdown-menu { + width: 250px; + padding: 0px; + + .favourites-button-bar { + padding: 6px; + + button { + width: 100%; + } + } + + ul { + margin: 0px; + padding: 6px; + list-style: none; + max-height: 200px; + overflow-y: auto; + } + + li { + .btn-toolbar { + float: right; + + .btn { + margin-left: 6px; + } + } + + a { + cursor: pointer; + } + } + } +} diff --git a/client2/src/sass/components/file-upload.scss b/client2/src/sass/components/file-upload.scss new file mode 100644 index 000000000..b488cbc42 --- /dev/null +++ b/client2/src/sass/components/file-upload.scss @@ -0,0 +1,73 @@ +.file-picker { + display: inline-block; + + input[type='file'] { + display: none; + } + + label { + display: inline-block; + margin-bottom: 0; + } +} + +.file-upload { + .progress { + width: 500px; + margin: 6px 0; + } + + .file-upload-error-message { + color: #9a133e; + position: relative; + cursor: pointer; + padding-right: 20px; + + .glyphicon-remove { + width: 16px; + height: 16px; + font-size: 16px; + position: absolute; + top: 50%; + right: 0; + margin-top: -8px; + } + } +} + +.file-upload-dialog { + .note { + text-align: center; + } + + ol.file-list { + border-bottom: 1px solid #eeeeee; + margin: 0 0 20px 0; + padding: 0 0 15px 0; + list-style: none; + + li { + padding: 5px 15px; + margin: 0 -15px; + + &:hover { + background-color: #eeeeee; + } + + .glyphicon { + float: right; + cursor: pointer; + + &:hover { + color: #9e0a0a; + } + } + } + } + + .modal-footer { + .file-upload { + float: right; + } + } +} diff --git a/client2/src/sass/components/filter-dropdown.scss b/client2/src/sass/components/filter-dropdown.scss new file mode 100644 index 000000000..8153121aa --- /dev/null +++ b/client2/src/sass/components/filter-dropdown.scss @@ -0,0 +1,104 @@ +.filter-dropdown { + .dropdown-toggle { + max-width: 200px; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 22px; + + .caret { + position: absolute; + top: 50%; + right: 10px; + } + } + + &.full-width { + width: 100%; + + .dropdown-toggle { + width: 100%; + max-width: 100%; + } + + .dropdown-menu { + width: 100%; + } + } + + .dropdown-menu { + padding: 0; + + ul { + margin: 0; + padding: 0 0; + list-style: none; + max-height: 222px; + overflow-y: auto; + } + + li { + margin: 0; + } + + a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; + } + + a:hover, + a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; + } + + .well-sm { + padding: 7px; + margin: 0; + border-radius: 2px; + } + } + + &.disabled { + cursor: not-allowed; + + &>button { + pointer-events: none; + } + } +} + +.form-group .filter-dropdown { + display: flex; + + .btn { + width: 100%; + text-align: left; + } +} + +.has-error .filter-dropdown { + .btn { + color: #a94442; + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + + .form-control { + border: 1px solid #ccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + + .form-control:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + } +} diff --git a/client2/src/sass/components/form-dialog.scss b/client2/src/sass/components/form-dialog.scss new file mode 100644 index 000000000..e44c81b68 --- /dev/null +++ b/client2/src/sass/components/form-dialog.scss @@ -0,0 +1,18 @@ +.form-dialog { + [class*='col-'] { + padding-left: 7px; + padding-right: 7px; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + + h4 { + font-size: 18px; + } +} diff --git a/client2/src/sass/components/form-input-control.scss b/client2/src/sass/components/form-input-control.scss new file mode 100644 index 000000000..e69de29bb diff --git a/client2/src/sass/components/history.scss b/client2/src/sass/components/history.scss new file mode 100644 index 000000000..566efde47 --- /dev/null +++ b/client2/src/sass/components/history.scss @@ -0,0 +1,18 @@ +#history-list { + width: 100%; + white-space: nowrap; + max-height: 250px; + overflow-y: auto; + + .btn { + margin: 0; + } + + .history-event { + white-space: normal; + } + + .table { + margin: 0; + } +} diff --git a/client2/src/sass/components/link-control.scss b/client2/src/sass/components/link-control.scss new file mode 100644 index 000000000..27ba425d9 --- /dev/null +++ b/client2/src/sass/components/link-control.scss @@ -0,0 +1,8 @@ +.link-control { + label { + float: left; + margin-top: 7px; + margin-right: 5px; + font-weight: normal; + } +} diff --git a/client2/src/sass/components/multi-dropdown.scss b/client2/src/sass/components/multi-dropdown.scss new file mode 100644 index 000000000..9c18fff2a --- /dev/null +++ b/client2/src/sass/components/multi-dropdown.scss @@ -0,0 +1,96 @@ +.multi-dropdown { + .dropdown-toggle { + max-width: 200px; + text-overflow: ellipsis; + overflow: hidden; + padding-right: 22px; + + .caret { + position: absolute; + top: 50%; + right: 10px; + } + } + + &.full-width { + .dropdown-toggle { + width: 100%; + max-width: 100%; + } + + .dropdown-menu { + width: 100%; + } + } + + .dropdown-menu { + padding: 0px; + + ul { + margin: 0; + padding: 0 7px; + list-style: none; + max-height: 200px; + overflow-y: auto; + } + + li { + margin: 5px 0; + } + + .well-sm { + padding: 7px 7px 0; + margin: 0; + border-radius: 2px; + } + + .checkbox { + margin-top: 5px; + margin-bottom: 5px; + + label { + white-space: nowrap; + } + } + + .select-all { + label { + font-weight: 600; + } + } + } +} + +.form-group .multi-dropdown { + display: flex; + + .btn { + width: 100%; + text-align: left; + } +} + +.has-error .multi-dropdown { + .btn { + color: #a94442; + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + + .checkbox { + color: #494949; + } + + .form-control { + border: 1px solid #ccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + } + + .form-control:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + } +} diff --git a/client2/src/sass/components/print-button.scss b/client2/src/sass/components/print-button.scss new file mode 100644 index 000000000..668a3ab05 --- /dev/null +++ b/client2/src/sass/components/print-button.scss @@ -0,0 +1,7 @@ +.print-button { + margin-right: 5px; + + span:not(:empty) { + margin-left: 5px; + } +} diff --git a/client2/src/sass/components/return-button.scss b/client2/src/sass/components/return-button.scss new file mode 100644 index 000000000..f102efda7 --- /dev/null +++ b/client2/src/sass/components/return-button.scss @@ -0,0 +1,8 @@ +.return-button { + margin-left: 5px; + + .glyphicon { + vertical-align: middle; + top: -1px; + } +} diff --git a/client2/src/sass/components/search-control.scss b/client2/src/sass/components/search-control.scss new file mode 100644 index 000000000..5010c9fcd --- /dev/null +++ b/client2/src/sass/components/search-control.scss @@ -0,0 +1,11 @@ +@media (min-width: 768px) { + .search-control .input-group { + display: inline-table; + vertical-align: middle; + } + + .search-control .input-group .input-group-btn, + .search-control .input-group .form-control { + width: auto; + } +} diff --git a/client2/src/sass/components/sort-table.scss b/client2/src/sass/components/sort-table.scss new file mode 100644 index 000000000..de796a1a2 --- /dev/null +++ b/client2/src/sass/components/sort-table.scss @@ -0,0 +1,30 @@ +.sort-table { + width: 100%; + overflow-y: auto; + position: relative; + + @media print { + overflow-y: visible !important; + } + + #sort-table-refreshing-overlay { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + border-radius: 5px; + box-shadow: 0 0 5px rgba(0,0,0,0.1); + background-color: rgba(0,0,0,0.1); + z-index: 1000; + pointer-events: none; + + .spinner { + position: absolute; + top: 50%; + left: 50%; + margin-top: -12px; + margin-left: -12px; + } + } +} diff --git a/client2/src/sass/components/ui/add-button-container.scss b/client2/src/sass/components/ui/add-button-container.scss new file mode 100644 index 000000000..c8eb1f562 --- /dev/null +++ b/client2/src/sass/components/ui/add-button-container.scss @@ -0,0 +1,4 @@ +#add-button-container { + float: right; + margin-top: 10px; +} diff --git a/client2/src/sass/components/ui/page-header.scss b/client2/src/sass/components/ui/page-header.scss new file mode 100644 index 000000000..a28d4e92b --- /dev/null +++ b/client2/src/sass/components/ui/page-header.scss @@ -0,0 +1,13 @@ +h1.ui-page-header { + small { + font-size: 85%; + } + + .btn-group { + float: right; + + .btn { + width: 40px; + } + } +} diff --git a/client2/src/sass/components/ui/search-bar.scss b/client2/src/sass/components/ui/search-bar.scss new file mode 100644 index 000000000..d354ffe0f --- /dev/null +++ b/client2/src/sass/components/ui/search-bar.scss @@ -0,0 +1,38 @@ +.search-bar { + #filters { + .btn-group { + .btn { + text-align: left; + } + } + + .btn-toolbar { + @include flex; + flex-wrap: wrap; + } + + .btn-toolbar > div, .btn-toolbar > button, .btn-toolbar > span { + margin: 5px; + } + + .btn-toolbar > label.checkbox-control { + margin: 12px 10px 5px 5px; + } + + .btn-toolbar > input { + float: left; + min-width: 175px; + margin: 5px; + width: auto; + } + + .btn-toolbar > div.date-control { + padding-left: 2px; + } + } + + #search-buttons > .row > div, #search-buttons > .row > button { + width: 105px; + margin: 5px 0; + } +} diff --git a/client2/src/sass/components/ui/subheader.scss b/client2/src/sass/components/ui/subheader.scss new file mode 100644 index 000000000..6e7c35c73 --- /dev/null +++ b/client2/src/sass/components/ui/subheader.scss @@ -0,0 +1,3 @@ +h3.ui-subheader { + font-weight: 600; +} diff --git a/client2/src/sass/gov3.scss b/client2/src/sass/gov3.scss new file mode 100644 index 000000000..5eee25b34 --- /dev/null +++ b/client2/src/sass/gov3.scss @@ -0,0 +1,2347 @@ +@import "./variables.scss"; + +html, +body { + height: 100%; +} + +body { + font-family: Calibri, Arial, "sans serif"; + background-color: #f1f1f1; + color: #494949; + font-size: 13px; +} + +a { + color: #1a5a96; +} + +h1, +h2, +h3, +h4, +h5 { + margin-top: 0; + color: #494949; +} + +h1 { + font-size: 24px; + font-weight: 600; +} + +h2 { + font-size: 21px; +} + +h3 { + font-size: 18px; +} + +h4 { + font-size: 15px; +} + +[class*="col-"] { + padding-left: 0; + padding-right: 0; +} + +table { + margin: 10px 0; +} + +td { + padding: 4px; +} + +th { + padding: 4px; + text-align: center; +} + +.row { + margin: 0; +} + +.table-responsive { + border: none; +} + +.modal-title { + font-weight: bold; +} + +.nowrap { + white-space: nowrap; +} + +#header { + width: 100%; + z-index: 2; +} + +#header-main { + background-color: #003366; + border: none; + /* border-bottom: 2px solid #fcba19; */ + /* padding-bottom: 5px; */ +} + +#header .header-main-left, +#header .header-main-right { + padding: 0; +} + +#logo { + float: left; +} + +#header .logo { + display: block; +} + +#access { + display: inline; + height: 0; + position: absolute; + width: 0; + z-index: 9; +} + +#access ul { + padding-left: 10px; + list-style: none; +} + +#access li a { + margin: 10px 0 0 -5000px; + width: 90px; + padding: 5px; + position: absolute; + top: 0; + color: #fcba19; +} + +#access li a:focus { + margin-left: 0; +} + +#header .qa-banner { + background-color: black; +} + +#header .qa-banner .container { + text-align: center; + max-width: 1140px; + padding: 15px; +} + +#header .qa-banner .container .qa-banner-text { + color: #fff; + font-size: 18px; +} + +#header .menu-button { + background-color: #38598a; + margin-top: 14px; + padding: 4px 0 3px; + text-align: center; + width: 155px; + color: #fff; + border: 1px solid white; + cursor: pointer; +} + +#header .menu-button:hover { + background-color: #5475a7; +} + +#header .menu-button span { + margin: 0; + font-weight: 400; + cursor: pointer; +} + +#header .menu-button img { + margin-right: 6px; + margin-bottom: 2px; +} + +#header .search, +#searchWidget .search { + /*height: 25px; + width: 100%; */ + margin-top: 4px; + margin-left: 10px; + position: relative; +} + +#searchWidget { + background-color: #f1f1f2; + padding: 15px; + margin-bottom: 15px; +} + +.noWhiteBorder, +.yesWhiteBorder { + margin-bottom: 15px; +} + +.yesWhiteBorder { + border: 5px solid #fff; +} + +#searchWidget p.searchWidget_heading { + font-weight: bold; + margin: 0; +} + +#searchWidget .search { + margin-left: 0; +} + +#header .search input, +#searchWidget .search input { + border: 1px solid #fff; + height: 30px; + padding: 3px 10px; + width: 100%; +} + +#header .search .search-trigger, +#searchWidget .search .search-trigger { + margin-top: -30px; + cursor: pointer; + height: 30px; + position: relative; + right: 6px; + float: right; + width: 30px; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/search-ico.png"); + background-position: 98% center; + background-repeat: no-repeat; +} + +#searchWidget .search .search-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/search-ico-blue.png"); + right: 0; +} + +#preSetSearchTerms, +#allOption { + display: none; +} + +#header-links { + margin-top: 10px; +} + +#header-links a { + color: #fff; +} + +@media (min-width: 768px) { + #header-links > ul li > a { + padding: 0; + } +} + +#header-main-row2 { + padding-bottom: 10px; +} + +.navigationRibbon { + -webkit-box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); + -moz-box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); + box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); + border-top: 2px solid #fcba19; +} + +.navigationRibbon a { + color: #fff; + display: table-cell; + text-align: center; + vertical-align: middle; + padding: 10px 15px; + position: relative; +} + +.navigationRibbon a + a:after { + content: ""; + background: #748bad; + position: absolute; + bottom: 25%; + left: 0; + height: 50%; + width: 1px; +} + +.navigationRibbon a.current { + text-decoration: underline; + font-weight: bold; +} + +.navigationRibbon .level2Navigation a.current { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/nav-ribbon-arrow.png"); + background-position: center bottom; + background-repeat: no-repeat; +} + +.navigationRibbon .level2Navigation { + background-color: #38598a; +} + +.navigationRibbon .level3Navigation { + background-color: #5475a7; +} + +.header-main-right { + margin-top: 5px; +} + +#breadcrumbContainer { + position: relative; + height: 80px; +} + +.breadcrumb { + background: none; + padding: 0; + margin: 0; + position: absolute; + bottom: 30px; +} + +.breadcrumb > li { + list-style-type: none; + display: inline; +} + +.breadcrumb > li::after, +.breadcrumb > li + li::after { + content: "/ "; + padding: 0 5px; +} + +.breadcrumb > li + li::before { + content: none; +} + +#breadcrumb li a { + font-size: 13px; +} + +#breadcrumb li #themeBreadcrumb { + font-size: 18px; +} + +#shareIcons { + position: relative; +} + +#shareContainer { + position: fixed; + right: 10px; + display: block; + bottom: 10px; + z-index: 1300; +} + +#shareContainer.footer-overlap { + position: absolute; + top: -122px; +} + +#shareButton { + background-repeat: no-repeat; + float: right; + background-color: #abaeb7; + padding: 14px 14px 14px 15px; + border-radius: 3px; + color: #fff; + text-decoration: none; + opacity: 0.75; + height: 53px; + width: 53px; + background-position: 56% 46%; +} + +#shareButton:hover { + opacity: 0.9; +} + +#shareBubble { + background-color: #ffffff; + height: 120px !important; + width: 325px; + display: none; + z-index: 10; + position: absolute; + bottom: 0; + right: 53px; + border: 1px solid #e3e3e3; +} + +#shareBubble h4 { + line-height: 1.8em; + padding: 10px 10px 8px 10px; + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.share_link { + padding: 0 10px 10px 10px; +} + +.share_link_buttons { + float: right; + padding: 3px; + margin-top: -4px; + margin-right: 7px; +} + +.share_link input { + width: 100%; + padding: 5px; +} + +/*RA-578 2016.07.18 r.lowe - added to prevent floated images from entering RC on mobile*/ +#body { + overflow: hidden; +} + +/*RA-597: Additional White Space */ +#body > p:first-of-type { + margin: 0px; +} + +#main-content-anchor { + display: block; + visibility: hidden; +} + +#main-content .table-responsive { + overflow-x: visible; + overflow-y: visible; +} + +ul.inline { + list-style-type: none; + margin: 0; + overflow: hidden; + padding: 0; +} + +ul.inline li { + float: left; + padding: 2px 10px; + position: relative; +} + +@media (min-width: 768px) { + ul.inline li + li { + border-left: 1px solid #4b5e73; + } +} + +ul.inline li a:link, +nav ul.inline li a:visited { + color: white; + display: block; + text-align: center; +} + +.iframe-video-embed, +.iframe-video-embed > iframe { + max-width: 100%; +} + +.iframe-map-embed, +.iframe-map-embed > iframe { + max-width: 100%; +} + +.iframe-visualization-embed, +.iframe-visualization-embed > iframe { + max-width: 100%; +} + +#footer { + background-color: transparent; + border-top: 2px solid #fcba19; + position: relative; + height: $footer-height; +} + +#footer.expanded { + z-index: 1040; +} + +#footer a, +#footer h2 { + color: #fff; +} + +#footer h2 { + font-size: 18px; + margin-bottom: 10px; + margin-top: 22px; + padding-right: 20px; +} + +#footer hr { + background: none repeat scroll 0 0 #4b5e73; + border: 0 none; + height: 1px; + margin: 10px 0; +} + +#footer #footerWrapper { + /* position: absolute; */ + width: 100%; + bottom: 0; +} + +#footerAdminSection ul { + clear: both; + padding: 10px 0; +} + +#footerAdminLinks { + clear: both; +} + +@media (min-width: 768px) { + #footerMediaLinks ul { + padding-top: 22px; + } +} + +#footerMediaLinks h2 { + display: inline-block; +} + +#footerFeedback { + position: relative; + height: 50px; +} + +#footerToggle { + background-color: #003366; + text-align: center; +} + +#footerCollapsible { + display: none; + background-color: #003366; + border: 1px solid transparent; +} + +#footerAdminSection { + background-color: #003366; +} + +#feedbackWrapper { + position: absolute; + bottom: 0; + right: 0; + color: #fff; +} + +#feedbackToggle { + background-color: #38598a; + cursor: pointer; + width: 220px; + height: 40px; + padding: 10px 0; + text-align: center; +} + +#feedbackForm { + display: none; + width: 220px; + height: 300px; + background-color: #38598a; +} + +.template { + min-height: calc(100vh - #{$footer-height}); + padding-bottom: 80px; + background-color: #fff; + font-size: 14px; +} + +#homeTemplate { + background-color: transparent; + margin-top: -20px; +} + +#errorPage { + padding: 10px; +} + +@media (min-width: 768px) { + #homeTemplate { + padding-top: 200px; + } + #errorPage { + padding-top: 150px; + } +} + +#themeTemplate { + background-position: right 150px; + background-repeat: no-repeat; + background-color: transparent; +} + +#errorPage { + background-position: right 150px; + background-repeat: no-repeat; + background-color: transparent; +} + +@media (min-width: 992px) { + .contentPageRightColumn, + .homePageRightColumn { + padding-left: 15px; + } +} + +@media (min-width: 768px) { + .contentPageLeftNavigation { + padding-right: 15px; + } +} + +.contentPageLeftNavigation ul { + list-style: none; + padding-left: 0; +} + +.contentPageLeftNavigation ul.leftNav { + border: 1px solid #e1e1e1; + padding-bottom: 10px; + padding-right: 10px; + padding-left: 10px; + width: 100%; +} + +.contentPageLeftNavigation ul li { + width: 100%; +} + +.contentPageLeftNavigation > div { + padding-left: 10px; +} + +.contentPageLeftNavigation ul li { + list-style: none; + background-position: 0 4px; + background-repeat: no-repeat; + line-height: 14px; + margin-top: 10px; + padding-left: 10px; + padding-right: 10px; +} + +ul.leftNav > li:first-child { + margin-top: 0; +} + +.contentPageLeftNavigation div > ul { + padding-bottom: 26px; + padding-top: 10px; + top: 10px; +} + +.contentPageLeftNavigation ul li.closed { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/sidecolumnnav_closed.gif"); + background-position: 0 2px; +} + +.contentPageLeftNavigation ul li ul { + display: none; +} + +.contentPageLeftNavigation ul li.open ul { + display: block; +} + +.contentPageLeftNavigation ul li.solo { + background-image: none; +} + +.contentPageLeftNavigation ul li.open { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/sidecolumnnav_open.gif"); + background-position: 0 2px; +} + +.contentPageLeftNavigation ul li a { + text-decoration: none; + display: block; + padding: 2px 0 0 4px; +} + +#topicLeftNav, +#topicLeftNav .navbar-collapse { + padding: 0; + border: none; +} + +#topicLeftNav li.open a { + background-color: inherit; +} + +.contentPageLeftNavigation ul li a:hover { + text-decoration: underline; +} + +.contentPageLeftNavigation ul li.active > div.leftNav-item-wrapper a { + font-weight: bold; + text-decoration: underline; +} + +.contentPageLeftNavigation ul li.current > div.leftNav-item-wrapper a { + font-weight: bold; + text-decoration: underline; +} + +.blue-heading-bar { + background-color: #003366; /* for IE */ + background-color: rgba(0, 51, 102, 0.8); + color: #fff; + font-size: 24px; + margin: 0; + padding: 8px 15px 7px 15px; +} + +.contentPageMainColumn .blue-heading-bar { + margin: 0; +} + +.featureBoxes-3col, +.tiles-container { + display: table; + width: 100%; +} + +.tiles-row { + display: table-row; +} + +.featureBoxes-3col { + margin-bottom: 15px; +} + +.featureBoxes-3col > .featureBox, +.tiles-row > .tile { + background-color: #fff; /* for IE */ + background-color: rgba(255, 255, 255, 0.8); + display: table-cell; + float: none; + vertical-align: top; + padding: 20px 15px; +} + +.tiles-container-3col .tiles-row .tile { + border-top: 1px solid #e3e3e3; + width: 33%; +} + +.tiles-container-3col .tiles-row:first-child .tile { + border-top: 0; +} + +.tiles-container-2col .tiles-row .tile { + border-top: 1px solid #e3e3e3; +} + +.tiles-container-2col .tiles-row:first-child .tile { + border-top: 0; +} + +.tiles-container-2col.level2 .tiles-row:first-child .tile { + border: 1px solid #e3e3e3; +} + +.tiles-container-2col.level2 .tiles-row .tile { + border: 1px solid #e3e3e3; + border-top: 0; +} + +@media (min-width: 768px) { + .tiles-container-2col.level2 .tiles-row .tile + .tile { + border-left: 0; + } +} + +.tiles-container-3col .tiles-row .tile + .tile, +.tiles-container-2col .tiles-row .tile + .tile { + border-left: 1px solid #e3e3e3; +} + +.featureBoxes-3col .featureBox + .featureBox { + border-left: 1px solid #e3e3e3; +} + +.featureBoxes-3col .featureBox .title, +.tiles-container .tile .title { + font-size: 18px; + color: #1a5a96; +} + +.featureBoxes-3col .featureBox .text, +.tiles-row .tile .tileText { + margin-top: 0; + font-size: 13px; + /* color: #7a7a7a; */ +} + +.featureBoxes-3col .featureBox img { + width: 100% !important; + height: auto !important; +} + +.homepage-tile { + background-color: #fff; + border-bottom: 1px solid #e3e3e3; + height: 70px; + position: relative; + /* overflow: hidden; */ +} + +.homepage-tile .tile-icon { + float: left; + height: 70px; + width: 85px; + position: relative; + padding: 0 15px; +} + +.homepage-tile .down-arrow-top { + position: absolute; + top: 0; + left: 36px; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: url("/StaticWebResources/static/gov3/images/down-arrow.png") + // no-repeat scroll 0 0 transparent; + height: 7px; + width: 12px; +} + +.homepage-tile .down-arrow-bottom { + position: absolute; + bottom: 0; + left: 36px; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: url("/StaticWebResources/static/gov3/images/down-arrow.png") + // no-repeat scroll 0 0 transparent; + height: 7px; + width: 12px; +} + +.homepage-tile.first .down-arrow-top, +.homepage-tile.last .down-arrow-bottom { + display: none; +} + +.homepage-tile .tile-content { + position: relative; + overflow: hidden; +} + +.homepage-tile .tile-text { + height: 70px; + font-size: 13px; + padding: 0 25px; +} + +.homepage-tile .tile-text .title { + padding: 5px 0 3px 0; + margin: 0; +} + +.homepage-tile .tile-search { + position: absolute; + top: 0; + right: 0; + display: none; + height: 99%; + width: 40px; + z-index: 3; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #fff + // url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") + // no-repeat left center; +} + +.homepage-tile .tile-search.touchable { + position: absolute; + top: 0; + right: 0; + display: block; + height: 99%; + width: 40px; + z-index: 3; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #fff + // url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") + // no-repeat left center; +} + +.homepage-tile:hover .tile-search, +.homepage-tile.flyout-expanded .tile-search { + display: block; +} + +.homepage-tile .tile-search:hover { + cursor: pointer; +} + +.homepage-tile .tile-search:hover, +.homepage-tile.flyout-expanded .tile-search { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #26639c + // url("/StaticWebResources/static/gov3/images/inlinesearch-button-on.png") + // no-repeat left center; +} + +.homepage-tile .tile-search-flyout { + position: absolute; + left: 1000px; + width: 100%; + max-width: 770px; + top: 0; + height: 100%; +} + +.homepage-tile .tile-search-flyout form { + height: 100%; +} + +.homepage-tile .tile-search-flyout input { + height: 99%; + width: 100%; + padding: 5px 50px 5px 15px; + border: 1px solid #26639c; + font-size: 16px; + background: #fff; +} + +.homepage-tile .tile-search-flyout input.placeholder { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #fff + // url("/StaticWebResources/static/gov3/images/tile_searchbox_placeholder.png") + // no-repeat left center; +} + +.homepage-tile table.ss-gac-m { + left: 85px; + width: 85%; + top: 68px; +} + +.blue-heading-bar.sortable { + position: relative; +} + +.blue-heading-bar.sortable .heading-title { + display: inline-block; + padding-right: 25px; +} + +.blue-heading-bar.sortable .tile-sort-button { + position: absolute; + top: 5px; + right: 5px; + cursor: pointer; +} + +.themeHeader { + color: #494949; + font-weight: 600; + width: 100%; + min-height: 54px; + position: relative; +} + +.themeHeader h1 { + font-size: 36px; +} + +.rightColumnBox { + background-color: #fff; /* for IE */ + background-color: rgba(255, 255, 255, 0.8); + padding: 15px; + margin-bottom: 15px; + word-wrap: break-word; +} + +.rightColumnBox p > img, +.themePromoBox p > img { + display: inline; +} + +.rightColumnBox img, +.themePromoBox img { + display: block; + margin: 0 auto 10px auto; + width: inherit !important; + max-width: 100% !important; + height: auto !important; +} + +/* .rightColumnBox a { */ +/* word-wrap: break-word; */ +/* } */ + +.homePageMainColumn { + padding-bottom: 15px; +} + +.contentPageMainColumn img, +.contentPageMainColumn table { + max-width: 100% !important; + height: auto !important; +} + +.tile.col-sm-6 img { + width: 100% !important; +} + +.contentPageMainColumn ul, +.contentPageRightColumn ul, +.homePageRightColumn ul, +#footer ul.bulleted { + padding-left: 0; + list-style-type: none !important; +} + +.contentPageMainColumn ul { + padding-left: 17px; +} + +.contentPageMainColumn ol { + padding-left: 28px; +} + +.contentPageMainColumn ul > li, +.contentPageRightColumn ul > li, +.homePageRightColumn ul > li, +#footer ul.bulleted > li { + padding-left: 15px; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: url("/StaticWebResources/static/gov3/images/bullet.png") no-repeat + // scroll 0 8px transparent; + margin-bottom: 3px; +} + +.contentPageMainColumn ol > li, +.contentPageRightColumn ol > li, +.homePageRightColumn ol > li { + padding-left: 2px; + background: none; + margin-left: 2px; +} + +.contentPageMainColumn > #pageIntro:after, +.contentPageMainColumn > #introduction:after { + content: ""; + display: table; + clear: both; +} + +.rightColumnBox.usefulContacts .contacts { + display: table; +} + +.rightColumnBox.usefulContacts .contacts .contactRow { + display: table-row; +} + +.rightColumnBox.usefulContacts .contacts .contactLabel { + display: table-cell; + padding-right: 15px; + padding-bottom: 10px; + font-weight: bold; +} + +.rightColumnBox.usefulContacts .contacts .contactValue { + display: table-cell; + padding-bottom: 10px; +} + +#subthemeTemplate .rightColumnBox, +#topicTemplate .rightColumnBox { + background-color: #f1f1f2; +} + +#themeTemplate h1, +#subthemeTemplate h1, +#topicTemplate h1 { + margin-bottom: 0.67em; +} + +#topicTemplate h2 { + margin-top: 0.83em; + margin-bottom: 0.83em; +} + +#topicTemplate h2.blue-heading-bar { + margin: 0; +} + +#topicTemplate h3 { + margin-top: 1em; + margin-bottom: 1em; +} + +#topicTemplate h4 { + margin-top: 1.33em; + margin-bottom: 1.33em; +} + +#topicTemplate hr { + border-color: #dedede; +} + +.contentPageMainColumn p, +.contentPageRightColumn p { + margin-top: 1em; + margin-bottom: 1em; +} + +.contentPageRightColumn p:first-of-type { + margin-top: 0; +} + +#topicTemplate a.olrLinkSwitch { + text-decoration: none; + float: right; + position: absolute; + right: 0; + bottom: 30px; +} + +div#breadcrumbContainer .olrPolicyPage { + margin-right: 30px; +} + +.contentPageMainColumn a, +.homePageRightColumn a, +.contentPageRightColumn a, +#breadcrumbContainer a, +#search_result a h4, +#search_result #clustering a, +.contentPageMainColumn .explore a:hover, +#carousel .page .content .wrapper div a, +#carousel .page .content .wrapper div a.pull-left { + text-decoration: underline; +} + +#themeTemplate .contentPageMainColumn a, +#subthemeTemplate .contentPageMainColumn a { + text-decoration: none; +} + +.homePageMainColumn a:hover, +.homePageRightColumn a:hover, +.contentPageLeftNavigation a:hover, +.contentPageMainColumn a:hover, +.contentPageRightColumn a:hover, +#breadcrumbContainer a:hover, +#search_result a:hover h4, +#search_result #clustering a:hover { + color: #00f; +} + +.explore { + position: relative; +} + +.explore-within { + background-color: #f4f6f9; + border: 1px solid #e1e3e6; + color: #174f84; + font-size: 14px; + padding: 4px 10px; + width: 130px; + float: left; + cursor: pointer; +} + +.explore ul { + background-color: #f4f6f9; + border: 1px solid #e1e3e6; + box-shadow: 2px 2px 2px #ccc; + display: none; + left: 0; + padding: 0; + position: absolute; + top: 26px; + width: 100%; + z-index: 5; +} + +.explore ul li { + background-color: #f4f6f9; + background-image: none; + display: block; + float: none; + font-size: 13px; + padding: 6px 12px; + width: 100%; + margin: 0; +} + +.explore ul li + li { + border-top: 1px solid #e1e3e6; +} + +.explore ul li a { + color: #333; + display: block; + font-size: 13px; + text-decoration: none; +} + +.explore ul li a:hover { + text-decoration: underline; +} + +.themePromoBox { + /* float: left; + width: 49%; */ + padding-top: 15px; +} + +.themePromoBoxContent { + background-color: white; + padding: 15px; +} + +.feed + .feed { + /* margin-top: 30px; */ +} + +.feed h4 { + line-height: inherit; +} + +span.zeroAnch { + display: none; +} + +img.back-to-top { + position: fixed; + right: 10px; + bottom: 10px; + opacity: 0.75; + filter: alpha(opacity=75); /* For IE8 and earlier */ + z-index: 1100; + cursor: pointer; + display: none; +} + +/* img.back-to-top.footer-overlap, */ +/* #footer.expanded img.back-to-top { */ +img.back-to-top.footer-overlap { + position: absolute; + top: -63px; +} + +img.back-to-top:hover { + opacity: 0.9; + filter: alpha(opacity=90); /* For IE8 and earlier */ +} + +@media (min-width: 992px) { + .themePromoBox.left { + padding-right: 8px; + } + .themePromoBox.right { + padding-left: 8px; + } +} + +.arrow-link { + color: #1a5a96; + display: inline-block; + font-size: 14px; + font-weight: 600; + padding-left: 10px; + text-transform: uppercase; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: url("/StaticWebResources/static/gov3/images/bullet-arrow.png") + // no-repeat scroll 0 4px transparent; + margin-top: 10px; +} + +.rightColumnBox .count { + background-color: #f1f1f1; + border: 1px solid #e3e3e3; + color: #1a5a96; + display: inline-block; + float: left; + font-size: 30px; + font-weight: 600; + margin: 2px 0 0 0; + padding: 0 4px; +} + +.rightColumnBox .caption { + color: #494949; + display: inline-block; + float: left; + font-size: 16px; + line-height: 18px; + margin-top: 8px; + padding-left: 7px; + width: 138px; +} + +.rightColumnBox .date { + font-size: 13px; + font-weight: bold; +} + +@media (max-width: 750px) { + .homepage-tile .tile-text { + padding-right: 40px; + } + .homepage-tile .tile-search { + height: 40px; + line-height: normal; + display: block; + } + .homepage-tile .tile-search img { + padding: 5px 0; + } + .homepage-tile .tile-search-flyout .tile-searchbox { + height: 40px; + } + + .homepage-tile table.ss-gac-m { + left: 0; + width: 100%; + top: 39px; + } +} + +@media (max-width: 767px) { + #header { + z-index: 2; + } + #header .container { + padding: 0; + } + #header .qa-banner .container .qa-banner-text { + font-size: 13px; + } + #header-main { + position: relative; + border-bottom: none; + margin-bottom: 0; + border-bottom: 2px solid #fcba19; + } + #header #logo img { + width: 95%; + height: 95%; + } + + #header-links > ul li { + width: 33.3%; + } + #header-links > ul li a { + text-align: left; + } + #header #header-main-row1 { + position: relative; + } + #header #header-main-row1 .header-main-left { + padding-top: 0; + padding-bottom: 0; + } + #header #header-main-row1 .header-main-right { + margin-left: -15px; + margin-right: -15px; + margin-top: 0; + padding: 10px; + position: static; + } + #header #header-main-row1 .navbar-header { + padding-bottom: 10px; + } + #header-main-row1 .search-boarder-arror::after { + border-right: 36px solid transparent; + border-top: 41px solid #c7c8ca; + content: ""; + position: absolute; + right: 95px; + top: 46px; + transform: rotate(45deg); + -ms-transform: rotate(45deg); /* IE 9 */ + -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */ + z-index: 10; + display: none; + } + #header-main-row1 .in .search-boarder-arror::after { + display: block; + } + #header #header-main-row1 .header-search { + border-top: none; + box-shadow: none; + background-color: #c7c8ca; + margin-bottom: -2px; + overflow-y: visible; + } + #header #header-main-row2 { + border: none; + max-height: none; + } + #header .search { + position: static; + } + #header .search .search-trigger { + margin-top: -30px; + } + #header .search, + #header .search input { + height: 35px; + margin: 0; + bottom: 7px; + right: 20px; + font-size: 16px; + } + #header .menu-button.mini-menu-trigger, + #header .search-button.mini-menu-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/menu-open-mobile.png"); + background-repeat: no-repeat; + background-color: transparent; + border-radius: 0; + cursor: pointer; + height: 52px; + margin-top: 4px; + margin-bottom: 4px; + position: absolute; + right: 10px; + top: 0px; + width: 60px; + border: none; + background-position: center center; + } + #header .mini-menu-trigger + .mini-menu-trigger { + border-right: 2px solid #4b5e73; + } + #header .search-button.mini-menu-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/search-open-mobile.png"); + right: 70px; + } + #homeTemplate { + position: relative; + } + #breadcrumbContainer, + #breadcrumbContainer > .breadcrumb, + #breadcrumbContainer > a.olrLinkSwitch, + .themeHeader, + .themeHeader > .themeHeaderTitle { + position: static; + } + #breadcrumbContainer { + height: auto; + padding: 10px 0; + } + .themeHeader { + height: auto; + } + #footer { + position: relative; + height: auto !important; + } + #footerThemeLinks ul { + margin: 0; + } + .homepage-tile .tile-text, + .homepage-tile { + height: auto; + min-height: 70px; + } + #themeTemplate, + #subthemeTemplate, + #topicTemplate { + padding-top: 0 !important; + background-image: none !important; + } + .tiles-container-3col.level1 .tiles-row .tile + .tile, + .tiles-container-2col.level1 .tiles-row .tile + .tile { + border-left: none; + border-top: 1px solid #e3e3e3; + } + .tiles-container-2col.level2 .tiles-row:first-child .tile + .tile { + border-top: none; + } + .explore-within { + float: none; + } + .featureBoxes-3col > .featureBox, + .tiles-row > .tile { + display: block; + } + .featureBoxes-3col .featureBox + .featureBox { + border-left: none; + border-top: 1px solid #e3e3e3; + } + .contentPageLeftNavigation ul.leftNav { + margin: 0; + padding: 0; + border: none; + top: 0; + } + .contentPageLeftNavigation > div { + padding-left: 0px; + } + .contentPageLeftNavigation ul.leftNav { + border-left: 1px solid #e2e2e2; + border-right: 1px solid #e2e2e2; + border-bottom: 1px solid #e2e2e2; + } + .contentPageLeftNavigation ul li { + border-top: 1px solid #e2e2e2; + margin: 0; + padding: 0; + background-image: none !important; + } + .contentPageLeftNavigation ul.leftNav > li:first-child { + border-top: none; + } + .contentPageLeftNavigation ul.leftNav li a { + padding: 15px 50px 15px 25px; + } + .contentPageLeftNavigation ul.leftNav li li a { + padding-left: 40px; + } + .contentPageLeftNavigation ul.leftNav li li li a { + padding-left: 55px; + } + .contentPageLeftNavigation ul.leftNav li li li li a { + padding-left: 70px; + } + .contentPageLeftNavigation ul.leftNav li li li li li a { + padding-left: 85px; + } + .contentPageLeftNavigation ul.leftNav li li li li li li a { + padding-left: 100px; + } + .topic-menu-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/section-nav-open.png"); + background-position: 97% center; + background-repeat: no-repeat; + color: #1a5a96; + cursor: pointer; + display: block; + font-size: 16px; + padding: 15px 10px; + width: 100%; + text-align: left; + border: 1px solid #e2e2e2; + border-radius: 0; + margin: 0; + } + .leftNav-item-wrapper { + position: relative; + } + #topicLeftNav .level-trigger { + background-position: center center; + background-repeat: no-repeat; + border-left: 1px solid #e2e2e2 !important; + cursor: pointer; + display: inline-block; + float: right; + height: 100%; + position: absolute; + right: 0; + top: 0; + width: 50px; + } + #topicLeftNav li.open > .leftNav-item-wrapper .level-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/section-nav-arrow-dn.png"); + } + #topicLeftNav li.closed > .leftNav-item-wrapper .level-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/section-nav-arrow-up.png"); + } + #shareIcons { + display: none; + } +} + +@media (max-width: 992px) { + .themePromoBox { + margin-bottom: 15px; + padding-top: 0; + } + .tiles-container { + margin-bottom: 15px; + } + .contentPageRightColumn { + margin-top: 15px; + } +} + +.alert-success:before { + position: relative; + top: 1px; + margin-right: 10px; + display: inline-block; + font-family: "Glyphicons Halflings"; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; + content: "\e013"; + font-size: larger; +} + +.alert-info:before { + position: relative; + top: 1px; + margin-right: 10px; + display: inline-block; + font-family: "Glyphicons Halflings"; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; + content: "\e086"; + font-size: larger; +} + +.alert-warning:before { + position: relative; + top: 1px; + margin-right: 10px; + display: inline-block; + font-family: "Glyphicons Halflings"; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; + content: "\e107"; + font-size: larger; +} + +.alert-danger:before { + position: relative; + top: 1px; + margin-right: 10px; + display: inline-block; + font-family: "Glyphicons Halflings"; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; + content: "\e101"; + font-size: larger; +} + +.alert:before { + float: left; +} + +.alert p { + margin: 0; + padding-left: 1.8em; +} + +.ss-gac-m tr:hover { + cursor: pointer; +} + +/* Collapsed header styles */ + +#header.collapsed-header #header-main { + border-bottom: 2px solid #fcba19; + margin-bottom: 0; +} + +#header.collapsed-header #logo img { + width: 95%; + height: 95%; +} + +#header.collapsed-header #header-main > .container { + position: relative; +} + +#header.collapsed-header .hidden-xs { + display: none !important; +} + +#header.collapsed-header #header-main-row1 { + position: relative; +} + +#header.collapsed-header #header-main-row1 .header-main-left { + float: none; + width: auto; +} + +#header.collapsed-header #header-main-row1 .navbar-header { + float: none; + padding-bottom: 10px; +} + +#header.collapsed-header .menu-button.mini-menu-trigger, +#header.collapsed-header .search-button.mini-menu-trigger { + background-color: transparent; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/menu-open-mobile.png"); + background-position: center center; + background-repeat: no-repeat; + border: medium none; + border-radius: 0; + cursor: pointer; + height: 52px; + margin-top: 4px; + margin-bottom: 4px; + position: absolute; + right: 10px; + top: 0; + width: 60px; + display: block; +} + +#header.collapsed-header .mini-menu-trigger + .mini-menu-trigger { + border-right: 2px solid #4b5e73; +} + +#header.collapsed-header .search-button.mini-menu-trigger { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("../images/mini-menu/search-open-mobile.png"); + right: 70px; +} + +#header.collapsed-header .navbar-collapse.collapse { + display: none !important; +} + +#header.collapsed-header .navbar-collapse.collapse.in { + display: block !important; +} + +#header.collapsed-header #header-main-row1 .header-search { + background-color: #c7c8ca; + border-top: medium none; + box-shadow: none; + margin-bottom: -2px; + + height: 0; + position: absolute; + right: 50px; + width: 440px; +} + +#header.collapsed-header .visible-xs-block { + display: block !important; +} + +#header.collapsed-header + #header-main-row1 + .header-search + .search-boarder-arror::after { + border-right: 36px solid transparent; + border-top: 41px solid #c7c8ca; + content: ""; + display: none; + position: absolute; + right: 61px; + top: -14px; + transform: rotate(45deg); + -ms-transform: rotate(45deg); /* IE 9 */ + -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */ + z-index: 10; +} + +#header.collapsed-header + #header-main-row1 + .header-search.in + .search-boarder-arror::after { + display: block !important; +} + +#header.collapsed-header #header-main-row1 .header-search .header-main-right { + margin-left: -15px; + margin-right: -15px; + margin-top: 0; + padding: 10px; + position: static; +} + +#header.collapsed-header + #header-main-row1 + .header-search + .header-main-right + .search { + position: static; +} + +#header.collapsed-header + #header-main-row1 + .header-search + .header-main-right + .search, +#header.collapsed-header + #header-main-row1 + .header-search + .header-main-right + .search + input { + bottom: 7px; + height: 35px; + margin: 0; + right: 20px; +} + +#header.collapsed-header + #header-main-row1 + .header-search + .header-main-right + .search + .search-trigger { + margin-top: -30px; +} + +#header.collapsed-header #header-main-row2 { + border: medium none; + max-height: none; +} + +#header.collapsed-header #header-main-row2 { + position: absolute; + right: 0; + background-color: #036; + right: 65px; + width: 440px; + padding: 0; +} + +#header.collapsed-header #header-main-row2 .header-main-right { + margin: 0; +} + +#header.collapsed-header .navbar-fixed-top .navbar-collapse { + height: 10px; + margin-left: -15px; + margin-right: -15px; + padding-left: 15px; + padding-right: 15px; +} + +#header.collapsed-header .col-lg-6 { + width: auto; + float: none; + left: auto; + right: auto; +} + +#header.collapsed-header .header-main-left { + padding: 0; +} + +#header.collapsed-header .navbar-nav { + float: none; +} + +#header.collapsed-header #header-links { + margin: 0; +} + +#header.collapsed-header #header-links > ul { + padding: 6px 5px; + margin: 0; +} + +#header.collapsed-header #header-links > ul li { + width: 33.3%; + padding: 4px 10px; +} + +#header.collapsed-header #header-links > ul li a { + text-align: left; + padding: 0 10px; +} + +#header.collapsed-header #header-links ul.inline li + li { + border-left: 0; +} + +#header.collapsed-header #govNavMenu { + position: static; + z-index: auto; + top: auto; + width: auto; + float: none; + background-color: #036; +} + +/* .search-button.mini-menu-trigger{ */ +/* background-image: url("../images/mini-menu/search-open-mobile.png"); */ +/* background-repeat: no-repeat; */ +/* background-color: transparent; */ +/* border-radius: 0; */ +/* cursor: pointer; */ +/* height: 52px; */ +/* margin-top: 4px; */ +/* margin-bottom: 4px; */ +/* position: absolute; */ +/* left: 420px; */ +/* top: 0px; */ +/* width: 60px; */ +/* border: none; */ +/* background-position: center center; */ +/* } */ + +/* [RA-359] CS - homepage customizations for BC Gov Services Campaign */ +.popular-services-search .homepage-tile { + border-bottom: 0; + margin-bottom: 15px; + min-height: 0; +} + +.popular-services-search .homepage-tile .tile-content { + height: 100%; +} + +.popular-services-search .homepage-tile .tile-search { + display: block; + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #26639c + // url("/StaticWebResources/static/gov3/images/inlinesearch-button-on.png") + // no-repeat scroll left center; + height: 100%; +} + +@media (max-width: 767px) { + .popular-services-search .homepage-tile .tile-search { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background: #fff + // url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") + // no-repeat scroll left center; + } +} + +.popular-services-search .homepage-tile .tile-search-flyout { + position: static; + max-width: 815px; +} + +.popular-services-search .homepage-tile .tile-search-flyout form { + max-width: 815px; +} + +.popular-services-search + .homepage-tile + .tile-search-flyout + form + .tile-searchbox { + border: 0; + padding-right: 45px; +} + +.popular-services-search + .homepage-tile + .tile-search-flyout + form + .tile-searchbox.placeholder { + background: none; +} + +.popular-services-search .homepage-tile .ss-gac-m { + left: 0; +} + +.popular-services-text { + background-color: #fff; + margin-bottom: 15px; + padding: 10px 15px; + font-size: 16px; + color: #1a5a96; +} + +.popular-services-text p { + margin: 0; +} + +.campaign-service-buttons .blue-heading-bar { + display: none; +} + +.campaign-service-buttons .featureBoxes-3col h3.title { + display: none; +} + +.campaign-service-buttons .featureBoxes-3col p > a { + text-decoration: underline; +} + +.campaign-service-buttons .featureBoxes-3col p > a.btn { + text-decoration: none; +} + +.alert-content { + line-height: 1; + vertical-align: middle; +} +.alert-icon { + vertical-align: middle; +} + +table.alert-box { + margin: 5px; +} +td.alert-icon-col { + width: 20px; + vertical-align: middle; + padding: 0; +} +td.alert-content-col { + vertical-align: middle; + padding: 0; +} + +/* end changes for [RA-359] */ +.search-suggestion-full { + width: 100%; + visibility: hidden; +} +#suggestion_form { + position: relative; +} + +/* begin changes for [CLD-1454] */ +.panel-heading .collapseArrow { + //temporary fix. Note that the .pngs were commented out because these assets do not exist. + // background-image: url("/StaticWebResources/static/gov3/images/accordion-chevron.png"); + background-size: 14px 14px; + background-repeat: no-repeat; + background-position: right 0px bottom 0px; + height: 14px; + width: 14px; + overflow: hidden; + float: right; +} + +.panel-heading .open { + /*Point arrow upwards*/ + webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -o-transform: rotate(180deg); + transform: rotate(180deg); +} + +.accordion-container { + margin-top: 6px; +} + +.panel-group .panel { + margin-top: 6px; + border-radius: 0px; +} + +.panel-body p.panel-text { + margin: 0px; +} + +.panel-group .panel + .panel { + margin-top: 6px; +} + +.accordion-btn-container { + width: 170px; +} + +button.accordion-btn { + background-color: #f1f1f3; + border: none; + padding: 5px 8px; + color: #1c5a97; + text-decoration: none !important; +} + +a.accordion-btn { + background-color: #f1f1f3; + border: none; + padding: 5px 8px; + color: #1c5a97; + text-decoration: none !important; +} + +a.accordion-btn:hover { + background-color: #f1f1f3; + border: none; + padding: 5px 8px; + color: #1c5a97; + text-decoration: none !important; + cursor: pointer; +} + +.accordion-bar { + background-color: #f1f1f1; + padding: 5px 0px; +} + +.panel > .panel-heading { + background-color: #f1f1f3; + border-color: #f1f1f3; + padding: 8px; + cursor: pointer; +} +.panel-heading { + border-radius: 0; +} + +.panel { + border-color: #f1f1f3; + border-radius: 0; +} + +.panel-text { + margin-top: -1em; +} +.panel-text p { + margin-bottom: 0em; +} +.panel > .panel-heading + .panel-collapse > .panel-body { + border: 2px #f1f1f3; +} + +#topicTemplate .panel-title { + font-weight: bold; + color: #1c5a97; + max-width: 95%; + font-size: 16px; + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.panel-title p { + margin-top: 0; + margin-bottom: 0; +} + +.show-btn { + margin-right: -4px; +} + +.hide-btn { + margin-left: -4px; +} + +#topicTemplate .contentPageMainColumn a.accordionA { + text-decoration: none; +} + +#topicTemplate .contentPageMainColumn a.accordionA:hover { + text-decoration: none; + color: #1c5a97; +} +/* end changes for [CLD-1454] */ + +/* RA-31, Twitter feed */ +h5.twitterUserName { + margin-bottom: 5px; + font-weight: bold; + /*float: left;*/ +} + +h5.twitterUserName a { + font-weight: normal; + color: #aaa; + /*float: left;*/ + margin-top: 5px; +} + +.twitter-follow { + margin-bottom: 15px; + /*float: left;*/ + clear: left; + font-weight: bold; +} + +.feedEntry .createdAgo { + font-size: 0.9em; + color: #aaa; + margin-bottom: 20px; +} + +.twitterHeader { + width: 100%; + border-bottom: 1px solid #fff; + /*float: left;*/ + margin-bottom: 15px; + padding-bottom: 15px; +} + +.feed.rightColumnBox { + float: left; +} +/* end of changes for RA-31, Twitter feed */ + +#main-content #body a.btn { + word-break: normal; +} + +/* break a link if the link text is too long for the page width, especially in mobile */ +#main-content #body a { + word-wrap: break-word; + /* RA-636 - Non standard for webkit */ + word-break: break-word; +} + +/* ALERT CUSTOMIZATIONS */ + +.alert-success { + color: #2d4821; +} + +.alert-warning { + color: #6c4a00; + background-color: #f9f1c6; +} + +.alert-danger { + color: #d2322d; +} +.printHeader { + display: none; +} +@media print { + /*Globals*/ + body { + font-family: Arial, Helvetica, sans-serif; + /* width:720px; */ + } + a { + text-decoration: underline !important; + } + a[href]:after { + content: none; + } + #breadcrumbContainer { + display: none; + } + .template { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .container { + padding: 0; + } + .printHeader { + display: block; + } + .row { + /* height: 120px; */ + padding: 15px; + } + .featureBoxes-3col > .featureBox { + display: block; + width: 100%; + } + .contentPageMainColumn ul > li, + .contentPageRightColumn ul > li, + ul.bulleted > li { + list-style-type: disc; + margin-left: 20px; + } + .rightColumnBox { + padding: 0; + } + .contentPageRightColumn { + width: 100%; + } + .tiles-row { + width: 100%; + display: block; + } + + /*Homepage*/ + #main-content { + /* margin-top:50px; */ + width: 100%; + overflow: hidden; + } + .homePageMainColumn > .blue-heading-bar { + margin-top: 10px; + } + .homePageMainColumn > .sortable { + display: inline; + } + .featureBoxes-3col { + /* display:none; */ + } + .blue-heading-bar { + padding: 0; + } + .tile-sort-button { + display: none; + } + .homepage-tile .tile-icon { + display: none; + } + + /*Theme Page*/ + .themeHeader h1 { + margin: 50px 0 0 0; + } + .themePromoBoxContent { + padding: 0; + } + + .themeHeader { + padding-left: 10px; + } + + .tiles-container-2col .tiles-row .tile { + width: 100%; + height: 100%; + display: block; + border: 0 !important; + border-bottom: 1px solid black !important; + padding: 20px 0; + } + + .explore-within { + float: none; + border: 1px solid black !important; + } + + /*Topic Page*/ + .col-sm-3 { + width: 100%; + } + .col-sm-offset-3 { + margin: 0; + } + + /*Footer*/ + #footer { + display: none; + } +} diff --git a/client2/src/sass/header.scss b/client2/src/sass/header.scss new file mode 100644 index 000000000..c3ab015c1 --- /dev/null +++ b/client2/src/sass/header.scss @@ -0,0 +1,213 @@ +@import "./mixins.scss"; + +$nav-background-color: #38598a; +$nav-background-color-test: #448a38; +$nav-background-color-dev: #8a3844; +$nav-background-color-trn: #744e91; +$nav-background-color-uat: #d98747; + +$nav-active-background-color: #5475a7; +$nav-active-background-color-test: #60a654; +$nav-active-background-color-dev: #a65460; +$nav-active-background-color-trn: #9b5ab5; +$nav-active-background-color-uat: #db976d; + +#header { + #working-indicator { + position: absolute; + top: 15px; + right: 15px; + background-color: #2e6da4; + border-radius: 3px; + font-size: 13px; + color: white; + padding: 1px 6px; + white-space: nowrap; + + .spinner { + border-color: white; + width: 11px; + height: 11px; + } + } + + #banner { + float: left; + margin-top: 20px; + margin-left: 35px; + color: #fff; + font-weight: 600; + } +} + +#top-nav { + margin-bottom: 0; + background-color: $nav-background-color; + border-radius: 0; + border: 0; + border-top: 2px solid #fcba19; + -webkit-box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); + -moz-box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); + box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); + + > .container { + @include flex; + align-items: center; + } + + #rollover-notice-button { + span { + margin-left: 5px; + } + } + + #navbar-right { + margin: 0 0 0 auto; + + .dropdown-menu { + right: 0; + left: auto; + } + } + + #profile-menu + .dropdown-menu { + padding: 15px 15px 5px 15px; + + .form-group { + margin-top: 10px; + } + + .dropdown-control, + .dropdown-control .btn { + width: 100%; + } + + .btn-primary { + width: 100%; + margin-bottom: 10px; + } + } + + .navbar-nav > li > a { + color: #fff; + } + .navbar-nav > li > a:hover { + color: #fff; + text-decoration: underline; + } + .navbar-nav > li > a:focus { + color: #fff; + } + .navbar-nav > li > .dropdown-menu { + color: #fff; + background-color: $nav-background-color; + font-size: 13px; + } + .navbar-nav > li > .dropdown-menu > li > a { + color: #fff; + } + .navbar-nav > li > .dropdown-menu > li > a:hover, + .navbar-nav > li > .dropdown-menu > li > a:focus { + color: #fff; + background-color: $nav-active-background-color; + text-decoration: underline; + } + .navbar-nav > .active > a { + color: #fff; + background-color: $nav-active-background-color; + text-decoration: underline; + } + .navbar-nav > .active > a:hover, + .navbar-nav > .active > a:focus { + color: #fff; + background-color: $nav-active-background-color; + } + .navbar-nav > .open > a { + color: #fff; + background-color: $nav-background-color; + text-decoration: underline; + } + .navbar-nav > .open > a:hover, + .navbar-nav > .open > a:focus { + color: #fff; + background-color: $nav-background-color; + } + + &.env-test { + background-color: $nav-background-color-test; + + .navbar-nav > li > .dropdown-menu, + .navbar-nav > .open > a, + .navbar-nav > .open > a:hover, + .navbar-nav > .open > a:focus { + background-color: $nav-background-color-test; + } + .navbar-nav > li > .dropdown-menu > li > a:hover, + .navbar-nav > li > .dropdown-menu > li > a:focus, + .navbar-nav > .active > a, + .navbar-nav > .active > a:hover, + .navbar-nav > .active > a:focus { + background-color: $nav-active-background-color-test; + } + } + + &.env-dev { + background-color: $nav-background-color-dev; + + .navbar-nav > li > .dropdown-menu, + .navbar-nav > .open > a, + .navbar-nav > .open > a:hover, + .navbar-nav > .open > a:focus { + background-color: $nav-background-color-dev; + } + .navbar-nav > li > .dropdown-menu > li > a:hover, + .navbar-nav > li > .dropdown-menu > li > a:focus, + .navbar-nav > .active > a, + .navbar-nav > .active > a:hover, + .navbar-nav > .active > a:focus { + background-color: $nav-active-background-color-dev; + } + } + + &.env-uat { + background-color: $nav-background-color-uat; + + .navbar-nav > li > .dropdown-menu, + .navbar-nav > .open > a, + .navbar-nav > .open > a:hover, + .navbar-nav > .open > a:focus { + background-color: $nav-background-color-uat; + } + .navbar-nav > li > .dropdown-menu > li > a:hover, + .navbar-nav > li > .dropdown-menu > li > a:focus, + .navbar-nav > .active > a, + .navbar-nav > .active > a:hover, + .navbar-nav > .active > a:focus { + background-color: $nav-active-background-color-uat; + } + } + + &.env-trn { + background-color: $nav-background-color-trn; + + .navbar-nav > li > .dropdown-menu, + .navbar-nav > .open > a, + .navbar-nav > .open > a:hover, + .navbar-nav > .open > a:focus { + background-color: $nav-background-color-trn; + } + .navbar-nav > li > .dropdown-menu > li > a:hover, + .navbar-nav > li > .dropdown-menu > li > a:focus, + .navbar-nav > .active > a, + .navbar-nav > .active > a:hover, + .navbar-nav > .active > a:focus { + background-color: $nav-active-background-color-trn; + } + } +} + +#rollover-notice { + .btn-primary { + width: 100%; + } +} diff --git a/client2/src/sass/init.scss b/client2/src/sass/init.scss new file mode 100644 index 000000000..a6dfb6a70 --- /dev/null +++ b/client2/src/sass/init.scss @@ -0,0 +1,37 @@ +#initialization { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 10% 15%; + background-color: white; + z-index: 9999; + transform-origin: 50%, 50%; + opacity: 1; + transition: transform 1s ease, opacity 400ms; + + &.done { + opacity: 0; + transform: scale(1.2); + } + + #init-message { + font-size: 20px; + font-family: Arial, 'sans serif'; + } + + .progress-bar { + width: 5%; + min-width: 30px; + } + + #loading-error-message { + margin-top: 50px; + text-align: center; + + p { + white-space: pre-line; + } + } +} diff --git a/client2/src/sass/main.scss b/client2/src/sass/main.scss new file mode 100644 index 000000000..4b67f2fc7 --- /dev/null +++ b/client2/src/sass/main.scss @@ -0,0 +1,137 @@ +//temporary fix to remove conlficts with unknown pngs. +@import "gov3"; +@import "init"; +@import "header"; +@import "views/all"; +@import "components/all"; +@import "print"; +@import "mixins"; + +#app { + height: 100%; +} + +#main { + height: 100%; +} + +.page-header { + margin: 20px 0; +} + +.nowrap { + white-space: nowrap; +} + +.spinner-container { + text-align: center; + padding: 0.5rem 0; +} + +.spinner { + display: inline-block; + vertical-align: baseline; + width: 24px; + height: 24px; + animation: rotate 0.8s infinite linear; + border: 2px solid #2e6da4; + border-right-color: transparent !important; + border-radius: 50%; + margin-bottom: -2px; +} + +html { + font-size: 14px; +} + +button { + .spinner { + margin-left: 10px; + width: 14px; + height: 14px; + } + + &.btn-primary { + .spinner { + border-color: white; + } + } +} + +th { + text-align: left; +} + +@keyframes rotate { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +a.light { + color: grey; +} + +// Bootstrap overrides + +.alert-success { + @include flex; + align-items: center; + margin-top: 30px; + + &:before { + content: ""; + } + + .btn { + margin-left: auto; + } +} + +.alert-warning { + &:before { + content: ""; + } +} + +// Spacing + +.nopadding { + padding: 0 !important; +} + +.mr-5 { + margin-right: 5px; +} + +.ml-5 { + margin-left: 5px; +} + +// Spacing End + +.row.equal-height { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + flex-wrap: wrap; +} + +.text-label { + font-weight: bold; + margin: 5px 0; +} + +#confirm-dialog .timer { + margin-left: 3px; + font-weight: bold; +} + +// Fix for extra dark overlay when multiple modals are open +[aria-hidden="true"] .modal-backdrop.in { + opacity: 0; +} diff --git a/client2/src/sass/mixins.scss b/client2/src/sass/mixins.scss new file mode 100644 index 000000000..49fd76c8e --- /dev/null +++ b/client2/src/sass/mixins.scss @@ -0,0 +1,7 @@ +@mixin flex { + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} diff --git a/client2/src/sass/print.scss b/client2/src/sass/print.scss new file mode 100644 index 000000000..07ae5dddd --- /dev/null +++ b/client2/src/sass/print.scss @@ -0,0 +1,155 @@ +@page { + margin: 10mm 5mm; +} + +@media print { + .watermark { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + font-size: 72px; + font-weight: bold; + color: hsl(0, 0, 90%) !important; + -webkit-print-color-adjust: exact !important; + color-adjust: exact !important; + z-index: -1; + } + + .search-bar, + .history, + .btn-group, + .btn, + .checkbox, + .checkbox-control { + display: none; + } + + h1 { + font-size: 18px; + } + + h2 { + font-size: 16px; + } + + h3 { + font-size: 14px; + } + + h4 { + font-size: 12px; + } + + a { + text-decoration: none !important; + } + + .template { + margin: 0; + width: 100%; + font-size: 10px; + } + + @for $i from 1 through 12 { + .col-sm-#{$i} { + float: left; + width: #{percentage(round($i * 8.33) / 100)}; + } + } + + .row { + padding-top: 0.5em; + padding-bottom: 0.5em; + } + + .well { + padding: 10px; + } + + #rental-requests-detail { + .well { + padding: 0; + border: none; + } + + .request-information { + margin-top: 0; + } + + #rental-requests-data { + font-size: 8px; + line-height: 1; + + > div { + width: 35%; + } + + > div:nth-child(even) { + margin-left: 30%; + } + } + + #rotation-list { + font-size: 8px; + } + + @supports (size: landscape) { + #rotation-list { + font-size: 10px; + } + } + + /* override bootstrap's white background so watermark can be seen clearly */ + td, th { + background: transparent !important; + } + } + + div.row { + margin: 0 -15px; + } + + .col-md-6 { + float: initial; + } + + #rotation-list { + th, td { + padding: 2px; + } + + th span { + display: block; + } + + td { + word-break: break-all; + } + + th:first-child, td:first-child, th:nth-child(10), td:nth-child(10) { + display: none; + } + + th:nth-child(2), td:nth-child(2), th:last-child, td:last-child { + display: table-cell !important; + } + + th:last-child, td:last-child { + min-width: 150px; + } + } + + .row:after { + margin-bottom: -25px; + } + + [class*='col-']:last-child .row:after { + margin-bottom: 0; + } + + div#history-list { + max-height: none; + } +} diff --git a/client2/src/sass/variables.scss b/client2/src/sass/variables.scss new file mode 100644 index 000000000..9038ea3d3 --- /dev/null +++ b/client2/src/sass/variables.scss @@ -0,0 +1,13 @@ +// Small tablets and large smartphones (landscape view) +$screen-sm: 576px; + +// Small tablets (portrait view) +$screen-md: 768px; + +// Tablets and small desktops +$screen-lg: 990px; + +// Large tablets and desktops +$screen-xl: 1200px; + +$footer-height: 45px; diff --git a/client2/src/sass/views/all.scss b/client2/src/sass/views/all.scss new file mode 100644 index 000000000..e2dc1bbb7 --- /dev/null +++ b/client2/src/sass/views/all.scss @@ -0,0 +1,12 @@ +@import './dialogs/all'; +@import './business-portal'; +@import './district-admin'; +@import './equipment-list'; +@import './home'; +@import './owners'; +@import './projects'; +@import './rental-agreements'; +@import './rental-requests'; +@import './roles'; +@import './rollover'; +@import './users'; diff --git a/client2/src/sass/views/business-portal.scss b/client2/src/sass/views/business-portal.scss new file mode 100644 index 000000000..3e050e3cc --- /dev/null +++ b/client2/src/sass/views/business-portal.scss @@ -0,0 +1,32 @@ +#business-portal { + #hets-logo { + float: left; + margin-right: 20px; + margin-bottom: 15px; + width: 218px; + height: 109px; + } + + #associate-owner { + a { + font-weight: 700; + } + + input#secretKey { + width: 250px; + } + + input#postalCode { + width: 120px; + } + + button { + vertical-align: top; + } + + .validation-error { + margin-top: 1em; + color: #a94442; + } + } +} diff --git a/client2/src/sass/views/dialogs/all.scss b/client2/src/sass/views/dialogs/all.scss new file mode 100644 index 000000000..60b72baa0 --- /dev/null +++ b/client2/src/sass/views/dialogs/all.scss @@ -0,0 +1,6 @@ +@import "./contacts-edit"; +@import "./documents-list"; +@import "./equipment-transfer"; +@import "./rental-rates-edit"; +@import "./notes"; +@import "./error-dialog"; diff --git a/client2/src/sass/views/dialogs/contacts-edit.scss b/client2/src/sass/views/dialogs/contacts-edit.scss new file mode 100644 index 000000000..b21ebee12 --- /dev/null +++ b/client2/src/sass/views/dialogs/contacts-edit.scss @@ -0,0 +1,14 @@ +#contacts-edit { + #notes { + height: 106px; + } + + .modal-title .label { + font-size: 100%; + margin-left: 20px; + } + + .modal-title .btn { + margin-left: 20px; + } +} diff --git a/client2/src/sass/views/dialogs/documents-list.scss b/client2/src/sass/views/dialogs/documents-list.scss new file mode 100644 index 000000000..8a8b1a59d --- /dev/null +++ b/client2/src/sass/views/dialogs/documents-list.scss @@ -0,0 +1,19 @@ +#documents-dialog { + .alert { + margin-top: 10px; + + .btn { + float: right; + margin-top: -7px; + } + } + + .file-picker-container { + text-align: center; + padding: 0 15px 15px 15px; + } + + .file-picker { + margin-bottom: 10px; + } +} diff --git a/client2/src/sass/views/dialogs/equipment-transfer.scss b/client2/src/sass/views/dialogs/equipment-transfer.scss new file mode 100644 index 000000000..b23e3bb84 --- /dev/null +++ b/client2/src/sass/views/dialogs/equipment-transfer.scss @@ -0,0 +1,16 @@ +#equipment-transfer { + #select-equipment { + .checkbox { + margin: 0; + text-align: center; + } + + tr th:first-child .checkbox { + margin-bottom: -2px; + + label { + font-weight: bold; + } + } + } +} diff --git a/client2/src/sass/views/dialogs/error-dialog.scss b/client2/src/sass/views/dialogs/error-dialog.scss new file mode 100644 index 000000000..725703957 --- /dev/null +++ b/client2/src/sass/views/dialogs/error-dialog.scss @@ -0,0 +1,28 @@ +#error-dialog { + #error-message { + font-size: 200%; + } + + #api-error { + margin-top: 2em; + + p { + font-size: 110%; + } + + #api-url-path { + color: #286498; + } + + #api-http-status { + color: #A43737; + } + + #api-error-response { + p { + margin-bottom: 0; + font-weight: bold; + } + } + } +} diff --git a/client2/src/sass/views/dialogs/notes.scss b/client2/src/sass/views/dialogs/notes.scss new file mode 100644 index 000000000..ce10d37e1 --- /dev/null +++ b/client2/src/sass/views/dialogs/notes.scss @@ -0,0 +1,9 @@ +#notes-list { + max-height: 200px; + overflow: auto; + margin-bottom: 20px; + + table { + margin-top: 0; + } +} diff --git a/client2/src/sass/views/dialogs/rental-rates-edit.scss b/client2/src/sass/views/dialogs/rental-rates-edit.scss new file mode 100644 index 000000000..a7ee111db --- /dev/null +++ b/client2/src/sass/views/dialogs/rental-rates-edit.scss @@ -0,0 +1,30 @@ +#rental-rates-edit, #rental-conditions-edit { + + #dollar-value { + padding-right: 10px; + overflow: hidden; + text-align: right; + text-overflow: ellipsis; + } + + .forms-container { + .form-item { + border-bottom: 1px solid #ccc; + padding-bottom: 15px; + margin-bottom: 30px; + + &:last-child { + border-bottom: none; + margin-bottom: 0; + } + } + } + + .align-right { + text-align: right; + } + + .remove-btn { + margin-right: 5px; + } +} diff --git a/client2/src/sass/views/district-admin.scss b/client2/src/sass/views/district-admin.scss new file mode 100644 index 000000000..c0945e21a --- /dev/null +++ b/client2/src/sass/views/district-admin.scss @@ -0,0 +1,2 @@ +#district-admin { +} diff --git a/client2/src/sass/views/equipment-list.scss b/client2/src/sass/views/equipment-list.scss new file mode 100644 index 000000000..b20b01be4 --- /dev/null +++ b/client2/src/sass/views/equipment-list.scss @@ -0,0 +1,69 @@ +@import '../mixins'; +@import '../variables'; + +#equipment-list { + .search-bar #filters { + .btn-group { + width: calc(100% / 5); + min-width: 150px; + } + + .btn-group .btn { + width: 100%; + max-width: 100%; + } + } +} + +#equipment-detail { + .top-container { + margin: 0 5px; + } + + #equipment-bottom { + margin: 15px 0; + } + + .equipment-header { + margin-bottom: 15px; + } + + .well { + margin-left: 5px; + margin-right: 5px; + } + + .label { + font-size: 100%; + margin-right: 5px; + } + + .checkbox { + margin-top: 0; + margin-bottom: 0; + height: 16px; + } + + .btn-group > .btn + .btn { + margin-left: -1px; + } +} + +#equipment-add, +#equipment-edit { + h4 strong span { + margin-left: 20px; + } + + .form-group { + h4 { + margin: 0; + } + } +} + +#seniority-edit { + h4 strong span { + margin-left: 20px; + } +} diff --git a/client2/src/sass/views/home.scss b/client2/src/sass/views/home.scss new file mode 100644 index 000000000..d8e09afe2 --- /dev/null +++ b/client2/src/sass/views/home.scss @@ -0,0 +1,31 @@ +@import "../variables.scss"; + +#home_image { + height: 200px; +} + +#home { + .fixed-width { + &.small .dropdown-toggle { + width: 125px; + } + + .dropdown-toggle { + width: 150px; + } + } + + .btn { + margin-right: 5px; + } + + .rotation-list-form { + text-align: right; + } + + @media only screen and (max-width: $screen-lg) { + .rotation-list-form { + text-align: left; + } + } +} diff --git a/client2/src/sass/views/owners.scss b/client2/src/sass/views/owners.scss new file mode 100644 index 000000000..aa7bbacd4 --- /dev/null +++ b/client2/src/sass/views/owners.scss @@ -0,0 +1,87 @@ +#owners-detail { + #owners-top { + margin: 0 5px 10px 5px; + + #owner-notes-button, #owner-documents-button { + margin-left: 5px; + } + } + + #owners-header { + margin-left: 5px; + margin-right: 5px; + } + + #owners-data { + .checkbox { + margin-top: 0; + margin-bottom: 0; + height: 16px; + } + } + + #contact-list { + max-height: 150px; + width: 100%; + overflow-y: auto; + margin-bottom: 10px; + + table { + margin: 0; + } + + th, td { + max-width: 125px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + + #equipment-list { + td:nth-child(4) { + width: 350px; + } + + .attachment { + display: inline-block; + } + } + + .well { + margin-left: 5px; + margin-right: 5px; + } + + .label { + font-size: 100%; + margin: 6px 5px; + display: inline-block; + } + + .col-display-label { + width: 170px; + } + + .alert { + margin-top: 10px; + + .btn { + float: right; + } + } + + h1 { + small { + font-size: 85%; + } + } +} + +#owners-edit { + .form-group { + h4 { + margin: 0; + } + } +} diff --git a/client2/src/sass/views/projects.scss b/client2/src/sass/views/projects.scss new file mode 100644 index 000000000..16171d5a3 --- /dev/null +++ b/client2/src/sass/views/projects.scss @@ -0,0 +1,94 @@ +#projects-detail { + .top-container { + margin: 0 5px; + } + + #projects-top { + margin-bottom: 10px; + } + + #equipment-list { + overflow-y: auto; + width: 100%; + max-height: 400px; + margin-top: 20px; + } + + .well { + margin-left: 5px; + margin-right: 5px; + } + + .label { + font-size: 100%; + margin-right: 5px; + } + + #add-request-button { + margin-left: 20px; + } +} + +#contact-list { + max-height: 150px; + width: 100%; + overflow-y: auto; + margin-bottom: 10px; + + table { + margin: 0; + } + + th, td { + max-width: 125px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .btn { + margin-left: 0; + } + +} + +#projects-edit { + textarea { + resize: vertical; + } +} + +#time-entry { + .remove-btn { + margin-left: 5px; + } + + .column-title { + margin-bottom: 5px; + font-weight: bold; + } + + .time-records-list { + padding: 0; + list-style: none; + max-height: 100px; + overflow: auto; + + .list-item { + margin: 5px 0; + } + } + + .time-entries-container { + margin: 30px 0 5px 0; + } + + .highlight { + font-weight: bold; + color: red; + } + + .small-text { + font-size: 10px; + } +} diff --git a/client2/src/sass/views/rental-agreements.scss b/client2/src/sass/views/rental-agreements.scss new file mode 100644 index 000000000..732dc4ca7 --- /dev/null +++ b/client2/src/sass/views/rental-agreements.scss @@ -0,0 +1,60 @@ +#rental-agreements-detail { + #rental-agreements-top { + margin-bottom: 10px; + } + + #rental-agreements-top, #rental-agreements-footer { + .btn { + margin-left: 5px; + } + } + + #rental-agreement-header { + min-height: 169px; + } + + #rental-agreements-note { + margin: 10px 0; + } + + #overtime-rates { + .overtime-rate { + margin-right: 20px; + } + } + + .label { + font-size: 100%; + margin-right: 5px; + } + + .no-margin { + margin: 0; + } + + .rental-rates { + position: relative; + + .edit-rate-btn { + position: absolute; + right: 0; + top: 0; + } + } +} + +#rental-agreements-overtime-notes-edit { + #overtime-rate-edit { + padding-bottom: 10px; + border-bottom: 1px solid #e5e5e5; + + .checkbox-control { + display: inline-block; + margin-right: 20px; + } + } + + #note-edit { + margin-top: 20px; + } +} diff --git a/client2/src/sass/views/rental-requests.scss b/client2/src/sass/views/rental-requests.scss new file mode 100644 index 000000000..0b5643c11 --- /dev/null +++ b/client2/src/sass/views/rental-requests.scss @@ -0,0 +1,86 @@ +#rental-requests-list { + #add-request-buttons { + margin-left: auto; + + .btn { + display: block; + width: 100%; + } + + .btn:first-child { + margin-bottom: 10px; + } + } +} + +#rental-requests-detail { + #rental-requests-top { + margin-bottom: 10px; + + .btn { + margin-left: 5px; + } + } + + #rental-request-status { + float: left; + min-width: 100px; + padding-top: 7px; + } + + #rotation-list { + width: 100%; + overflow-y: auto; + } + + .request-information { + margin-top: 20px; + } + + .label { + font-size: 100%; + margin-right: 5px; + } + + .btn, .checkbox-control { + margin-left: 20px; + } + + #rotation-list { + .btn-link { + padding: 0; + margin: 0; + } + + th:nth-child(2), td:nth-child(2), th:nth-child(11), td:nth-child(11) { + display: none; + } + + td:nth-child(5) { + width: 250px; + } + + // tr.blank-row {} + + .attachment { + display: inline-block; + } + } +} + +#hire-offer-edit { + input[type='number'] { + width: auto; + min-width: 175px; + } + + .spinner-container { + height: 24px; + } +} + +#confirm-dialog, #hire-offer-edit { + &.modal { + z-index: 1040; + } +} diff --git a/client2/src/sass/views/roles.scss b/client2/src/sass/views/roles.scss new file mode 100644 index 000000000..c6c739ac3 --- /dev/null +++ b/client2/src/sass/views/roles.scss @@ -0,0 +1,42 @@ +#roles-list { + #roles-filters { + .search-control { + width: 350px; + margin-left: 5px; + } + } + + .alert .btn { + float: right; + } +} + +#roles-detail { + #roles-top { + margin-bottom: 10px; + text-align: right; + } + + #roles-permissions { + table { + font-size: 92%; + + tr { + cursor: pointer; + + &.selected { + background-color: #217AFF; + color: white; + } + } + } + } +} + +#roles-edit { + .container-fluid { + padding-left: 0; + padding-right: 0; + margin-left: -7px; + } +} diff --git a/client2/src/sass/views/rollover.scss b/client2/src/sass/views/rollover.scss new file mode 100644 index 000000000..c5c763c7e --- /dev/null +++ b/client2/src/sass/views/rollover.scss @@ -0,0 +1,13 @@ +#roll-over { + .progress { + margin: 10px 0; + } + + #checklist { + margin: 20px 0; + } + + #description { + margin: 20px 0; + } +} diff --git a/client2/src/sass/views/users.scss b/client2/src/sass/views/users.scss new file mode 100644 index 000000000..5459c5d62 --- /dev/null +++ b/client2/src/sass/views/users.scss @@ -0,0 +1,48 @@ +#users-detail { + #users-top { + margin-bottom: 10px; + } + + #users-access { + .checkbox-control { + float: right; + font-size: 14px; + } + + input { + margin-top: 0; + } + } + + .well { + margin-left: 5px; + margin-right: 5px; + } + + .label { + font-size: 100%; + margin-right: 5px; + } + + .checkbox { + margin-top: 0; + margin-bottom: 0; + height: 16px; + } + + .col-display-label { + width: 100px; + } + + .alert { + .btn { + float: right; + } + } +} + +#users-role-popover { + .date-control { + margin-right: 10px; + } +} diff --git a/client2/src/setupProxy.js b/client2/src/setupProxy.js new file mode 100644 index 000000000..6350bf763 --- /dev/null +++ b/client2/src/setupProxy.js @@ -0,0 +1,12 @@ +const { createProxyMiddleware } = require("http-proxy-middleware"); + +module.exports = function (app) { + debugger; + app.use( + "/api", + createProxyMiddleware({ + target: process.env.REACT_APP_API_HOST || "http://localhost:27238", + changeOrigin: true, + }) + ); +}; diff --git a/client2/src/setupTests.js b/client2/src/setupTests.js new file mode 100644 index 000000000..8f2609b7b --- /dev/null +++ b/client2/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; From 1d26ddeb704415253ae1fe8feead3dc728204fc1 Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Thu, 3 Jun 2021 15:52:56 -0700 Subject: [PATCH 012/352] converting to CRA --- client/.dockerignore | 2 - client/.eslintrc.json | 60 - client/.gitattributes | 2 - client/.gitignore | 3 - client/.vscode/settings.json | 18 - client/Dockerfile | 17 - client/README.md | 107 - client/babel.config.js | 31 - client/build.bat | 10 - client/gulp.bat | 2 - client/gulpfile.js | 257 - client/nginx-start/start.sh | 13 - client/nginx.conf.tmpl | 100 - client/package-lock.json | 12189 ---------------- client/package.json | 103 - client/server/main.js | 85 - client/server/toxy-proxy.js | 49 - client/src/Web.config | 25 - client/src/html/buildinfo.hbs | 28 - client/src/html/index.hbs | 36 - client/src/images/blueline.png | Bin 158 -> 0 bytes client/src/images/gov/bceid_logo.png | Bin 2637 -> 0 bytes client/src/images/gov/favicon.png | Bin 11639 -> 0 bytes client/src/images/gov/gov3_bc_logo.png | Bin 3881 -> 0 bytes client/src/images/gov/hets.jpg | Bin 68151 -> 0 bytes client/src/images/greyline.png | Bin 158 -> 0 bytes client/src/js/App.jsx | 201 - client/src/js/actionTypes.js | 228 - client/src/js/actions.js | 39 - client/src/js/api.js | 2360 --- client/src/js/components/Authorize.jsx | 29 - client/src/js/components/BadgeLabel.jsx | 22 - client/src/js/components/CheckboxControl.jsx | 37 - client/src/js/components/ColDisplay.jsx | 30 - client/src/js/components/Confirm.jsx | 42 - client/src/js/components/Countdown.jsx | 58 - client/src/js/components/DateControl.jsx | 86 - client/src/js/components/DeleteButton.jsx | 27 - client/src/js/components/DropdownControl.jsx | 158 - client/src/js/components/EditButton.jsx | 29 - client/src/js/components/Favourites.jsx | 225 - client/src/js/components/FileAttachDialog.jsx | 84 - client/src/js/components/FilePicker.jsx | 37 - client/src/js/components/FileUpload.jsx | 105 - client/src/js/components/FilterDropdown.jsx | 187 - client/src/js/components/Form.jsx | 27 - client/src/js/components/FormDialog.jsx | 84 - client/src/js/components/FormInputControl.jsx | 76 - client/src/js/components/History.jsx | 155 - client/src/js/components/LinkControl.jsx | 68 - client/src/js/components/Mailto.jsx | 36 - client/src/js/components/ModalDialog.jsx | 39 - client/src/js/components/MultiDropdown.jsx | 182 - client/src/js/components/OverlayTrigger.jsx | 29 - client/src/js/components/PageOrientation.jsx | 22 - client/src/js/components/PrintButton.jsx | 45 - client/src/js/components/ReturnButton.jsx | 31 - client/src/js/components/RootCloseMenu.jsx | 24 - client/src/js/components/SearchControl.jsx | 78 - client/src/js/components/SortTable.jsx | 85 - client/src/js/components/Spinner.jsx | 35 - client/src/js/components/StatusDropdown.jsx | 77 - client/src/js/components/TableControl.jsx | 35 - client/src/js/components/TooltipButton.jsx | 49 - client/src/js/components/Unimplemented.jsx | 21 - client/src/js/components/Watermark.jsx | 24 - .../js/components/ui/AddButtonContainer.jsx | 20 - client/src/js/components/ui/PageHeader.jsx | 29 - client/src/js/components/ui/SearchBar.jsx | 22 - client/src/js/components/ui/SubHeader.jsx | 66 - client/src/js/constants.js | 142 - client/src/js/history.js | 328 - client/src/js/init.js | 115 - client/src/js/reducers/all.js | 18 - client/src/js/reducers/lookups.js | 205 - client/src/js/reducers/models.js | 605 - client/src/js/reducers/search.js | 50 - client/src/js/reducers/ui.js | 142 - client/src/js/reducers/user.js | 17 - client/src/js/reducers/version.js | 19 - client/src/js/selectors/history-selectors.js | 37 - client/src/js/selectors/ui-selectors.js | 64 - client/src/js/store.js | 40 - client/src/js/utils/array.js | 35 - client/src/js/utils/date.js | 124 - client/src/js/utils/http.js | 241 - client/src/js/utils/routes.js | 11 - client/src/js/utils/string.js | 83 - client/src/js/utils/string_test.js | 25 - client/src/js/views/404.jsx | 26 - client/src/js/views/AitReport.jsx | 419 - client/src/js/views/BusinessOwner.jsx | 304 - client/src/js/views/BusinessPortal.jsx | 221 - client/src/js/views/DistrictAdmin.jsx | 295 - client/src/js/views/Equipment.jsx | 307 - client/src/js/views/EquipmentDetail.jsx | 543 - client/src/js/views/EquipmentTable.jsx | 82 - client/src/js/views/Footer.jsx | 43 - client/src/js/views/HiringReport.jsx | 339 - client/src/js/views/Home.jsx | 106 - client/src/js/views/Main.jsx | 106 - client/src/js/views/OvertimeRates.jsx | 116 - client/src/js/views/Owners.jsx | 260 - client/src/js/views/OwnersDetail.jsx | 988 -- client/src/js/views/Projects.jsx | 267 - client/src/js/views/ProjectsDetail.jsx | 584 - .../src/js/views/RentalAgreementsDetail.jsx | 522 - client/src/js/views/RentalRequests.jsx | 384 - client/src/js/views/RentalRequestsDetail.jsx | 483 - client/src/js/views/Roles.jsx | 171 - client/src/js/views/RolesDetail.jsx | 266 - client/src/js/views/Rollover.jsx | 188 - client/src/js/views/SeniorityList.jsx | 133 - client/src/js/views/StatusLetters.jsx | 153 - client/src/js/views/TimeEntry.jsx | 381 - client/src/js/views/TopNav.jsx | 211 - client/src/js/views/Users.jsx | 273 - client/src/js/views/UsersDetail.jsx | 450 - client/src/js/views/Version.jsx | 146 - client/src/js/views/WcbCglCoverage.jsx | 288 - .../js/views/dialogs/AttachmentAddDialog.jsx | 153 - .../js/views/dialogs/AttachmentEditDialog.jsx | 102 - client/src/js/views/dialogs/CloneDialog.jsx | 184 - .../views/dialogs/ConditionAddEditDialog.jsx | 139 - client/src/js/views/dialogs/ConfirmDialog.jsx | 33 - .../views/dialogs/ConfirmForceHireDialog.jsx | 86 - .../js/views/dialogs/ContactsEditDialog.jsx | 273 - .../js/views/dialogs/DistrictEditDialog.jsx | 128 - .../DistrictEquipmentTypeAddEditDialog.jsx | 154 - .../js/views/dialogs/DocumentsListDialog.jsx | 217 - .../js/views/dialogs/EquipmentAddDialog.jsx | 308 - .../dialogs/EquipmentChangeStatusDialog.jsx | 98 - .../js/views/dialogs/EquipmentEditDialog.jsx | 382 - .../EquipmentRentalRatesEditDialog.jsx | 134 - .../views/dialogs/EquipmentTransferDialog.jsx | 312 - client/src/js/views/dialogs/ErrorDialog.jsx | 123 - .../js/views/dialogs/HireOfferEditDialog.jsx | 354 - .../src/js/views/dialogs/NotesAddDialog.jsx | 106 - client/src/js/views/dialogs/NotesDialog.jsx | 156 - .../views/dialogs/OvertimeRateEditDialog.jsx | 138 - .../views/dialogs/OwnerChangeStatusDialog.jsx | 160 - .../src/js/views/dialogs/OwnersAddDialog.jsx | 378 - .../src/js/views/dialogs/OwnersEditDialog.jsx | 267 - .../views/dialogs/OwnersPolicyEditDialog.jsx | 158 - .../js/views/dialogs/ProjectsAddDialog.jsx | 266 - .../js/views/dialogs/ProjectsEditDialog.jsx | 267 - .../RentalAgreementOvertimeNotesDialog.jsx | 109 - .../dialogs/RentalAgreementsEditDialog.jsx | 150 - .../dialogs/RentalConditionsEditDialog.jsx | 210 - .../views/dialogs/RentalRatesEditDialog.jsx | 258 - .../views/dialogs/RentalRequestsAddDialog.jsx | 336 - .../dialogs/RentalRequestsEditDialog.jsx | 175 - .../js/views/dialogs/SeniorityEditDialog.jsx | 230 - .../src/js/views/dialogs/TimeEntryDialog.jsx | 555 - .../js/views/dialogs/UserRoleAddDialog.jsx | 178 - .../src/js/views/dialogs/UsersEditDialog.jsx | 227 - client/src/robots.txt | 2 - client/src/sass/components/all.scss | 21 - client/src/sass/components/badge-label.scss | 5 - client/src/sass/components/clone-dialog.scss | 18 - client/src/sass/components/date-control.scss | 38 - .../src/sass/components/dropdown-control.scss | 72 - client/src/sass/components/favourites.scss | 40 - client/src/sass/components/file-upload.scss | 73 - .../src/sass/components/filter-dropdown.scss | 104 - client/src/sass/components/form-dialog.scss | 18 - .../sass/components/form-input-control.scss | 0 client/src/sass/components/history.scss | 18 - client/src/sass/components/link-control.scss | 8 - .../src/sass/components/multi-dropdown.scss | 96 - client/src/sass/components/print-button.scss | 7 - client/src/sass/components/return-button.scss | 8 - .../src/sass/components/search-control.scss | 11 - client/src/sass/components/sort-table.scss | 30 - .../components/ui/add-button-container.scss | 4 - .../src/sass/components/ui/page-header.scss | 13 - client/src/sass/components/ui/search-bar.scss | 38 - client/src/sass/components/ui/subheader.scss | 3 - client/src/sass/gov3.scss | 2259 --- client/src/sass/header.scss | 213 - client/src/sass/init.scss | 37 - client/src/sass/main.scss | 132 - client/src/sass/mixins.scss | 7 - client/src/sass/print.scss | 155 - client/src/sass/variables.scss | 13 - client/src/sass/views/all.scss | 12 - client/src/sass/views/business-portal.scss | 32 - client/src/sass/views/dialogs/all.scss | 6 - .../src/sass/views/dialogs/contacts-edit.scss | 14 - .../sass/views/dialogs/documents-list.scss | 19 - .../views/dialogs/equipment-transfer.scss | 16 - .../src/sass/views/dialogs/error-dialog.scss | 28 - client/src/sass/views/dialogs/notes.scss | 9 - .../sass/views/dialogs/rental-rates-edit.scss | 30 - client/src/sass/views/district-admin.scss | 2 - client/src/sass/views/equipment-list.scss | 69 - client/src/sass/views/home.scss | 31 - client/src/sass/views/owners.scss | 87 - client/src/sass/views/projects.scss | 94 - client/src/sass/views/rental-agreements.scss | 60 - client/src/sass/views/rental-requests.scss | 86 - client/src/sass/views/roles.scss | 42 - client/src/sass/views/rollover.scss | 13 - client/src/sass/views/users.scss | 48 - client/test/index.html | 49 - client/test/spec/load.js | 13 - client/typings/node/node.d.ts | 2161 --- client/webpack.config.js | 100 - 208 files changed, 43804 deletions(-) delete mode 100644 client/.dockerignore delete mode 100644 client/.eslintrc.json delete mode 100644 client/.gitattributes delete mode 100644 client/.gitignore delete mode 100644 client/.vscode/settings.json delete mode 100644 client/Dockerfile delete mode 100644 client/README.md delete mode 100755 client/babel.config.js delete mode 100644 client/build.bat delete mode 100644 client/gulp.bat delete mode 100644 client/gulpfile.js delete mode 100644 client/nginx-start/start.sh delete mode 100644 client/nginx.conf.tmpl delete mode 100644 client/package-lock.json delete mode 100644 client/package.json delete mode 100755 client/server/main.js delete mode 100755 client/server/toxy-proxy.js delete mode 100644 client/src/Web.config delete mode 100644 client/src/html/buildinfo.hbs delete mode 100644 client/src/html/index.hbs delete mode 100644 client/src/images/blueline.png delete mode 100644 client/src/images/gov/bceid_logo.png delete mode 100644 client/src/images/gov/favicon.png delete mode 100644 client/src/images/gov/gov3_bc_logo.png delete mode 100644 client/src/images/gov/hets.jpg delete mode 100644 client/src/images/greyline.png delete mode 100644 client/src/js/App.jsx delete mode 100644 client/src/js/actionTypes.js delete mode 100644 client/src/js/actions.js delete mode 100644 client/src/js/api.js delete mode 100644 client/src/js/components/Authorize.jsx delete mode 100644 client/src/js/components/BadgeLabel.jsx delete mode 100644 client/src/js/components/CheckboxControl.jsx delete mode 100644 client/src/js/components/ColDisplay.jsx delete mode 100644 client/src/js/components/Confirm.jsx delete mode 100644 client/src/js/components/Countdown.jsx delete mode 100644 client/src/js/components/DateControl.jsx delete mode 100644 client/src/js/components/DeleteButton.jsx delete mode 100644 client/src/js/components/DropdownControl.jsx delete mode 100644 client/src/js/components/EditButton.jsx delete mode 100644 client/src/js/components/Favourites.jsx delete mode 100644 client/src/js/components/FileAttachDialog.jsx delete mode 100644 client/src/js/components/FilePicker.jsx delete mode 100644 client/src/js/components/FileUpload.jsx delete mode 100644 client/src/js/components/FilterDropdown.jsx delete mode 100644 client/src/js/components/Form.jsx delete mode 100644 client/src/js/components/FormDialog.jsx delete mode 100644 client/src/js/components/FormInputControl.jsx delete mode 100644 client/src/js/components/History.jsx delete mode 100644 client/src/js/components/LinkControl.jsx delete mode 100644 client/src/js/components/Mailto.jsx delete mode 100644 client/src/js/components/ModalDialog.jsx delete mode 100644 client/src/js/components/MultiDropdown.jsx delete mode 100644 client/src/js/components/OverlayTrigger.jsx delete mode 100644 client/src/js/components/PageOrientation.jsx delete mode 100644 client/src/js/components/PrintButton.jsx delete mode 100644 client/src/js/components/ReturnButton.jsx delete mode 100644 client/src/js/components/RootCloseMenu.jsx delete mode 100644 client/src/js/components/SearchControl.jsx delete mode 100644 client/src/js/components/SortTable.jsx delete mode 100644 client/src/js/components/Spinner.jsx delete mode 100644 client/src/js/components/StatusDropdown.jsx delete mode 100644 client/src/js/components/TableControl.jsx delete mode 100644 client/src/js/components/TooltipButton.jsx delete mode 100644 client/src/js/components/Unimplemented.jsx delete mode 100644 client/src/js/components/Watermark.jsx delete mode 100644 client/src/js/components/ui/AddButtonContainer.jsx delete mode 100644 client/src/js/components/ui/PageHeader.jsx delete mode 100644 client/src/js/components/ui/SearchBar.jsx delete mode 100644 client/src/js/components/ui/SubHeader.jsx delete mode 100644 client/src/js/constants.js delete mode 100644 client/src/js/history.js delete mode 100644 client/src/js/init.js delete mode 100644 client/src/js/reducers/all.js delete mode 100644 client/src/js/reducers/lookups.js delete mode 100644 client/src/js/reducers/models.js delete mode 100644 client/src/js/reducers/search.js delete mode 100644 client/src/js/reducers/ui.js delete mode 100644 client/src/js/reducers/user.js delete mode 100644 client/src/js/reducers/version.js delete mode 100644 client/src/js/selectors/history-selectors.js delete mode 100644 client/src/js/selectors/ui-selectors.js delete mode 100644 client/src/js/store.js delete mode 100644 client/src/js/utils/array.js delete mode 100644 client/src/js/utils/date.js delete mode 100644 client/src/js/utils/http.js delete mode 100644 client/src/js/utils/routes.js delete mode 100644 client/src/js/utils/string.js delete mode 100644 client/src/js/utils/string_test.js delete mode 100644 client/src/js/views/404.jsx delete mode 100644 client/src/js/views/AitReport.jsx delete mode 100644 client/src/js/views/BusinessOwner.jsx delete mode 100644 client/src/js/views/BusinessPortal.jsx delete mode 100644 client/src/js/views/DistrictAdmin.jsx delete mode 100644 client/src/js/views/Equipment.jsx delete mode 100644 client/src/js/views/EquipmentDetail.jsx delete mode 100644 client/src/js/views/EquipmentTable.jsx delete mode 100644 client/src/js/views/Footer.jsx delete mode 100644 client/src/js/views/HiringReport.jsx delete mode 100644 client/src/js/views/Home.jsx delete mode 100644 client/src/js/views/Main.jsx delete mode 100644 client/src/js/views/OvertimeRates.jsx delete mode 100644 client/src/js/views/Owners.jsx delete mode 100644 client/src/js/views/OwnersDetail.jsx delete mode 100644 client/src/js/views/Projects.jsx delete mode 100644 client/src/js/views/ProjectsDetail.jsx delete mode 100644 client/src/js/views/RentalAgreementsDetail.jsx delete mode 100644 client/src/js/views/RentalRequests.jsx delete mode 100644 client/src/js/views/RentalRequestsDetail.jsx delete mode 100644 client/src/js/views/Roles.jsx delete mode 100644 client/src/js/views/RolesDetail.jsx delete mode 100644 client/src/js/views/Rollover.jsx delete mode 100644 client/src/js/views/SeniorityList.jsx delete mode 100644 client/src/js/views/StatusLetters.jsx delete mode 100644 client/src/js/views/TimeEntry.jsx delete mode 100644 client/src/js/views/TopNav.jsx delete mode 100644 client/src/js/views/Users.jsx delete mode 100644 client/src/js/views/UsersDetail.jsx delete mode 100644 client/src/js/views/Version.jsx delete mode 100644 client/src/js/views/WcbCglCoverage.jsx delete mode 100644 client/src/js/views/dialogs/AttachmentAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/AttachmentEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/CloneDialog.jsx delete mode 100644 client/src/js/views/dialogs/ConditionAddEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/ConfirmDialog.jsx delete mode 100644 client/src/js/views/dialogs/ConfirmForceHireDialog.jsx delete mode 100644 client/src/js/views/dialogs/ContactsEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/DistrictEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/DocumentsListDialog.jsx delete mode 100644 client/src/js/views/dialogs/EquipmentAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx delete mode 100644 client/src/js/views/dialogs/EquipmentEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/EquipmentTransferDialog.jsx delete mode 100644 client/src/js/views/dialogs/ErrorDialog.jsx delete mode 100644 client/src/js/views/dialogs/HireOfferEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/NotesAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/NotesDialog.jsx delete mode 100644 client/src/js/views/dialogs/OvertimeRateEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx delete mode 100644 client/src/js/views/dialogs/OwnersAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/OwnersEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/ProjectsAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/ProjectsEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalConditionsEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalRatesEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalRequestsAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/RentalRequestsEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/SeniorityEditDialog.jsx delete mode 100644 client/src/js/views/dialogs/TimeEntryDialog.jsx delete mode 100644 client/src/js/views/dialogs/UserRoleAddDialog.jsx delete mode 100644 client/src/js/views/dialogs/UsersEditDialog.jsx delete mode 100644 client/src/robots.txt delete mode 100644 client/src/sass/components/all.scss delete mode 100644 client/src/sass/components/badge-label.scss delete mode 100644 client/src/sass/components/clone-dialog.scss delete mode 100644 client/src/sass/components/date-control.scss delete mode 100644 client/src/sass/components/dropdown-control.scss delete mode 100644 client/src/sass/components/favourites.scss delete mode 100644 client/src/sass/components/file-upload.scss delete mode 100644 client/src/sass/components/filter-dropdown.scss delete mode 100644 client/src/sass/components/form-dialog.scss delete mode 100644 client/src/sass/components/form-input-control.scss delete mode 100644 client/src/sass/components/history.scss delete mode 100644 client/src/sass/components/link-control.scss delete mode 100644 client/src/sass/components/multi-dropdown.scss delete mode 100644 client/src/sass/components/print-button.scss delete mode 100644 client/src/sass/components/return-button.scss delete mode 100644 client/src/sass/components/search-control.scss delete mode 100644 client/src/sass/components/sort-table.scss delete mode 100644 client/src/sass/components/ui/add-button-container.scss delete mode 100644 client/src/sass/components/ui/page-header.scss delete mode 100644 client/src/sass/components/ui/search-bar.scss delete mode 100644 client/src/sass/components/ui/subheader.scss delete mode 100644 client/src/sass/gov3.scss delete mode 100644 client/src/sass/header.scss delete mode 100644 client/src/sass/init.scss delete mode 100644 client/src/sass/main.scss delete mode 100644 client/src/sass/mixins.scss delete mode 100644 client/src/sass/print.scss delete mode 100644 client/src/sass/variables.scss delete mode 100644 client/src/sass/views/all.scss delete mode 100644 client/src/sass/views/business-portal.scss delete mode 100644 client/src/sass/views/dialogs/all.scss delete mode 100644 client/src/sass/views/dialogs/contacts-edit.scss delete mode 100644 client/src/sass/views/dialogs/documents-list.scss delete mode 100644 client/src/sass/views/dialogs/equipment-transfer.scss delete mode 100644 client/src/sass/views/dialogs/error-dialog.scss delete mode 100644 client/src/sass/views/dialogs/notes.scss delete mode 100644 client/src/sass/views/dialogs/rental-rates-edit.scss delete mode 100644 client/src/sass/views/district-admin.scss delete mode 100644 client/src/sass/views/equipment-list.scss delete mode 100644 client/src/sass/views/home.scss delete mode 100644 client/src/sass/views/owners.scss delete mode 100644 client/src/sass/views/projects.scss delete mode 100644 client/src/sass/views/rental-agreements.scss delete mode 100644 client/src/sass/views/rental-requests.scss delete mode 100644 client/src/sass/views/roles.scss delete mode 100644 client/src/sass/views/rollover.scss delete mode 100644 client/src/sass/views/users.scss delete mode 100644 client/test/index.html delete mode 100644 client/test/spec/load.js delete mode 100644 client/typings/node/node.d.ts delete mode 100644 client/webpack.config.js diff --git a/client/.dockerignore b/client/.dockerignore deleted file mode 100644 index 354eebdbd..000000000 --- a/client/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -.git -node_modules/ diff --git a/client/.eslintrc.json b/client/.eslintrc.json deleted file mode 100644 index 5aa15c8ae..000000000 --- a/client/.eslintrc.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "parser": "babel-eslint", - "env": { - "browser": true, - "es6": true - }, - "extends": ["eslint:recommended", "plugin:react/recommended"], - "parserOptions": { - "ecmaVersion": 2018, - "ecmaFeatures": { - "jsx": true, - "modules": true - }, - "sourceType": "module" - }, - "plugins": [ - "react" - ], - "settings": { - "react": { - "pragma": "React", // Pragma to use, default to "React" - "version": "15.0" // React version, default to the latest React stable release - } - }, - "rules": { - "linebreak-style": [ - "error", - "unix" - ], - "semi": [ - "warn", - "always" - ], - "comma-dangle": [ - "warn", - "always-multiline" - ], - "no-console": [ "off" ], - "curly": [ - "error", "all" - ], - "brace-style": [ - "error", - "1tbs", { - "allowSingleLine": true - } - ], - "no-unused-vars": [ - "warn", { - "vars": "all", - "args": "after-used" - } - ], - "no-trailing-spaces": "warn", - "no-mixed-spaces-and-tabs": "error", - "no-tabs": "error", - "jsx-quotes": ["warn", "prefer-double"] - // "object-shorthand": ["warn", "always"] - } -} diff --git a/client/.gitattributes b/client/.gitattributes deleted file mode 100644 index 7a234a4ab..000000000 --- a/client/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.js text eol=lf -*.jsx text eol=lf diff --git a/client/.gitignore b/client/.gitignore deleted file mode 100644 index 8d67a86cd..000000000 --- a/client/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -node_modules -dist diff --git a/client/.vscode/settings.json b/client/.vscode/settings.json deleted file mode 100644 index c17600d3d..000000000 --- a/client/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - // The number of spaces a tab is equal to. - "editor.tabSize": 2, - - // Configure glob patterns for excluding files and folders. - "files.exclude": { - "dist/": true, - "node_modules/": true, - "bower_components/": true, - ".vscode/": true - }, - "eslint.enable": true, - "editor.trimAutoWhitespace": true, - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "files.trimFinalNewlines": true -} diff --git a/client/Dockerfile b/client/Dockerfile deleted file mode 100644 index 6f445285b..000000000 --- a/client/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/node:1 AS builder -LABEL maintainer="young-jin.chung@gov.bc.ca" - -COPY . /src - -RUN cd /src && npm ci && \ - ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT - -FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/nginx-116-rhel8:1 - -COPY --from=builder /src/dist/. /tmp/src -COPY --from=builder /src/nginx-start/. /tmp/src/nginx-start -COPY --from=builder /src/nginx.conf.tmpl /tmp/src/nginx.conf.tmpl - -RUN $STI_SCRIPTS_PATH/assemble - -CMD $STI_SCRIPTS_PATH/run \ No newline at end of file diff --git a/client/README.md b/client/README.md deleted file mode 100644 index 50bac758f..000000000 --- a/client/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# Hired Equipment Tracking System Web Application - -The Hired Equipment Tracking System (a.k.a. HETS) is a web application to track and hire equipment -in British Columbia. The client/ directory is the home of of the front-end source code. - -## Getting Started - -These instructions will get you web application and running on your local machine for development -and testing purposes. - -### Prerequisites - -The following software requirements are required: - -1. [Node](https://nodejs.org/en/download/) (at least version 8) -2. [git](https://git-scm.com/downloads) - -### Installing - -1. Git clone the [repository](https://github.com/bcgov/hets) onto your local machine. - - ``` - git clone git@github.com:bcgov/hets.git - ``` - -2. Install the Node module dependencies. You will need to be in the hets/client/ directory. - - ``` - npm install - ``` - - **Note**: The installation of [node-sass](https://www.npmjs.com/package/node-sass) might fail - depending on the target platform because of a missing C compiler. - -3. Run the local dev server - - ``` - npm start - ``` - -Now you will be able to access the web app when you go to -[http:://localhost:4375](http:://localhost:4375) - -## Development - -The web application requires the [C# API Server](https://github.com/bcgov/hets/tree/master/Server) -to be runing on localhost which can connect to a local PostgreSQL database. Check the -[Server project’s documentation](https://github.com/bcgov/hets/blob/master/Server/README.md) on how -to run the API server. Look for documentation in the -[DB Scripts](https://github.com/bcgov/hets/tree/master/Db%20Scripts) directory on how to init a -database. - -[Redux](https://redux.js.org/) is used to store most of the application’s state. The application’s -[store.js](https://github.com/bcgov/hets/tree/master/client/src/js/store.js) contains the response -data from any API request to be used by the React components as well as UI data. - -[React Router v3](https://github.com/ReactTraining/react-router/tree/v3/docs) is used to control the -browser’s URL history and routing. Routes are defined in -[app.jsx](https://github.com/bcgov/hets/tree/master/client/src/js/app.jsx) file. If a user is a -business owner they can only access the routes at the path `/business`. All other users can access -the rest of the application’s routes. - -API requests follow an [action creator pattern](https://redux.js.org/basics/actions#action-creators) -and they are all defined in a [api](./src/js/api.js) file. - -[SASS](https://sass-lang.com/) is a CSS preprocessor. The SCSS flavour of SASS is used for all the -files in the project. The React Bootstrap's CSS is built as a seperate `vendor.css` file in -`dist/css/`. The application’s SCSS files are all located in the `src/sass/` directory. - -The web application uses [Webpack](https://webpack.js.org/)’s -[Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) which will update -the UI whenever a [React Component](https://reactjs.org/docs/react-component.html) is saved on disk. - -[Gulp](https://gulpjs.com/) is the tool used for the front-end build system. Inside the -[gulpfile.js](https://github.com/bcgov/hets/tree/master/client/gulpfile.js) are defined a series of -tasks that can be run to build the project. The common ones are: - -1. `gulp` — starts a local Node webserver which will watch and re-build JS, SASS, and copy static - files into `dist/` -2. `gulp --production` — builds a production optimized version of the application into `dist/` -3. `gulp clean` — deletes all the files in the `dist/` directory. -4. `gulp test` — runs unit and integration tests. - -### Running tests - -There are only a few unit tests for HETS at the moment which can be run with: `npm test`. - -## Coding style - -Coding style for JS is enforced by [ESLint](https://eslint.org/). ESLint is run whenever the -JavaScript is built. Warnings turn into errors when the project is built. Any ESLint errors will -fail to build the JS. - -## Deployment - -Deployment is done by running `build.bat` which calls `gulp --production` to build a complete -production optimized web application in dist/. The files in dist/ are then copied to the right spot -in OpenShift. - -## Built With - -- [React](https://reactjs.org/) - JS library for building UIs -- [React Bootstrap](https://react-bootstrap.github.io/) - UI components and styles - -## License - -This project is licensed under the [Apache v2 License](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/client/babel.config.js b/client/babel.config.js deleted file mode 100755 index db17dd9c2..000000000 --- a/client/babel.config.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-env node */ - -module.exports = function(api) { - api.cache(true); - - const presets = [ - ['@babel/preset-env', {modules: 'commonjs'}], - '@babel/preset-react', - ]; - - const plugins = [ - ['@babel/plugin-proposal-class-properties', { 'loose': true, 'useBuiltIns': true }], - ['@babel/plugin-proposal-object-rest-spread', { 'loose': true, 'useBuiltIns': true }], - 'react-hot-loader/babel', - ]; - - return { - presets, - plugins, - env: { - test: { - presets: [ - ['@babel/preset-env', {modules: false}], - ], - }, - production: { - plugins: ['transform-react-remove-prop-types'], - }, - }, - }; -}; diff --git a/client/build.bat b/client/build.bat deleted file mode 100644 index c1bfc82aa..000000000 --- a/client/build.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -REM =========================================================================== -REM A batch file for automating the component installation and build -REM in a Windows environment. -REM =========================================================================== -call npm install - -gulp --production - -pause diff --git a/client/gulp.bat b/client/gulp.bat deleted file mode 100644 index f3039952f..000000000 --- a/client/gulp.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -.\node_modules\.bin\gulp %* diff --git a/client/gulpfile.js b/client/gulpfile.js deleted file mode 100644 index dbc901f3a..000000000 --- a/client/gulpfile.js +++ /dev/null @@ -1,257 +0,0 @@ -/* eslint-env node */ - -const del = require("del"); -const gulp = require("gulp"); -const $ = require("gulp-load-plugins")(); -const depsOk = require("deps-ok"); -const webpack = require("webpack"); -const webpackStream = require("webpack-stream"); -const _ = require("lodash"); - -const argv = require("minimist")(process.argv.slice(2)); -const PORT = argv.port || 4375; -const HOST = argv.host || "localhost"; - -const API_HOST = argv.apihost || "server-tran-hets-dev.pathfinder.gov.bc.ca"; -const API_PORT = argv.apiport || process.env.BC_GOV_HETS_API_PORT || 80; - -// set variable via $ gulp --production -var IS_PRODUCTION = !!argv.production; -process.env.NODE_ENV = IS_PRODUCTION ? "production" : "development"; - -var BUILD_NUMBER = $.util.env.buildno || "Dev"; -var BUILD_GIT_SHA = $.util.env.commit || "Local"; - -// var port = $.util.env.port || 1337; -const IMAGES_DIR_GLOB = "src/images/**/*.{png,jpg,jpeg,gif}"; -const JS_UNIT_TEST_GLOB = "src/js/**/*_test.js"; -const CSS_DIR_GLOB = "src/sass/**/*.scss"; -const HANDLEBARS_DIR_GLOB = "src/html/**/*.{hbs,html}"; -const DIST_DIR = "dist"; -const NODE_MODULES_DIR = "node_modules/"; -const VENDOR_CSS = [ - "bootstrap/dist/css/bootstrap.css", - "react-datetime/css/react-datetime.css", -]; - -var WEBPACK_CONFIG = require("./webpack.config.js"); - -function devOnlyPlumber() { - return !IS_PRODUCTION ? $.plumber() : $.util.noop(); -} - -gulp.task("deps-ok", (done) => { - // NOTE: Only checking NPM modules because deps-ok has poor support for the bower.json github - // shorthand dependency format. - const ok = depsOk(process.cwd(), { verbose: false }); - done(ok ? null : new Error("Found outdated installs")); -}); - -gulp.task("clean", (done) => del([DIST_DIR], done)); - -gulp.task("js:modules", () => { - return gulp - .src(_.last(WEBPACK_CONFIG.entry.app)) - .pipe(devOnlyPlumber()) - .pipe( - webpackStream(WEBPACK_CONFIG, webpack).on("error", (err) => { - $.util.log("WEBPACK ERROR", err); - }) - ) - .pipe(gulp.dest(`${DIST_DIR}/js/`)) - .pipe($.size({ title: "js modules" })); -}); - -gulp.task("templates", function () { - var now = new Date(); - var TEMPLATE_DATA = { - year: new Date().getFullYear(), - buildNum: BUILD_NUMBER, - buildSha: BUILD_GIT_SHA, - buildTime: now, - buildTimeStamp: now.toISOString(), - }; - - return gulp - .src(["src/html/**/*.hbs"]) - .pipe(devOnlyPlumber()) - .pipe($.compileHandlebars(TEMPLATE_DATA)) - .pipe($.rename({ extname: ".html" })) - .pipe(gulp.dest(DIST_DIR)); -}); - -gulp.task("sass", function () { - return gulp - .src("src/sass/main.scss") - .pipe($.sourcemaps.init()) - .pipe($.sass().on("error", $.sass.logError)) - .pipe($.autoprefixer()) - .pipe(IS_PRODUCTION ? $.cleanCss() : $.util.noop()) - .pipe($.sourcemaps.write("./maps")) - .pipe($.size({ title: "css" })) - .pipe(gulp.dest(DIST_DIR + "/css/")); -}); - -/** Static Asset Tasks **/ - -gulp.task("css:vendor", function () { - var libs = VENDOR_CSS.map(function (path) { - return NODE_MODULES_DIR + path; - }); - - if (libs.length === 0) { - return Promise.resolve(); - } - - return gulp - .src(libs) - .pipe(devOnlyPlumber()) - .pipe($.sourcemaps.init({ loadMaps: true })) - .pipe($.autoprefixer()) - .pipe(IS_PRODUCTION ? $.cleanCss() : $.util.noop()) - .pipe($.concat("vendor.css")) - .pipe($.sourcemaps.write("./maps")) - .pipe(gulp.dest(DIST_DIR + "/css/")); -}); - -gulp.task("robots.txt", () => { - return gulp - .src(["src/robots.txt"]) - .pipe($.size({ title: "robots.txt" })) - .pipe(gulp.dest(`${DIST_DIR}/`)); -}); - -gulp.task("images", function () { - return gulp - .src(IMAGES_DIR_GLOB) - .pipe($.size({ title: "images" })) - .pipe(gulp.dest(DIST_DIR + "/images/")); -}); - -gulp.task("fonts", function () { - return gulp - .src(["node_modules/bootstrap/dist/fonts/**"]) - .pipe($.size({ title: "fonts" })) - .pipe(gulp.dest(DIST_DIR + "/fonts/")); -}); - -gulp.task("webConfig", function () { - return gulp - .src("src/web.config") - .pipe($.size({ title: "webConfig" })) - .pipe(gulp.dest(DIST_DIR)); -}); - -/* Production Build Tasks */ - -gulp.task("fingerprint", () => { - var options = { - // debug: true, - dontSearchFile: [/\.map$/], // Don't bother fingerprinting sourcemaps - dontRenameFile: [ - /\/(index|login)\.html$/, // Don't fingerprint since they are un-fingerprinted URLs for the client. - ], - }; - - return gulp - .src([`${DIST_DIR}/**`]) - .pipe(devOnlyPlumber()) - .pipe($.revAll.revision(options)) - .pipe(gulp.dest("dist")) - .pipe($.revAll.versionFile()) - .pipe(gulp.dest("dist")); -}); - -/* Testing Tasks */ - -gulp.task("test:integration", function () { - return gulp.src("test/index.html"); -}); - -gulp.task("test:unit", function () { - return gulp.src(JS_UNIT_TEST_GLOB, { read: false }).pipe( - $.mocha({ - require: "@babel/register", - }) - ); -}); - -/* Watch Task */ - -gulp.task("watch", function () { - gulp.watch(IMAGES_DIR_GLOB, gulp.series("images")); - gulp.watch(CSS_DIR_GLOB, gulp.series("sass")); - gulp.watch([JS_UNIT_TEST_GLOB, "test/js/**/*.js"], gulp.series("test:unit")); - gulp.watch(HANDLEBARS_DIR_GLOB, gulp.series("templates")); -}); - -/* Dev Server Task */ - -var server = $.liveServer( - [ - "server/main.js", - `--port=${PORT}`, - `--host=${HOST}`, - `--apiport=${API_PORT}`, - `--apihost=${API_HOST}`, - ], - {}, - false -); - -gulp.task("server:dev", function (done) { - server.start(); - - gulp.watch(["server/main.js", "webpack.config.js"]).on("change", function () { - server.start.bind(server)(); - console.log("Reloading dev server"); - }); - - done(); -}); - -/* Build Tasks */ - -gulp.task( - "assets:static", - gulp.parallel("robots.txt", "images", "fonts", "css:vendor") -); -gulp.task("styles", gulp.parallel("sass", "css:vendor")); - -gulp.task( - "build:assets:simple", - gulp.parallel("styles", "assets:static", "templates") -); -gulp.task("build:assets", gulp.parallel("build:assets:simple", "js:modules")); - -gulp.task( - "build:complete", - gulp.series( - "deps-ok", - "clean", - "test:unit", - "build:assets", - // 'test:integration', - "fingerprint" - ) -); - -gulp.task( - "build:dev", - gulp.series( - "deps-ok", - "clean", - "test:unit", - "build:assets:simple", - gulp.parallel("watch", "server:dev") - ) -); - -gulp.task("build", gulp.series("clean", "build:assets")); - -gulp.task( - "default", - gulp.series(IS_PRODUCTION ? "build:complete" : "build:dev") -); - -gulp.task("test", gulp.series("test:unit", "build", "test:integration")); diff --git a/client/nginx-start/start.sh b/client/nginx-start/start.sh deleted file mode 100644 index 0afa627a3..000000000 --- a/client/nginx-start/start.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -#echo "---> Setting window.RUNTIME_REACT_APP values ..." -#JS_PATH=~/js/env.config.js - -#echo "window.RUNTIME_REACT_APP_SSO_HOST='${REACT_APP_SSO_HOST}';" > $JS_PATH -#echo "window.RUNTIME_REACT_APP_SSO_REALM='${REACT_APP_SSO_REALM}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_SSO_CLIENT='${REACT_APP_SSO_CLIENT}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_API_HOST='${REACT_APP_API_HOST}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_DWPBI_URL='${REACT_APP_DWPBI_URL}';" >> $JS_PATH - -echo "---> Creating nginx.conf ..." -envsubst '${HETS_DEPLOY_SUFFIX}' < /tmp/src/nginx.conf.tmpl > /etc/nginx/nginx.conf \ No newline at end of file diff --git a/client/nginx.conf.tmpl b/client/nginx.conf.tmpl deleted file mode 100644 index f6849c97d..000000000 --- a/client/nginx.conf.tmpl +++ /dev/null @@ -1,100 +0,0 @@ -# For more information on configuration, see: -# * Official English Documentation: http://nginx.org/en/docs/ -# * Official Russian Documentation: http://nginx.org/ru/docs/ - - -worker_processes auto; -error_log /var/log/nginx/error.log; -pid /run/nginx.pid; - -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. -include /usr/share/nginx/modules/*.conf; - -events { - worker_connections 1024; -} - -http { - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - gzip on; - gzip_disable "msie6"; - - gzip_comp_level 6; - gzip_min_length 1100; - gzip_buffers 16 8k; - gzip_proxied any; - gzip_types - text/plain - text/css - text/js - text/xml - text/csv - text/javascript - application/javascript - application/json - application/xml - application/vnd.google-earth.kml+xml - "application/gml+xml; version=3.2" - application/rss+xml - image/svg+xml; - - # Load modular configuration files from the /etc/nginx/conf.d directory. - # See http://nginx.org/en/docs/ngx_core_module.html#include - # for more information. - include /opt/app-root/etc/nginx.d/*.conf; - - server { - listen 8080 default_server; - listen [::]:8080 default_server; - server_name _; - - underscores_in_headers on; - add_header Last-Modified $date_gmt; - add_header Cache-Control "private, no-store, no-cache, must-revalidate"; - - client_max_body_size 5M; - - location /api/ { - proxy_connect_timeout 1800; - proxy_send_timeout 1800; - proxy_read_timeout 1800; - send_timeout 1800; - - proxy_set_header HOST $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Real-IP $remote_addr; - - # proxy_hide_header WWW-Authenticate; - - proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080; - } - - location /swagger/ { - proxy_set_header HOST $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://hets-api${HETS_DEPLOY_SUFFIX}:8080/swagger/; - } - - location / { - root /opt/app-root/src; - index index.html index.htm; - - try_files $uri /index.html =404; - } - } -} \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json deleted file mode 100644 index c56872381..000000000 --- a/client/package-lock.json +++ /dev/null @@ -1,12189 +0,0 @@ -{ - "name": "hets-client", - "version": "1.5.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", - "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helpers": "^7.2.0", - "@babel/parser": "^7.3.4", - "@babel/template": "^7.2.2", - "@babel/traverse": "^7.3.4", - "@babel/types": "^7.3.4", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.11", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", - "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", - "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0", - "esutils": "^2.0.0" - } - }, - "@babel/helper-call-delegate": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", - "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.0.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.4.tgz", - "integrity": "sha512-uFpzw6L2omjibjxa8VGZsJUPL5wJH0zzGKpoz0ccBkzIa6C8kWNUbiBmQ0rgOKWlHJ6qzmfa6lTiGchiV8SC+g==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.3.4", - "@babel/helper-split-export-declaration": "^7.0.0" - } - }, - "@babel/helper-define-map": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", - "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.0.0", - "lodash": "^4.17.10" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", - "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", - "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/template": "^7.2.2", - "@babel/types": "^7.2.2", - "lodash": "^4.17.10" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", - "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz", - "integrity": "sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.3.4", - "@babel/types": "^7.3.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, - "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } - }, - "@babel/helpers": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", - "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", - "dev": true, - "requires": { - "@babel/template": "^7.1.2", - "@babel/traverse": "^7.1.5", - "@babel/types": "^7.3.0" - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", - "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.4.tgz", - "integrity": "sha512-lUf8D3HLs4yYlAo8zjuneLvfxN7qfKv1Yzbj5vjqaqMJxgJA3Ipwp4VUJ+OrOdz53Wbww6ahwB8UhB2HQyLotA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.3.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.2.0" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz", - "integrity": "sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", - "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0", - "regexpu-core": "^4.2.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", - "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz", - "integrity": "sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz", - "integrity": "sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz", - "integrity": "sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.1.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.3.4", - "@babel/helper-split-export-declaration": "^7.0.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true - } - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.3.2.tgz", - "integrity": "sha512-Lrj/u53Ufqxl/sGxyjsJ2XNtNuEjDyjpqdhMNh5aZ+XFOdThL46KBj27Uem4ggoezSYBxKWAil6Hu8HtwqesYw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", - "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0", - "regexpu-core": "^4.1.3" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", - "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", - "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", - "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz", - "integrity": "sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz", - "integrity": "sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", - "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz", - "integrity": "sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.1.0", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", - "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", - "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.3.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", - "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", - "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz", - "integrity": "sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA==", - "dev": true, - "requires": { - "regenerator-transform": "^0.13.4" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", - "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", - "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0", - "regexpu-core": "^4.1.3" - } - }, - "@babel/polyfill": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.2.5.tgz", - "integrity": "sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug==", - "dev": true, - "requires": { - "core-js": "^2.5.7", - "regenerator-runtime": "^0.12.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - } - } - }, - "@babel/preset-env": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", - "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.3.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.3.4", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.3.4", - "@babel/plugin-transform-classes": "^7.3.4", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.2.0", - "@babel/plugin-transform-dotall-regex": "^7.2.0", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.2.0", - "@babel/plugin-transform-function-name": "^7.2.0", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/plugin-transform-modules-systemjs": "^7.3.4", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", - "@babel/plugin-transform-new-target": "^7.0.0", - "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.3.4", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.2.0", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.2.0", - "browserslist": "^4.3.4", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.3.0" - }, - "dependencies": { - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - }, - "dependencies": { - "electron-to-chromium": { - "version": "1.3.743", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz", - "integrity": "sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg==", - "dev": true - }, - "node-releases": { - "version": "1.1.72", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", - "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", - "dev": true - } - } - }, - "caniuse-lite": { - "version": "1.0.30001232", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", - "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==", - "dev": true - } - } - }, - "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-react-display-name": "^7.0.0", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/plugin-transform-react-jsx-self": "^7.0.0", - "@babel/plugin-transform-react-jsx-source": "^7.0.0" - } - }, - "@babel/register": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.0.0.tgz", - "integrity": "sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g==", - "dev": true, - "requires": { - "core-js": "^2.5.7", - "find-cache-dir": "^1.0.0", - "home-or-tmp": "^3.0.0", - "lodash": "^4.17.10", - "mkdirp": "^0.5.1", - "pirates": "^4.0.0", - "source-map-support": "^0.5.9" - }, - "dependencies": { - "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", - "dev": true - }, - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", - "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", - "requires": { - "regenerator-runtime": "^0.12.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" - } - } - }, - "@babel/runtime-corejs2": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.4.0.tgz", - "integrity": "sha512-54PQxRRKLRYTrF89Z9tyjJ+uoxyn05Avt1Ou6UT1x5QWpdo1FPQ15i/lGL+ZLvE5yxzlTO7u2oE06VCU9IYijA==", - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" - } - }, - "@babel/traverse": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", - "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.3.4", - "@babel/types": "^7.3.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", - "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, - "@hot-loader/react-dom": { - "version": "16.8.4", - "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-16.8.4.tgz", - "integrity": "sha512-S+5x4HJEMV7p2FzgUBEzrgiNJJeN4m5auTL3rZbmGsuyGt3Tgg8zgz6Mt1Udj8dKDxaryixDSNh0d/63TMqizg==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.4" - } - }, - "@hypnosphi/create-react-context": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", - "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - }, - "dependencies": { - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", - "dev": true - }, - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async-done": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz", - "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^1.0.7", - "stream-exhaust": "^1.0.1" - }, - "dependencies": { - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - } - } - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "autoprefixer": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", - "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", - "dev": true, - "requires": { - "browserslist": "^3.2.8", - "caniuse-lite": "^1.0.30000864", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^6.0.23", - "postcss-value-parser": "^3.2.3" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - } - } - }, - "babel-loader": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz", - "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", - "dev": true, - "requires": { - "find-cache-dir": "^2.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "util.promisify": "^1.0.0" - }, - "dependencies": { - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - } - } - }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", - "dev": true - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", - "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", - "dev": true - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "body": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", - "dev": true, - "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" - }, - "dependencies": { - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", - "dev": true - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "dev": true, - "requires": { - "bytes": "1", - "string_decoder": "0.10" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "bootstrap": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", - "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - }, - "dependencies": { - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", - "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - } - } - }, - "caniuse-lite": { - "version": "1.0.30000936", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000936.tgz", - "integrity": "sha512-orX4IdpbFhdNO7bTBhSbahp1EBpqzBc+qrvTRVUFfZgA4zta7TdM6PN5ZxkEUgDnz36m+PfWGcdX7AVfFWItJw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", - "dev": true - }, - "chokidar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz", - "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - } - } - }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", - "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } - } - }, - "connect-livereload": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz", - "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=", - "dev": true - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "continuable-cache": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "dev": true, - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - }, - "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "create-react-class": { - "version": "15.7.0", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", - "integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==", - "requires": { - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "requires": { - "array-find-index": "^1.0.1" - } - }, - "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, - "dargs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", - "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-fabulous": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", - "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", - "dev": true, - "requires": { - "debug": "2.X", - "lazy-debug-legacy": "0.0.X", - "object-assign": "4.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - } - } - }, - "deep-freeze-strict": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-freeze-strict/-/deep-freeze-strict-1.1.1.tgz", - "integrity": "sha1-d9BYPKJKab5LvZrC+uQV1VUj5bA=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deepmerge": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-0.2.10.tgz", - "integrity": "sha1-iQa/nlJaT78bIDsq/LRkAkmCEhk=", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deps-ok": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/deps-ok/-/deps-ok-1.4.1.tgz", - "integrity": "sha512-5S216xoLM4mwrBUZBVVXIdkIxnp8TLjK1QeghAEJHiwxIpNpGJd5RkNR59duRCNPey8k/UlWh39WknjXH3mBDQ==", - "dev": true, - "requires": { - "check-more-types": "2.24.0", - "debug": "3.1.0", - "lazy-ass": "1.6.0", - "lodash": "4.17.10", - "minimist": "1.2.0", - "q": "2.0.3", - "quote": "0.4.0", - "semver": "5.5.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "~1.1.9" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.113", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", - "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - } - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", - "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", - "dev": true, - "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.46", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", - "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.15.1.tgz", - "integrity": "sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.2", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.12.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "eslint-loader": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.1.2.tgz", - "integrity": "sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg==", - "dev": true, - "requires": { - "loader-fs-cache": "^1.0.0", - "loader-utils": "^1.0.2", - "object-assign": "^4.0.1", - "object-hash": "^1.1.4", - "rimraf": "^2.6.1" - } - }, - "eslint-plugin-react": { - "version": "7.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", - "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1", - "object.fromentries": "^2.0.0", - "prop-types": "^15.6.2", - "resolve": "^1.9.0" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-scope": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz", - "integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-stream": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.2.2.tgz", - "integrity": "sha1-95+ZhMB+4/2bRP+zzQQisT4kCE0=", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", - "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "expect.js": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", - "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=", - "dev": true - }, - "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "~1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "fined": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz", - "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", - "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "requires": { - "globule": "^1.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - } - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - } - }, - "glob-watcher": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", - "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "object.defaults": "^1.1.0" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - }, - "dependencies": { - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - } - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" - }, - "gulp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.0.tgz", - "integrity": "sha1-lXZsYB2t5Kd+0+eyttwDiBtZY2Y=", - "dev": true, - "requires": { - "glob-watcher": "^5.0.0", - "gulp-cli": "^2.0.0", - "undertaker": "^1.0.0", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "gulp-cli": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz", - "integrity": "sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.1.0", - "isobject": "^3.0.1", - "liftoff": "^2.5.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.0.1", - "yargs": "^7.1.0" - } - } - } - }, - "gulp-autoprefixer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz", - "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=", - "dev": true, - "requires": { - "autoprefixer": "^8.0.0", - "fancy-log": "^1.3.2", - "plugin-error": "^1.0.1", - "postcss": "^6.0.1", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "gulp-clean-css": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-2.4.0.tgz", - "integrity": "sha1-KuSBCf6DzMln/1rVPARJSaSGOzY=", - "dev": true, - "requires": { - "clean-css": "^4.0.4", - "gulp-util": "^3.0.8", - "object-assign": "^4.1.1", - "through2": "^2.0.3", - "vinyl-sourcemaps-apply": "^0.2.1" - } - }, - "gulp-compile-handlebars": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/gulp-compile-handlebars/-/gulp-compile-handlebars-0.6.1.tgz", - "integrity": "sha1-nMHZy5URBd+uUwko0qkEoU10xdM=", - "dev": true, - "requires": { - "gulp-util": "^3.0.3", - "handlebars": ">=3.0.0", - "through2": "^0.6.3" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - } - }, - "gulp-live-server": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/gulp-live-server/-/gulp-live-server-0.0.31.tgz", - "integrity": "sha1-O0wYb+ygcIJhcY9sis4ZPxmPLVE=", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "connect": "^3.3.4", - "connect-livereload": "^0.5.3", - "debug": "^2.1.1", - "deepmerge": "~0.2.7", - "event-stream": "~3.2.1", - "q": "^1.2.0", - "serve-static": "^1.9.1", - "tiny-lr": "^1.0.3" - }, - "dependencies": { - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - } - } - }, - "gulp-load-plugins": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-1.6.0.tgz", - "integrity": "sha512-HlCODki0WHJvQIgAsJYOTkyo0c7TsDCetvfhrdGz9JYPL6A4mFRMGmKfoi6JmXjA/vvzg+fkT91c9FBh7rnkyg==", - "dev": true, - "requires": { - "array-unique": "^0.2.1", - "fancy-log": "^1.2.0", - "findup-sync": "^3.0.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "micromatch": "^3.1.10", - "resolve": "^1.1.7" - }, - "dependencies": { - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - } - } - }, - "gulp-mocha": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-5.0.0.tgz", - "integrity": "sha512-NIjXZLqqcw9DXIEBcfm0sP1AUDlUJJeaK9EGCH2s6lSwo5NK/cEat0Vm7XelOkxZnWl0O5Za+aM6E4jyxWxTlw==", - "dev": true, - "requires": { - "dargs": "^5.1.0", - "execa": "^0.8.0", - "mocha": "^4.1.0", - "npm-run-path": "^2.0.2", - "plugin-error": "^0.1.2", - "through2": "^2.0.3" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - } - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "gulp-plumber": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.1.tgz", - "integrity": "sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "fancy-log": "^1.3.2", - "plugin-error": "^0.1.2", - "through2": "^2.0.3" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - } - } - } - }, - "gulp-rename": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", - "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", - "dev": true - }, - "gulp-rev-all": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/gulp-rev-all/-/gulp-rev-all-0.9.8.tgz", - "integrity": "sha512-nznONaAYzzZi2NA00BMgPL9/o9ZXN1VpxXMY/c7CaGIl4xYbIG9WPYoXvY4GEF6xJA5IirVcDifhfLIVk324Vg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "fancy-log": "^1.3.2", - "merge": "^1.2.0", - "plugin-error": "^0.1.2", - "through2": "~0.4.0", - "vinyl": "^2.1.0" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "~1.0.17", - "xtend": "~2.1.1" - } - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "gulp-sass": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.2.1.tgz", - "integrity": "sha512-UATbRpSDsyXCnpYSPBUEvdvtSEzksJs7/oQ0CujIpzKqKrO6vlnYwhX2UTsGrf4rNLwqlSSaM271It0uHYvJ3Q==", - "dev": true, - "requires": { - "gulp-util": "^3.0", - "lodash.clonedeep": "^4.3.2", - "node-sass": "^4.8.3", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "gulp-size": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gulp-size/-/gulp-size-2.1.0.tgz", - "integrity": "sha1-HCtk8X+QcdWr2Z0VS3s0gfj7oSg=", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "gulp-util": "^3.0.0", - "gzip-size": "^3.0.0", - "object-assign": "^4.0.1", - "pretty-bytes": "^3.0.1", - "stream-counter": "^1.0.0", - "through2": "^2.0.0" - } - }, - "gulp-sourcemaps": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.9.3.tgz", - "integrity": "sha1-3zesVJkrIgpnDewaBL+Fv3rl77U=", - "dev": true, - "requires": { - "acorn": "4.X", - "convert-source-map": "1.X", - "css": "2.X", - "debug-fabulous": "0.0.X", - "detect-newline": "2.X", - "graceful-fs": "4.X", - "source-map": "0.X", - "strip-bom": "2.X", - "through2": "2.X", - "vinyl": "1.X" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-uglify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-2.0.1.tgz", - "integrity": "sha1-6M+4MQFPyf8uBV4zeFhhgw1Jk2U=", - "dev": true, - "requires": { - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash": "^4.13.1", - "make-error-cause": "^1.1.1", - "through2": "^2.0.0", - "uglify-js": "2.7.5", - "uglify-save-license": "^0.4.1", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "uglify-js": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", - "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", - "dev": true, - "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-watch": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-4.3.11.tgz", - "integrity": "sha1-Fi/FY96fx3DpH5p845VVE6mhGMA=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "chokidar": "^1.6.1", - "glob-parent": "^3.0.1", - "gulp-util": "^3.0.7", - "object-assign": "^4.1.0", - "path-is-absolute": "^1.0.1", - "readable-stream": "^2.2.2", - "slash": "^1.0.0", - "vinyl": "^1.2.0", - "vinyl-file": "^2.0.0" - }, - "dependencies": { - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "gzip-size": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", - "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", - "dev": true, - "requires": { - "duplexer": "^0.1.1" - } - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "history": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", - "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=", - "requires": { - "invariant": "^2.2.1", - "loose-envify": "^1.2.0", - "query-string": "^4.2.2", - "warning": "^3.0.0" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", - "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", - "requires": { - "react-is": "^16.7.0" - } - }, - "home-or-tmp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz", - "integrity": "sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "dependencies": { - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - } - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immer": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/immer/-/immer-2.1.3.tgz", - "integrity": "sha512-rlXI8sYY22/ykqFodL37W1/syMhYDVVEsui5HWrQezgmavV6f8oDbN2fKBH6XZkjH5qz9hapbpmgDPYOufJsfg==" - }, - "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "in-publish": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", - "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==" - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "requires": { - "repeating": "^2.0.0" - } - }, - "indexport": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/indexport/-/indexport-0.1.1.tgz", - "integrity": "sha1-FgMaCoJ5Hk+K0TKwhfZcGrWxL6Y=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "inquirer": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", - "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.11", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.1.0.tgz", - "integrity": "sha512-TjxrkPONqO2Z8QDCpeE2j6n0M6EwxzyDgzEeGp+FbdvaJAt//ClYi6W5my+3ROlC/hZX2KACUwDfK49Ka5eDvg==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fail": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-fail/-/is-fail-0.1.1.tgz", - "integrity": "sha1-jUEnvUTS5fsjneFU7qx8yPXxUmg=", - "dev": true - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", - "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", - "dev": true, - "requires": { - "array-includes": "^3.0.3" - } - }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", - "dev": true - }, - "keycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", - "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", - "dev": true - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lazy-debug-legacy": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", - "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", - "dev": true - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^2.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "livereload-js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", - "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "loader-fs-cache": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", - "integrity": "sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw=", - "dev": true, - "requires": { - "find-cache-dir": "^0.1.1", - "mkdirp": "0.5.1" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - } - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "^3.0.0" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "requires": { - "js-tokens": "^3.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", - "dev": true, - "requires": { - "make-error": "^1.2.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "midware": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/midware/-/midware-0.1.7.tgz", - "integrity": "sha1-gnbsr4VavB+7Yhy1rdgA2+JFpFY=", - "dev": true - }, - "midware-pool": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/midware-pool/-/midware-pool-0.1.2.tgz", - "integrity": "sha1-rtAKf5kn1xpHuf7B2ty+lNwLuQo=", - "dev": true, - "requires": { - "midware": "^0.1.7" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "dev": true, - "requires": { - "basic-auth": "~2.0.0", - "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - } - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - } - } - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-sass": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", - "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "2.2.5", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "now-and-later": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", - "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-hash": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", - "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", - "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", - "function-bind": "^1.1.1", - "has": "^1.0.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - } - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", - "dev": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parent-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", - "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "optional": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - }, - "pop-iterate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz", - "integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M=", - "dev": true - }, - "popper.js": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz", - "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==" - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-bytes": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz", - "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "prop-types": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.1.tgz", - "integrity": "sha512-f8Lku2z9kERjOCcnDOPm68EBJAO2K00Q5mSgPAUE/gJuBgsYLbVy6owSrtcHj90zt8PvW+z0qaIIgsIhHOa1Qw==", - "requires": { - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "prop-types-extra": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz", - "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==", - "requires": { - "react-is": "^16.3.2", - "warning": "^3.0.0" - } - }, - "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz", - "integrity": "sha1-dbjbAlWhpa+C9Yw/Oqoe/sfQ0TQ=", - "dev": true, - "requires": { - "asap": "^2.0.0", - "pop-iterate": "^1.0.1", - "weak-map": "^1.0.5" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "quote": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/quote/-/quote-0.4.0.tgz", - "integrity": "sha1-EIOSF/bBNiuJGUBE0psjP9fzLwE=", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "react": { - "version": "16.8.4", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.4.tgz", - "integrity": "sha512-0GQ6gFXfUH7aZcjGVymlPOASTuSjlQL4ZtVC5YKH+3JL6bBLCVO21DknzmaPlI90LN253ojj02nsapy+j7wIjg==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.4" - } - }, - "react-bootstrap": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.4.tgz", - "integrity": "sha512-xj+JfaPOvnvr3ow0aHC7Y3HaBKZNR1mm361hVxVzVX3fcdJNIrfiodbQ0m9nLBpNxiKG6FTU2lq/SbTDYT2vew==", - "requires": { - "@babel/runtime-corejs2": "^7.0.0", - "classnames": "^2.2.5", - "dom-helpers": "^3.2.0", - "invariant": "^2.2.4", - "keycode": "^2.2.0", - "prop-types": "^15.6.1", - "prop-types-extra": "^1.0.1", - "react-overlays": "^0.8.0", - "react-prop-types": "^0.4.0", - "react-transition-group": "^2.0.0", - "uncontrollable": "^5.0.0", - "warning": "^3.0.0" - }, - "dependencies": { - "react-overlays": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", - "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", - "requires": { - "classnames": "^2.2.5", - "dom-helpers": "^3.2.1", - "prop-types": "^15.5.10", - "prop-types-extra": "^1.0.1", - "react-transition-group": "^2.2.0", - "warning": "^3.0.0" - } - } - } - }, - "react-context-toolbox": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz", - "integrity": "sha512-tY4j0imkYC3n5ZlYSgFkaw7fmlCp3IoQQ6DxpqeNHzcD0hf+6V+/HeJxviLUZ1Rv1Yn3N3xyO2EhkkZwHn0m1A==" - }, - "react-datetime": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-2.16.3.tgz", - "integrity": "sha512-amWfb5iGEiyqjLmqCLlPpu2oN415jK8wX1qoTq7qn6EYiU7qQgbNHglww014PT4O/3G5eo/3kbJu/M/IxxTyGw==", - "requires": { - "create-react-class": "^15.5.2", - "object-assign": "^3.0.0", - "prop-types": "^15.5.7", - "react-onclickoutside": "^6.5.0" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - } - } - }, - "react-dom": { - "version": "16.8.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.4.tgz", - "integrity": "sha512-Ob2wK7XG2tUDt7ps7LtLzGYYB6DXMCLj0G5fO6WeEICtT4/HdpOi7W/xLzZnR6RCG1tYza60nMdqtxzA8FaPJQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.4" - } - }, - "react-hot-loader": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.8.0.tgz", - "integrity": "sha512-HY9F0vITYSVmXhAR6tPkMk240nxmoH8+0rca9iO2B82KVguiCiBJkieS0Wb4CeSIzLWecYx3iOcq8dcbnp0bxA==", - "requires": { - "fast-levenshtein": "^2.0.6", - "global": "^4.3.0", - "hoist-non-react-statics": "^3.3.0", - "loader-utils": "^1.1.0", - "lodash": "^4.17.11", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.0.2", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "react-is": { - "version": "16.8.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.1.tgz", - "integrity": "sha512-ioMCzVDWvCvKD8eeT+iukyWrBGrA3DiFYkXfBsVYIRdaREZuBjENG+KjrikavCLasozqRWTwFUagU/O4vPpRMA==" - }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "react-onclickoutside": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.8.0.tgz", - "integrity": "sha512-5Q4Rn7QLEoh7WIe66KFvYIpWJ49GeHoygP1/EtJyZjXKgrWH19Tf0Ty3lWyQzrEEDyLOwUvvmBFSE3dcDdvagA==" - }, - "react-overlays": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz", - "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==", - "requires": { - "classnames": "^2.2.6", - "dom-helpers": "^3.4.0", - "prop-types": "^15.6.2", - "prop-types-extra": "^1.1.0", - "react-context-toolbox": "^2.0.2", - "react-popper": "^1.3.2", - "uncontrollable": "^6.0.0", - "warning": "^4.0.2" - }, - "dependencies": { - "uncontrollable": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.1.0.tgz", - "integrity": "sha512-2TzEm0pLKauMBZfAZXsgQvLpZHEp95891frCZdGDrSG7dWYaIQhedwLAzi0X8pR8KHNqlmuYEb2cEgbQzr050A==", - "requires": { - "invariant": "^2.2.4" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "react-popper": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", - "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", - "requires": { - "@babel/runtime": "^7.1.2", - "@hypnosphi/create-react-context": "^0.3.1", - "deep-equal": "^1.1.1", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" - }, - "dependencies": { - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "react-prop-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", - "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", - "requires": { - "warning": "^3.0.0" - } - }, - "react-redux": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.1.tgz", - "integrity": "sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "hoist-non-react-statics": "^3.3.0", - "invariant": "^2.2.4", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^16.8.2" - }, - "dependencies": { - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "react-is": { - "version": "16.8.4", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", - "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==" - } - } - }, - "react-router": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.2.1.tgz", - "integrity": "sha512-SXkhC0nr3G0ltzVU07IN8jYl0bB6FsrDIqlLC9dK3SITXqyTJyM7yhXlUqs89w3Nqi5OkXsfRUeHX+P874HQrg==", - "requires": { - "create-react-class": "^15.5.1", - "history": "^3.0.0", - "hoist-non-react-statics": "^2.3.1", - "invariant": "^2.2.1", - "loose-envify": "^1.2.0", - "prop-types": "^15.5.6", - "warning": "^3.0.0" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", - "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" - } - } - }, - "react-router-bootstrap": { - "version": "0.23.3", - "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.23.3.tgz", - "integrity": "sha1-lww1xTwExh+2sRDU/2Uafopzsro=", - "requires": { - "prop-types": "^15.5.8" - } - }, - "react-transition-group": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.6.1.tgz", - "integrity": "sha512-9DHwCy0aOYEe35frlEN68N9ut/THDQBLnVoQuKTvzF4/s3tk7lqkefCqxK2Nv96fOh6JXk6tQtliygk6tl3bQA==", - "requires": { - "dom-helpers": "^3.3.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - }, - "dependencies": { - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "redux": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz", - "integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==", - "requires": { - "loose-envify": "^1.4.0", - "symbol-observable": "^1.2.0" - }, - "dependencies": { - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - } - } - }, - "redux-freeze": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/redux-freeze/-/redux-freeze-0.1.7.tgz", - "integrity": "sha512-L+S9pvWW4u7BRqM2nmeOR/ZTU5k/3pWd+0Vq/oH4vliObKzMLBvENkzmicL/eb44gO3C/OX0fov6NHIlDGw8Zg==", - "requires": { - "deep-freeze-strict": "1.1.1" - } - }, - "redux-promise-middleware": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/redux-promise-middleware/-/redux-promise-middleware-6.0.1.tgz", - "integrity": "sha512-YcUOyZNTzSYocj3Gs8yhuV0u9wAZc3xxkEo42Ch0t5oiEW+KWf6UlknzswLH9uYFtUVz5NJHn2D72Y3WWKaoZA==" - }, - "redux-thunk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", - "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", - "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" - }, - "regenerator-transform": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", - "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp-tree": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", - "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "reselect": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" - }, - "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.8.0.tgz", - "integrity": "sha1-I2dijcDtskex6rZJ3FOshiisLV8=", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "requires": { - "glob": "^7.1.3" - } - }, - "rocky": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/rocky/-/rocky-0.4.16.tgz", - "integrity": "sha512-DLbDulYYe8PHCYIIpH4nSdzUU3hUfAOPD5MHxbGMxEzI70w+AMhZg4Go6l2UAvaQDXZnfhjXVlskcnxl8tS5uA==", - "dev": true, - "requires": { - "http-proxy": "^1.16.2", - "indexport": "^0.1.1", - "is-fail": "^0.1.1", - "lodash": "^4.17.20", - "media-typer": "^0.3.0", - "midware-pool": "^0.1.1", - "raw-body": "^2.1.2", - "retry": "^0.8.0", - "router": "^1.3.1" - } - }, - "router": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/router/-/router-1.3.3.tgz", - "integrity": "sha1-wUL2tepNazNZAiypW2WAvSF/ic8=", - "dev": true, - "requires": { - "array-flatten": "2.1.1", - "debug": "2.6.9", - "methods": "~1.1.2", - "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "setprototypeof": "1.1.0", - "utils-merge": "1.0.1" - }, - "dependencies": { - "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", - "dev": true - } - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass-graph": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", - "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "scheduler": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.4.tgz", - "integrity": "sha512-cvSOlRPxOHs5dAhP9yiS/6IDmVAVxmk33f0CtTJRkmUWcb1Us+t7b1wqdzoC0REw2muC9V5f1L/w5R5uKGaepA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "dependencies": { - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", - "dev": true - } - } - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - } - }, - "serialize-javascript": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", - "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", - "dev": true - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.11.tgz", - "integrity": "sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==" - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "requires": { - "through": "2" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "requires": { - "readable-stream": "^2.0.1" - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, - "stream-counter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-1.0.0.tgz", - "integrity": "sha1-kc8lac5NxQYf6816yyY5SloRR1E=", - "dev": true - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", - "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", - "dev": true, - "requires": { - "first-chunk-stream": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "^4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "table": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", - "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", - "dev": true, - "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.1.0.tgz", - "integrity": "sha512-TjxrkPONqO2Z8QDCpeE2j6n0M6EwxzyDgzEeGp+FbdvaJAt//ClYi6W5my+3ROlC/hZX2KACUwDfK49Ka5eDvg==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "tiny-lr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", - "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", - "dev": true, - "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "toxy": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/toxy/-/toxy-0.3.16.tgz", - "integrity": "sha512-UPM6+AJp+BocVb8CHVnW9wtjCFWmn2PSq05OTKv379F2gfczLP/uMw0gjBh6t+Uo4YEbuETOwgP2wDENVo2BAg==", - "dev": true, - "requires": { - "indexport": "^0.1.1", - "midware": "^0.1.3", - "object-assign": "^3.0.0", - "raw-body": "^2.1.2", - "rocky": "^0.4.15", - "router": "^1.3.1" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "requires": { - "glob": "^7.1.2" - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "uglify-save-license": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz", - "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", - "dev": true - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true - }, - "uglifyjs-webpack-plugin": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.1.2.tgz", - "integrity": "sha512-G1fJx2uOAAfvdZ77SVCzmFo6mv8uKaHoZBL9Qq/ciC8r6p0ANOL1uY85fIUiyWXKw5RzAaJYZfNSL58Or2hQ0A==", - "dev": true, - "requires": { - "cacache": "^11.2.0", - "find-cache-dir": "^2.0.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.4.0", - "source-map": "^0.6.1", - "uglify-js": "^3.0.0", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" - }, - "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "uncontrollable": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz", - "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==", - "requires": { - "invariant": "^2.2.4" - } - }, - "undertaker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", - "integrity": "sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "v8flags": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz", - "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", - "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^2.0.0", - "vinyl": "^1.1.0" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "^0.5.1" - } - }, - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dev": true, - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "optional": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "optional": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "optional": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "optional": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "optional": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "dev": true, - "optional": true, - "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "optional": true - } - } - }, - "weak-map": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz", - "integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes=", - "dev": true - }, - "webpack": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", - "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - } - } - }, - "webpack-dev-middleware": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.1.tgz", - "integrity": "sha512-XQmemun8QJexMEvNFbD2BIg4eSKrmSIMrTfnl2nql2Sc6OGAYFyb8rwuYrCjl/IiEYYuyTEiimMscu7EXji/Dw==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.3.1", - "range-parser": "^1.0.3", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", - "dev": true - } - } - }, - "webpack-hot-middleware": { - "version": "2.24.3", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.24.3.tgz", - "integrity": "sha512-pPlmcdoR2Fn6UhYjAhp1g/IJy1Yc9hD+T6O9mjRcWV2pFbBjIFoJXhP0CoD0xPOhWJuWXuZXGBga9ybbOdzXpg==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "html-entities": "^1.2.0", - "querystring": "^0.2.0", - "strip-ansi": "^3.0.0" - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - } - } - }, - "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "webpack-stream": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/webpack-stream/-/webpack-stream-5.2.1.tgz", - "integrity": "sha512-WvyVU0K1/VB1NZ7JfsaemVdG0PXAQUqbjUNW4A58th4pULvKMQxG+y33HXTL02JvD56ko2Cub+E2NyPwrLBT/A==", - "dev": true, - "requires": { - "fancy-log": "^1.3.3", - "lodash.clone": "^4.3.2", - "lodash.some": "^4.2.2", - "memory-fs": "^0.4.1", - "plugin-error": "^1.0.1", - "supports-color": "^5.5.0", - "through": "^2.3.8", - "vinyl": "^2.1.0", - "webpack": "^4.26.1" - }, - "dependencies": { - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "worker-farm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } -} diff --git a/client/package.json b/client/package.json deleted file mode 100644 index 6acd62b71..000000000 --- a/client/package.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "name": "hets-client", - "version": "1.5.0", - "description": "Hired Equipment Tracking System JavaScript Web Application", - "main": "dist/index.html", - "scripts": { - "test": "gulp test", - "start": "gulp --apihost localhost --apiport 27238" - }, - "repository": { - "type": "git", - "url": "git@github.com:bcgov/hets.git" - }, - "keywords": [ - "bcgov", - "hets" - ], - "contributors": [ - "Séamus O'Connor (http://pneumaticweb.com/)", - "Randy Posynick (https://github.com/RandyInVictoria/)", - "Alejandro Sanchez (https://github.com/asanchezr)", - "Mike Lyttle (https://github.com/MikeLyttle)" - ], - "license": "Apache-2.0", - "private": true, - "dependencies": { - "bluebird": "^3.5.2", - "bootstrap": "^3.4.1", - "classnames": "^2.2.6", - "immer": "^2.1.3", - "lodash": "^4.17.21", - "moment": "^2.22.2", - "node-sass": "^4.14.1", - "react": "^16.8.4", - "react-bootstrap": "^0.32.4", - "react-datetime": "^2.16.3", - "react-dom": "^16.8.4", - "react-hot-loader": "^4.8.0", - "react-overlays": "^1.2.0", - "react-redux": "^6.0.1", - "react-router": "^3.2.1", - "react-router-bootstrap": "^0.23.3", - "redux": "^4.0.1", - "redux-freeze": "^0.1.7", - "redux-promise-middleware": "^6.0.1", - "redux-thunk": "^2.3.0", - "reselect": "^4.0.0" - }, - "devDependencies": { - "@babel/core": "^7.3.4", - "@babel/plugin-proposal-class-properties": "^7.3.4", - "@babel/plugin-proposal-object-rest-spread": "^7.3.4", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.4", - "@babel/preset-react": "^7.0.0", - "@babel/register": "^7.0.0", - "@hot-loader/react-dom": "^16.8.4", - "babel-eslint": "^10.0.1", - "babel-loader": "^8.0.5", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24", - "del": "~2.2.0", - "deps-ok": "^1.4.1", - "eslint": "^5.15.1", - "eslint-loader": "^2.1.2", - "eslint-plugin-react": "^7.12.4", - "expect.js": "~0.3.1", - "express": "^4.13.4", - "gulp": "^4.0.0", - "gulp-autoprefixer": "^5.0.0", - "gulp-clean-css": "^2.4.0", - "gulp-compile-handlebars": "~0.6.1", - "gulp-concat": "~2.6.0", - "gulp-live-server": "0.0.31", - "gulp-load-plugins": "^1.6.0", - "gulp-mocha": "^5.0.0", - "gulp-plumber": "^1.1.0", - "gulp-rename": "^1.4.0", - "gulp-rev-all": "^0.9.8", - "gulp-sass": "^3.2.1", - "gulp-size": "~2.1.0", - "gulp-sourcemaps": "~1.9.1", - "gulp-uglify": "~2.0.0", - "gulp-util": "~3.0.7", - "gulp-watch": "~4.3.5", - "http-proxy-middleware": "^0.19.1", - "minimist": "^1.2.5", - "mocha": "^5.2.0", - "morgan": "^1.9.1", - "toxy": "^0.3.12", - "uglifyjs-webpack-plugin": "^2.1.2", - "webpack": "^4.29.6", - "webpack-dev-middleware": "^3.6.1", - "webpack-hot-middleware": "^2.24.3", - "webpack-stream": "^5.2.1" - }, - "browserslist": [ - "last 2 version", - "> 1%", - "Firefox ESR", - "IE 11", - "not IE < 11" - ] -} diff --git a/client/server/main.js b/client/server/main.js deleted file mode 100755 index 7f6b301b0..000000000 --- a/client/server/main.js +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env node -/*eslint-env node*/ - -const path = require('path'); -const express = require('express'); -const morgan = require('morgan'); -const proxy = require('http-proxy-middleware'); - -const webpack = require('webpack'); -const webpackMiddleware = require('webpack-dev-middleware'); -const WEBPACK_CONFIG = require('../webpack.config'); - -const argv = require('minimist')(process.argv.slice(2)); - -// Include your SmUserId on the command line or in ENV. -const DEV_USER = argv.devuser || process.env.HETS_DEV_USER || ''; - -const PROJECT_ROOT = path.join(__dirname, '..'); -const DIST_PATH = path.join(PROJECT_ROOT, 'dist'); - -const PORT = argv.port || 8000; -const HOST = argv.host || 'localhost'; -const API_HOST = argv.apihost || 'server-tran-hets-dev.pathfinder.gov.bc.ca'; -const API_PORT = argv.apiport || process.env.BC_GOV_HETS_API_PORT || 80; -const SERVE_ONLY_STATIC = Boolean(argv.staticpath); -const STATIC_PATH = SERVE_ONLY_STATIC ? argv.staticpath : DIST_PATH; - -const app = express(); - -app.use(morgan('dev')); - -app.post('/api/test-file-upload', function(req, res) { - var buf = ''; - req.on('data', function(chunk){ buf += chunk; }); - req.setEncoding('utf8'); - req.on('end', function() { - var v = Math.random(); - console.log(v); - if(v > 0.5) { - console.log('successful upload'); - setTimeout(function() {res.end();}, 2 * 1000); - } else { - console.log('failed upload'); - res.status(400).send('upload failed').end(); - } - }); -}); - -app.use('/api', proxy(`http://${API_HOST}:${API_PORT}/api`, { - changeOrigin: true, - headers: { - 'DEV-USER': DEV_USER, - }, -})); - -if (!SERVE_ONLY_STATIC) { - // Override WebPack config to work with this express server - WEBPACK_CONFIG.output.path = '/'; - WEBPACK_CONFIG.output.publicPath = '/js/'; - - const compiler = webpack(WEBPACK_CONFIG); - const middleware = webpackMiddleware(compiler, { - publicPath: WEBPACK_CONFIG.output.publicPath, - contentBase: 'src', - stats: { - colors: true, - hash: false, - timings: true, - chunks: false, - chunkModules: false, - modules: false, - }, - }); - app.use(require('webpack-hot-middleware')(compiler)); - app.use(middleware); -} - -app.use(express.static(STATIC_PATH)); - -app.use('/test', express.static(PROJECT_ROOT + '/test')); -app.use('/node_modules', express.static(PROJECT_ROOT + '/node_modules')); - -app.listen(PORT, function () { - console.log('\uD83C\uDF0E Dev web server initialized http://' + HOST + ':' + PORT); -}); diff --git a/client/server/toxy-proxy.js b/client/server/toxy-proxy.js deleted file mode 100755 index c1e444399..000000000 --- a/client/server/toxy-proxy.js +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env node - -/*eslint-env node*/ - -'use strict'; - -var toxy = require('../node_modules/toxy'); -var argv = require('minimist')(process.argv.slice(2)); - -var port = argv.port || argv.p || 8000; -var proxy = toxy(); -// var rules = proxy.rules; -var poisons = proxy.poisons; - -proxy.forward('http://localhost:' + port); - -// proxy.all('/api/users/search') -// .poison(toxy.poisons.inject({ -// code: 503, -// body: '{"error": "toxy injected error"}', -// headers: {'Content-Type': 'application/json'}, -// })); - -// proxy.all('/api/roles') -// .redirect('https://logontest7.gov.bc.ca/clp-cgi/int/logon.cgi'); - -// proxy.all('/api/business/owner/*') -// .redirect('https://logontest7.gov.bc.ca/clp-cgi/int/logon.cgi'); - -// make initial app load fast -proxy.get('/api/authentication/dev/token/*').disableAll(); -proxy.get('/api/users/current').disableAll(); -proxy.get('/api/districts').disableAll(); -proxy.get('/api/regions').disableAll(); -proxy.get('/api/serviceareas').disableAll(); -proxy.get('/api/districts/*/localAreas').disableAll(); -proxy.get('/api/districts/*/fiscalYears').disableAll(); -proxy.get('/api/permissions').disableAll(); -proxy.get('/api/userdistricts').disableAll(); - -proxy.all('/api/*') - .poison(poisons.latency({ min: 500, max: 2000 })) - .poison(poisons.slowRead({ bps: 100 })); - -proxy.all('/*'); - -proxy.listen(3000); -console.log('Server listening on port:', 3000); -console.log('Proxying to API on port:', port); diff --git a/client/src/Web.config b/client/src/Web.config deleted file mode 100644 index 68515fb39..000000000 --- a/client/src/Web.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/src/html/buildinfo.hbs b/client/src/html/buildinfo.hbs deleted file mode 100644 index c5c8bc72f..000000000 --- a/client/src/html/buildinfo.hbs +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - MOTI Heavy Equipment Tracking System - - -
-
- Name - MOTI Heavy Equipment Tracking System -
-
- Build Date - {{buildTime}} -
-
- Version: - {{buildNum}} -
-
- Git Commit - {{buildSha}} -
-
- - diff --git a/client/src/html/index.hbs b/client/src/html/index.hbs deleted file mode 100644 index 3c335dc56..000000000 --- a/client/src/html/index.hbs +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - {{!-- Attempt at overriding the "compatibility mode for intranet" in IE 11 --}} - - - - - - - - MOTI Hired Equipment Tracking System - - - -
-

Loading HETS…

- -
-
- 5% Complete -
-
- -
-
- -
- - - - - diff --git a/client/src/images/blueline.png b/client/src/images/blueline.png deleted file mode 100644 index cb01efb3ec6ddf7781be3f82c83ee0d5dc0f6b81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61SFYwH*Nw_oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#J`1m?9Cx9{-)^9gY-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSo9FbnKx9mKhQOj4NvxlIAdaUU=Gk5~R`7)z4*}Q$iB}nqelJ diff --git a/client/src/images/gov/bceid_logo.png b/client/src/images/gov/bceid_logo.png deleted file mode 100644 index 5ea1cd2fe326fba142851d10db433b558e077aa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2637 zcmV-T3bOTyP)d0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU*?@2^KRCwC#S_^PgeskK^5fxfV%Gf=U$juZq0 zNnQ!*qyZ7Gz|IhoJ`x~Zd(uZ{N zQO*#WOA%u7Uh;qJgEd{ zD2uz0aS4POU<7f!gb|T@8A(P9qn5FYv6Zot(b>=OM=)kHE@n()lwu4M^9V6~81ogz z9>%{JTX5`1spK&_xVoA;TWiVi1^N(NfDC9kjL!LOAdJ62ATmw@f{QYyGUhQZP|yF1QSJ8fw)*wdu?)!|-;yIsq*Z!{31yEnWp@Q8^}5h4UK5UABA1FdkyeRT^{|qL4HhSdkvy9JUKEpBQan#wOXmDxrkKe1TFUQMZHL2KYH37Rvjmq|Xz zxE04s88(*CmbBy+>~b~l;%~&+xXqfp=FsbP&6V@`#d#m z`KB8$j(V75n@!mbk86{6-^5s?uF3JwvJqUn$H63F*ssprQnN21rV#@1q5&jS%MmL+ zdYmT3YpLzfX7c$%PS2fy$y(^S2F(K3ls+1>eunR-ZvDjTwbzTBMV_U zk$9yas`HyMUr&PbIzlQZ}?}4t4ua*cjCoB1dMy^Ph~I zLUrE6)%y-934+mSC%VRd8g-sUb9KYSi{RV}!eZ1e27>$zHl`5L=*jAQ>jx&ZK%q`Z zPDj0ES^6@@?GE!_qV5s;v1xW4@Q2FCA1*)9f~&XjYodDY0@mjbWN#`G9 z%wW9a@a$=}G2R(mq21ptwC?aDZL_B&#mD)77`NCIa1yLhXTh8h7&T^Rg7PZQ;dd4f zh0c~PKf=2E;-yz9i~bziV1>|BOBjurRGK0#&sN#aj}6v}V!Ixp*zQM}!9`kV0mQK} zst&tFjhllEtwz`hEH1zC2V~l63=VGVexVn1Izup!@_fv?vPicGPBf z+G1FdLt>E?C6DZ;4u;ipl;5_)TPgnLij2^D)@!#h&b8H!o1t)XP=;8+>kSC`39CL! zaWd-9JG&$Rs8~!{Bl%9Ir^@6eU=*YHv z$p{3jgyb@9sA!F?fvfL5wu-f}+btM>6%8>OZSx?p!K&jdEm&r=swp_$VPo2i!CFx! z^DC6ErUdsKRewuO`7LC=eI`UH&LksMm$J2uA4)=#_K()sm*C|FO>jcnZSl-{;sW_~Yt0 zKn@MlevrH;8XhfGicz90+@gJ1xnqu#@%<~)+ZcureF5tflCR@`{vZSwQpKU9u>ZAX zrFzh7(2g1iNt5}n68n6?q9}8`)b@WYSE8#mmHMzgsPvCAo@yn^g@ zsSfgHN1RH|e1Hlk&9~qGTgq&;i({>(@=yg(1o1T1=9Ed8Qwapqu4=JDTo=Qz_M;@I zdy9i~c3!5;4!LI?x=nowE*BF@Iy5(PZEm%loOgfqm&%}}AEE9IxG6BM0rlX1duG+q z{2C?d)?@!6>C`a^kDATaR_PSu{b01|;MPL00*qm8$H?OjZ8yPvNGB2fUw{DszM#8l+K$(900000NkvXXu0mjfpz{(m diff --git a/client/src/images/gov/favicon.png b/client/src/images/gov/favicon.png deleted file mode 100644 index bc4b5a97e8eff63c1c5e86239902157cc0d2acdd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11639 zcmeHtXH-+&wl<;n-cbwz6i^5yl!O*~k=~IafrJn`geHhmrHC{UP^9+X*c-3=Plno-?`rz@;-QYG|?C%GcPl3Ets8~ix2|oW{VQ? zb8*L^@$h8i{oE0DPAD&+Eeefsl?83Jc7T8wq%6o(Tw7S%T?yrYQTO*m8T#uO+4(!! zL6IPNIdU047>>XN<%IzHxj4IGVScipU%W8f{Y5tz1pEc@a*_p^Y3l)%+&oc0h!8|b zSWv|e<0A@^BL~WOBJE)Y%BsIp;99aE2QM#o7#Qs9>nr3dCgkRc28%$UP_VElSX5LH zhY-ZxarHv@3A$prFDQQFP)1?xJTdNG7&lko1t-GR&D%>B1j3C2e<#O{+Nt>AI)8U? z(f&n`^+JL*a197|cF)V^J4fzv6aA+JkXH z{qp=*8#N7Wy+3R&WJF_J+<#eIp#O?Q+WmoZ_x5!Dg+bbZQO+nATp(B+v&i4@UKsm7 z7wB*ExfuCxf#BTz!T&e(KlJ()%P(DF%5HYv7fv;lWkDD5!jNuu7$of1t+cH z5JcKaK?NZQdl5mXm^egG0)m7<5fF%&gsAObs5D%$UI&C^8|q=j+y z_WN_d2;+h>^g>*SCL#`j3PT{GqGBRaVv=Gae}YU*LxUvP>D3rYPNK-$4nafAq5 zu3=mdXcXAp75!`AVpU+cx!`m~T$Bcm_*Xw}DljEa6vE5R)5y)uSr&8=D)55wS49D3 zeyi8mss95f^INv6<80kL@BGETA=H)|y~_dB?nb@0;lb^Vv_{|WFn1}%&o$`$MOuR{MT!4{x6oGe7HpeQTrM|7;;6;L;0+v%Td#*`t%Q!26?zrY9#6htos1m1i_ND$14v zPG?Vd*9ek3wua=}x10mtV!i}-4+YDM4W}Rc46r(;PWrlhx_$cTU~5_R%mwUJIf_@-OE zH-CKZrybw($}be(GHv$*<&)&wGVje?JwvF@eMmpwe&~>W{N?Gj9cMzxmSb6mUDe@(n!;+Y}PJTW`6-ML)>l`4JJu@$R_2+cp}S z;cz$3>XgU0*qU@j=qbT3|ucMc=|xJ@P2c2SlIC+%$=RU+nbFoI~}|d30=G0pUq~s z_rzY^m@{?BPg#ED{TjV2Ury(Ip9HA3_t|&iiCtlfT{!lb@n* zI9NY^tDHRd0dK!a*)#K6*WCPM3rxMaQ+eZvoi5yLwLWdF{7{Zq@-n6D(f(|-i2ZZS zlDU1l#MCM~>5du}lERlfhZ;kPq}r&!HtN$h!Q zV@J;oz>~}W;$|CHh@y5zB^+ye^Cd1?E_y8;amxY!^ zP3^fGfV_wi)4VEW?J4-E;^oho+}lpWC4&uxt#}hw!$wnh(l4)aFnlaG?LsUi7v(J( zvej0$nx;t>1QhL=y%q1cD$X|WB<;(TLvVd|e$)J1GXJgXx%xKa#csJ1ob1EsAM1&e zQibK(3U01CeE6NrD|GIL7!Cu;`v;d{LoLJS?++PkU(b=+O4sf?Y1z2&u~JU-)MlPg zEkxUib(xjyYKk(2aM=rT%hmyDjgeid$tS%!zCu z2MS<(xMpO}v|Qzt$ArrsL16nTrHa!6Wk}K3$vk!Q#+=>_v54BnL$q@f^(R=o+?qXo z2T{+ggdtvCLC53fAtgYb!E#QvD;Ef1LW1N_hx$)=9XwSK0PP(ZnH8fAO{(?H1~zL% zckw6Cx(_JJB!VOce{?YU7fKmhR}@M zI+((B;h6B^o}mO;P~q*|HX*W3nO#|4Fm$zV*U^OT>xbeJ`@St~#vU z>#+~vCEOjTF)O6#e#}|wEkf_abS6hJ17$giD?*|*Je~l69^G9~m)hM1s^S4Hx}SmH zR^;4<@W~bS(`aE}BlCw+hJx8jL12T80;t8P_EnE;X=0TIwwHYAp`2H*ikKEXssSW% zscUxA-?%U18$BL`u5dr%tKRB#PB2>S%q%~`K8|jNkjgw~AQ?!}8NA-w=^rbuSy}h) z)^3A`ML7T9P=bwxzSj1c#3w2nF%vbZhYJ(WXhcI)jFWhL3zVWWBXw&y z(QGLPH$9aET9KvkH=eW=8JV@@-2RF1cBl}L06?+wWC~n&`tW`{Pv@Ri@UQ&DIx3ky za+L0S-RaHvRRs-YiLJ+I!cUV9^>yB^dVX}*`ll+q#v6#xcLuF_V>!7--ghUKww(3;1Rp#Ubi(P+nwa4KAy*% zmb7(STCtGC#i$jod#(}apV`;ABn_{edF<2cSwngy~ROchfgjU?H8)88Z+Ma zaLN+ImwB{V##n$+B&DF&7BkWWsIUNl0>r}jgQ*d~72>cf_4Lf6cqE@(6jNQwHMAj) zmUSi*g$ypE5o$+YieGvU$DSz%wRy0SR}^g)%T%l5>B+vPkrX!r8<}L#)lsdI*pIP- z3}_57?Wdz)tJ!ui^LBwche&VBXF)n@c+PMxg-KcT`&SVYQSmdo-Ne*lH=VAdp(Dz& zz&kX~P&O z*EHd*{!Ti`>dbj!@jW5S`wjq2NoDp|Pa?Ncz2H`1nlpL`zBw`eBmh>#$0R=uIJGC{ zx%W}tj5goyZk<&y;L)v7WkiY$n|0@tfRE9>w+BA~LL_H3cO1z*wzN*)>N+h;lW|2; zaXhZb?#%Jb7@rE2yS>ked_8bk7+{OK+C{&6ixy$nHcm`Y;GuARmVNaZLp%vnN^rrN z_(G33{5=tIU#IUX5sL!dp8n2f=w&A0h$Ns-*eiG~=3%5C>Y3`PWH zm+l=}TSD7<7nvBF>rzdv;lk@g3h9}{+!5}a3v|K76;35dPrCEsb8_DUYN%~Qc$4sb zD4x2r^f6@;v&L7C9mZ9Ivtp?^t;q}S_T%xSQ^V~P)ErNy=fd*oZQFn~w~{~U?QA%Y zX9G0SPxOJLBK{flua-(jt+L=85Otm`=Fqg2Sjr#*pU97{SNK#^RpOsnmwNiohC^2ne8$=r>|S_7BrQvvw!)LGd!2b z=w*1_)t`~f5ud5Yz=Z7Gxs0oy6spOtt#|1Gpn4zb{S z>@I_(%`qa>WUAF=QEUDWc-mq^)LtxD&!XWDYJ9djeJ09Vil4>$bVtn>#BW?OhgXQ$ zR8-yY{xWRZ1<%diBJh4eSwu1J1v2}bi#Wk|iEU9%<$;h_1#873<3}H;XtHz)iEY&1 z6SxBPSTwu7X2)v-_UNYzdo?w$x2>wS08(FF2=&N{O5PVLQ`S~~mC0oNpX-_OFFJJ^3n`~8LfsDZ#|r((Qk`T@uC2mrXDNr=Q0&p#&E_4=OG!c2Mox+ z;VT=|DvU5mK@!=D(`nc9+-jJwK?m(El5gnj9+)LM8f3!n5(F!d!TSu4t0H2h%;^cM z%~`~T*w~G$D1NZr*#8<4AMaOweJ&YAQq$?Y$MuS!bYYq}wOfdzi%AE@XAqLazA;DM zMt$yOzKedpDYUW@ZKu*YJO$AzN~3ixCgXPJw;#%>8jXZgzOge>W6}PmSHa$}fv?ip z3d+!U^cg>v*dTy-cQpFxP!|pB<`u?RlZ~;@yv4Kkg6S=adiF|N6pe|Mi@21U8qHKA z3;{1JQ|-q)8)Uw$66Ce?(kIMaBg2e!EFnUYhmil{Ne4=C8WD^yaiqYyf=StkU7&_)vt=wca#yO zTe!PVpB-qUws>i74UVkuCmiv&)zt9d8fdI~H7jT(z^Clw-E=>qfz5g`bvyU6%C7zb zgVj!)&kv0E77Gz!OXnx13Vhf5MSXYFY*q1ptz+!ILmY^29{$e=cuj3B6gB=>{-OV zfvTK-U*Prb4ySVhg6mBu?TBsDErCD)_4u>y*2p>Y$*ydZI<}>&!{tM-1FLVsoIoS+ zFxS3vylskR#YBcj9ChVd37huq2KJFM>D;f`A~>!*nigL8e8V7BOvUnMZ^l*FBqCJg zVW)gHGaLRlrHLFMMon2?lQq2dc}xE~lhfVP_Q?HuErIXO4xIipePZN;qB&x~iB+dp zsB)At|4C4>Y8dFKIdlw{v7b#ytJ{|G;QY!nU z8#UyPN&~Ybl7f|5c#RxAz1v}=mjSia$2B{?_k0qo6ebcp;Fr8M?%I(_$}v??d<$dL z)zasn|5{ZsjcQ7I&$~}YcaH=fo}-#9ID2S-;#9WKjbmfU9X~P`%;%p&u{TWT$`E1n|jedUYFBs>T)qi=}z#F zhjI*cPS;fdBK5G2Xxhu#^H>mANjeMcPoVU^6ByT?|Gg~dejK4rCogp3n|#V3@8$MR zQKbhAYx=X)-hvN_i^2$RP$&j>h(wNGe<*8V9JG@gqPLb}O|Nbmq8&b48b9G@%K#C5 z){w+fr2dp^!Vo5+K61%a{)G=gxZOd zOMPG&*hr44dd{5IT`j8Z;sGu;#o@(dgzx#l<`Llxo_b_)!hS0E%j`qlLw%B?VYC6K-*{bJucsFrSSUO7zJ+BZ z21wyZ<2Qt4r2-7!aiF|*QbA_2Jzo`aHMc;WIwSwZj5SX!hz*Kyi!XiSSOc|z&cWcX z+98P6R%>Mso8kQs_NKFlMG_}V@OSBz-BE=9d_QgD5p8V|Y?~jW|KLDK zCooqmG5dv>tR{d>D6EW2Xne7Kau{$`YDBukgg8Y}zZWn+jEaL#Bxy=>x8b=>A2^Uy z$J@E)X&G5csjA9qa05@hHWY@wb6ds4?UR$Ld>Kw&A%Rd-buL_Qd04PdJ2sml_qfho zeZ*ELVc#j#`WmGb$q)>EzD<9V7l!7B7lSFj9g zQF1Vsb)aN3g6F%bE!_qK-Co#k$T^~&R*@dQ<=ccV7xWv(d)`$6dU0uQIN6S={s|9AvlBfY7Qc8|fxGDiCkV!1>Pj*)!~PS% z7RF`1#4|PQnJ`e)4Nd^dvzqRtQiR^EV+k5a6`=TJweSK@@mME6dZ2XdB_5H&VzGKM z$)Mhk%LUM!>&e>wrKG*COuHz-7^1!lGg3Ro6j;)^s;mSV`QHED0-$vj z%ca+?)lgFylIGF~)&4*MS3Xis*%~kF5{7XVX4V}uOKgYNXvXPQX>FRF913QM5`yyZTZE&8|(`6s^YOU-u}(g7^c?mw>0aeMC!m3w7pk z+%MFVHRxXI^v5;`RTv^Q{0+|Uz#rNx1>oK5my|_9k~1C+D;O4WTU)B+lY+=v;)-5oEQZNUo9e`;{xgBkJ5Z>3n0&L2~md$ z>M(DK*iMUKi z%>`~I&{>rh!dGdhqJ;ovg-4h3%4Z{=;_?b?OAXS#$SfcnvgUjMb4Gnh#!$ zM4RgBueRQfY=8pweyZqR$Fu#Auu9WS(RcMbky_t1+h^IU>u+y169eOioJ@(g^7n|7 zZfAv>4MYGv;v>Q2DrxW9=LbgeXTvxHM_vlYbhxbPze1RE>^Cfg{@0o5g(&k2MP_8GedYA`e2$qPjeBQm|m?U_-494)3IUI#tOo{R)Cy1n?P z122~gtY5ZSR@UA~H?l^K)Sptz9b-<%P#imfROzzD-94n_d*q|kJSWrFM)H79Bn&^y zP%;Xb2nOY4+#`(?TCL!l@g$Ld9>pm~ffbg^R>DN*V=DV%Tnp^nwm*u zatP-Z_sjgXYy(O>|I7BwF>qj1hebq72uHxTfNMu04o)AqiW@iu$6dR=t)k`@#jkAw zUN}~sW#hnunXM+%gN zH$D+{bJ?|(0zEO~fuXi$Lw6Ty*^swJ8;8!C+(A4sC9zC+`LB|``Pp8wh#Ztr8L~`cR2W`Y}0%_KVsZ>6Mg=l1cEXG>qg%BEilKcrg z)U}D=EE~6H2g#3K5>8sb{rFq|;@o{zkcn)9ig@mm^um{9Ux)D^%V!cG7pywM1Pxlu zzCsXir71x)i5;j^yVPiP_5D%-r835dIvbyF-TQj4bw@GY0BqtYj1+na z;6sXWFH%u6RW#fW`f2$M)NK+XavDe3zTa32wgkMaN>t%+Xc}V{i$BA=EdMpr_Be%q z9o%t#4nHpr9!{?Lx_KYaSURH|>aJ*qdx2G6Ps>Q<{QUgr`_|d?FQ#Dh``R&(WAE?SAFBNxTS=YZ!&UONDg~E(c;cj=hl582Ylo3(7H#*`2h8g6~6GaWgj)KSIL4!O~tW|g9dDOtOV5)^@i!k#bp%@(tlD1iC*TPbe1cn z)XE%_L#0o0;^{gqZfX>-kEIpru8DOv$+#^ubfS-0;O7CI@7@8tJy9-g&lEC!lffZL zA2|Bz>o2|3Y8$0?gM5%2SDJPCIAJ3Hd9J>kqc8GFP0rTX)D@-4H1n-`9r^Ee*S=GL X8-R7U>Gn=9UX9jJ(NV5Yv$_7|bA(B{M@2j>Z&aYmC7#n=#DToZlbk_dd_(dG7nZKHu+keXr%8JIvJNg5W;!eSCa;f(92+ zXx{U5P-CoQlOolb>AAPfdWkpWet&>SJk8X6i9B^8K@iUJRz;O0rDW0?wM zH<_OvPnih^?|;mLFZlopt0 zQM4!6!%?al8Ze|1456+9RaVwh)rCS~NEH=*6&OMdg@P*oY@4244c**#My3Z3HSM4^I^NRXU4foxAF1X`v({L|8gNbF_7VPtPZJj|jBqQc?NBql3Ve!c z=p5J!CvL9|=iF7`gF2kK5)^mKfIU3*VQ^x$`1JM)due4I7nrPK83gotamz&#^4|g< zJ%GM|o~(1+S7N|$0*Pv}ON{_@5dd~jT`Fpm^Nm}tUD^B*n5(DW&YYN81m2l8_k7ys zEFHh(WnhWs)+z(b-Jiy00G6*IIr(%M`Wnl2mSfNT=?=Ub`(!m}b8lM9?>@{%@mRHxmu5ECuPj75;xRughU!Dj}dYM)6 z!P@T$&}QKiSCCuvzN2r_`Bu6aJ(K&+IIXmq`vwM#r9aAfqw92M<<*&6eiy=%%YgUR zsU_XOXv*01!uG~wO>19rQ9ZXocbmJ3^UnZgYgMgd-n?gD^UCACmgP3;c|_%yGaq-i zm1f7FfNs+4;>z|yOL%evFp>LdY#}P+wIJNi+R&7Ax~dFxbRU6L^Hu=UHYYac0Z z9OTw0?pCwsRGt(;d0rx?9Ya`q$5sO!cE>LTP$J62FZiI{(?xY`4`@*g$r;=-;my*+ zYa3ewqtgpt*V9LzRq*QJDbr(LqJvjy_ zT?~^w`^eYAtXHgtAHk{xT|_9snuQJp+JW_q#Zetipj2oY78guj6PY zc+Y#cYppZdIj)~1c8v{-)b8s4=RH!S+M3|Q8Sj$Hx#l)xyI&jNY2D#cd1(D zj}4X@)3$N1D*8+Y(=j=vrD~Am6$L{}%lds{X-u>W+VLZLYtCS_q0~jnQYQP&7nRG- z`f3Fxh6M4EYiV7Fp%rI0C(H6B2OBN~z`NhwL*HwY6Lm}UJQ;K4UH@i9W5dlHEL#(p z!ej_X;ER7xsT^{r z=W55P8R7ew=<}If>8K{z$-vFFT>jc20eNZ4+9N;HSb;KD_xxOm|FzPP-LIXkOCq|m z6j9A8@&rGvIYYzzPERc6wR|fx$dGD{N1Nx_*(#mgaRTT4+wae`IP}&O(>s3rxyc~Q zYNz4(vkXR~=fvh+IbX?)hsI5ST-)YrFgUNrC3W$B&~(Y5UTWW66SEB1x_mt4G8>~; zaX{eDAcu>~sWW$AMuwxm{1Q9qdsO&U>lZt>?k*gzAPsrER8}eWUhmWRDM`?&6vp01 z@9Dj+t$5769Y;a-A=8JXuTPH7+wLjY@sT6}k4`ylmYJPWctyzBD)v4Csv?`&KT0SL z6Q_+IPsSS`&208nU4)go9|*K^2c5(cjm(iv1k63ujrGIQaRM70 zVd(&4hBBnR*ZMN+w#xN*y|yB?gI$xf$5Ge4_gjtMDpzwhNhvmxFO5~sc-9}7pC~dL zX(s#5m*`!dA$x9PMpI%bKeop02}fSj=*-UiM0ic`kfmXwVyixZF02sAOd_}6L)Fn_ zh_@q~n)1TmKa;2{EPSD;ZRIH7Fk{6eL*5?t>Qk%fukB-h9h&W_U_IGiv$o?BapP2& zdWhJwp5n~j1EyL>gg*W$y|c9+YZ_OaI4&V1Kq7kURi~PX2eRoNr)KSmV8IhF?+p=8 zp!lC^y)8&I(J$YT+IO<~Y)n=G!5V+@x=AXu>zy>eX7s-JeD7m zbo-jTha8BG9g#Lt5rUNb^SM6E!L18L#@V^`FZ8qDKD3FCQF9zn(M8E`T!IlZR*RzF zJuvMPQAB3Qt@%RbEaA_Y@oT#CEaLC5yvQ$<7@HTyr;A2H6vYm3WD{R%tEPAf-@Z?i zu)p6jxm^AbaB|PSzVx8vCTqN?4ny_&rtquyqmhuvxmG1hg4~hx0IbCEp3me8qYqu_ zAI}gk+2+MOk^$u(B~ZG?<$vEf(sEs7nteKz!Og4@>IvYWPt+lF9-Ir5d zXez>e)h1NNoYJYbFD#!{Rkti4eddaLaA2_fm36X1VbN~$Q5N*_O$lB9n>I2+!!1EJ ziXA47^W$&%CH~ zO)u7bjAVXa(s&zwx1VDXcxWbx+p{VjAl4ZNFhyP}* z4*P2oTZ$9DXZ$2w;pf&UVa-fh8VOau{IOh zeVqKyX~M>IR(@5l`{VqWpqXIyy_LrR`ND>Dm(YCGGrTvNz;x8zJ<@PBE7#^QCTqZF zNAHu~Offm39Vqt-g@=?a+%ZwVVM{WTB^r4{f-PPjQMgWXT*VZ z&WiO+xV%XyFtMr91QT9krk@q9MVQkfzDFEmpi@Q)#S$7s7|0X-A`V~c5Los0wa!yA zQX0hv436te<*~QSnSL`(u4@`TRc)(KWJ-omL~v0MooSX?*DO`?f_7N4^6eHPDyCw< z^Kt(RXAAw?E0sG@OT;|Zg_fnpB*{#;*o}vY#-@8BLOKyc2^psXQ#y&@QhbgIR)U!@v_ABW2&0pDo8=q@clT>7S-8lq*oWtL@B^upQR@8jtw}bJ{)?uHd zL3KoS9C&hqrTzMkQiOw6o>dUT=YH7DK11PxtbSt;(Jhv9xNve&L!)R!a%_Kdx~QgW z5^;)8TDx>cJ6<%kk;57g1t#Af%+Hi{+9Yc@eW$!sh__)0yW z>o~n4pf{$}f8}Lk^O8ci|NFI-=!ObbKIZxqR=5zI9tjN@^4`{BAJdk|49I(7(0L^x zslD3Q2@UC&Iz$iP_~qd4TGXXj$gUK8S%w@9TQ9W7l-*2px#1u1ZA~_)opOSvUFmx3 z48y#LxcIBKTIt=iVZEBHaK^!C`iF^Iw)Y#uQw*2^*mJf}^6C9124ZivQh{My zMLBU3<~KT0wV0#e%|@_;Y32FcG~p;l?%=t8(L4q7ClMOYb)Hw(%wEeXNN9hrAHG73 z=$<-Eh;dE6{suST-gor&vSCya+QcsS8LWS*r&V#z1FkU9o^$@GUxbb2H?PvK18{`L zNWI7oKZ*OHv)8^gzkZr{G~=^(Fez#qn6tRiyVlfvw!l+#(PU_MW$Bl+&|!5StD1V? z%!VYr{YmKb_Wn6(63N@7xFmQ_qxkBC`GRfLvj1{* diff --git a/client/src/images/gov/hets.jpg b/client/src/images/gov/hets.jpg deleted file mode 100644 index e8fd6042179ef8ad4f46ab864422b5143d5bc227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68151 zcmeFZ2|Scv`!IgnL#0JjvV>A(8T%5GrKA#B)21=T&WIUnOuJH1grcG-TL{^=N>Wmi zEqf(f*6iEN{LejOq`o~Z&-46#pZEX1rp%mk?sLwyU*|g8O@2@QNTn73wd!k5%m(_A(MukfMf;E+b4c1g%~Ncmn>fqi2E^%PPn#itpTR zWGF7BNU5`dQfHYsi}Qt*cb^cYrt`TjkDe-|JX5AT8wcOZz#j|^g4ms109*9%IA=T# zWMPp&`mQ)b3oO=wQbWfHhru}E9pMLX8vfOEaDnq2l(vSp9&il}TO8a5eoXBXfxDm=2VdWK zuwot$^qg_FSSMHToExsG>5Oxtkp;-MaGA>(Si9=ZWi(x!G{0q>aNja}EF4_tp6s>8 zxy@y^J3461WdLWtb*+K6x1MDLRY;J5wuUCa1~wkZz*0cK5{tLkhW!9%DIaYYr+<`b zIQ+AohKr?pD<=N6%px_620;1~M5=t3txd$jU*UaVlD7_9-@~o6^@I^;y z1w0x2VVkv4psqm4%{Ue*Du%FjqERfur6Ne4z|`bPH|9)-$^S5l(Sf3tWbE06J~Y8xZr+L-Go;BeRXyVYfY>J z)@2@Zms9)K(4Kn$nm~K8PB5=oaad;3j*ql9HgYF7RO0R!zxU**7cOUA@~Ls4Mu%P9kK+2y9F571;9{m1JXF~=SoRA zgBmM-Q$qmK1pir#1;V%hbl-)$w^Adi%TJtr4*H=5dyOxK>*Fg(n{GtYsV}skW&?$ zCCc61UBX>P0_$QeiBM8fl9ZB`l$I6;HN;&#op2}*aVJ+HS`S(nSG0>QC8`mCdjumk z9;Ye@Fr|=SiJt4#8CVOYPfN5U#sTAqal*L*b|GM@sN_02&sF{@U*}cS)%|r()B@HmHSiB1w1F8$rK)K?!y8&{3CGGDUZ+8Q9%{8}maKO9bfXBkR z{JfKS6)37hg9{YFNZt=9Z}X8NjqnZ zHOxb2Wla|h%yuIXK+>#5=bJR(Ih(Y!gw*_r+q`xd5PM=&1>u>TI07M#kTC-0BLgOL zQeYyaEG0#)s*AO>wetL-s=N_x()V3eV7`_hp8b=`y1L5LQ4i&yg+=3GL($Pv6~yCh zEtQqF%WRj^R8m*eR77ZLAP|ZQGO}74a*8{&w6@D?s4Gwq10Bq7NcAC>STtxq$3SIi zX)6UqSqwrP%<-heEiGl`#X;6W93d?wgGO1&%1fa!wBB@_TyZETGzLZk@K(YW^du`K zqa7vN@y#2aSQ?_Wrb3bL0DPI(ApbdoGfkOiI1iO%GFg>kTPjf z2C@fE@taJP4RI(JFi8V*D=S+EzhN!|Zr<4XFZIll>RV{I z%$LXv9?T4Fy)eL< zLByu)4#qVJMTE3G0t|1|A{$jfDG4Qnj2uFaR)lx51ujI#32lRMrRei)e{kI9I_n@b zP}cKZ1&I7W2<3!>7gJRQbv<2dQI=q&5;wqD;~h{gaL=?VJ5Y|c4q*7CRuTZUzJH1a z9sHyjb-31Z#yAPUNm?6Vz;G05hy#mlU}OW+Q8+6AhC?ZN6@5dHkdl&80U8f$j{ulf zNhnCEIHK$^Se%sv7=NWDj@xDj_<5*4$WEA4c$>Vw2d~r=JHeIse{M-$sA~?txQ>@ zp)yX3x}qRJ?MZ;r6(!P|twj~H6dcP?no=Sm)Hl7G&nq}U*H(6=;6&}+)CLG{wmU~k z_(Tc&DD`lZcu(IzPjkDW;cOijc+``Y1DZdJCs+xZUtr;Y2YLWknCGzm0hPk*zlBN- z{$Z*qFlkvTM5$lGg9ASUc+{d`^6%66w=k)?_8)`&#_vBRRvYHg-@>I)H_PC^hYDNb ze;MfSGzpfh2GF_x5G;-KKT}^A=&XPFTe#nt`cpOjExD=)B^d#2RT(7#4OLm175=e8 zgT}K6&q9|0UYueRRKh`zzcO0`RcRRo09{%UK$nsKYuaU~)8si5mR9@@I_U8?&}9(- zx{}nt2VIsrL7juH^u5sk06I)NLRJ9=PiyzzT6MwgO0v~54!vf_vNHv*~?IbPt&8nfG<4@j^({GVEX0%8a`E!2fpVK#A@Hjgg=OAQhg8O6gzYVUl-2WlafxG+-{c?%`KFs~O znCZ`<%h7ao7W((h2Oa(zwlsn=(o%ran*K3x(D?g-<_FP(u;(|>DKQ?H?gGh6(+u{{ z!T%WK&4o&{k_TP>8a~+i1e`}Gz~d}J?(apfL^Cv+&sCsFV-^F@=Wj5OgJWz2aQy&- zxwzqvS?~>M8U}O2z$^x!&);BxkOLS1Mrf!i(k%JU;m?gzv+(CQLIn?c{55n%n0$)U zm;dV#Pmw0DS=c|ge9+;qVZ-qi;Jq9iX&|I%qWp8(=b|ba@8xL2)-3NqpTEIC9(MZ( zN}Q=kv!y>rK%NGVhQJSTCg}1v@F{U7CCvQ$5&s`y<{Uq$BI3c8;Y4vz{vZzZSg`4c08|9|iwAxl_b0Ly0y1+Uxx&^tt)TtkV73=h4;} zr4{7`G-sVRb@9zmU(bkE0M15&#b_xhczqUpW{atcxknxB)lx#!Jz(`sMgk$D@NK0* z9WFb3mXMF327zSZzBo7Mw(_-02|;hU~~9kIaOPE z{xT-z;k-3cT7AmK>)Z}3oS0XM%8q#psh~&N3LvGFx^PO_1g3CqK18^$UoV_$!fL7u z0t7QvX(@r-s^81w4;E1oQZy}_)mP~`nNpQTTI$zw0vI3w2C^~$g?|qNnIAAf{1_!E z{d%O(RF#H#0453lE(VG}*eqghf=A;4)pGt9)I-|^<>@-B?*9e-FaR>4#*crk8MFqo zdO^!lIr7`+4fdcwEMUS$K%i&92oEG+QnjXI1#pwbN1nJdq+M1e%FUWFQP}AGsw56jHxDQAV zjL4muAjPMmRVH^f+ z1JY6;z1YRb0Nnp#+zQ?+u-JND+G1WB2QKV^x{xN;862AgSJ(tLp*IVFZ39Jtofvlq z3=Su*56<$TTr9yIEk|dRlP3gGX@*-tEB zW#3wUE5qIeS6sn0V1_H-$}Da`P}W)SUVw&gWx`S5lHC~y%B+}24;QR2^KOvYV$c#W zL+3uftuR;fUnl0llYrsP-JuYmolk_d8VznR;#~y5jSnSA~{Lu(!$TfluW z41BW$BVYow44h^K;-0;fAYkkC-A#{qJ^Y)^=Jfz4sd^0(D`Q9yr?~{Qtb!9_=qra9 zSF%G4hi-!>baQgs!)gLv9|*GauC|n0w2-EOkpLR+;zq5) z2>&pF%i|mnC$t9QgM^?>;6k%Bxa6z?Z37pacR_mKlCv3f1VV%RmX6>>3+~Wy=p=Lw zx(Ho?LZEOc5{iN1p=2lx%7XHtC(v`~74#OWff}I?P&?EE4MJnkG#wos3*8dBm2_+9 z_~|y#iP1^ZDblIYZKvBqXFz90ca+YW&WR3Bcbx7t-9@?}x^TKXbn$elbUAcS=w8xQ z($&*_r0b>|qMM>;pkGYSNzY5akzSHskzSpCH@y-4VR~!&WAtA1XXpdyuhZY9e?Xr} z|AhV(eGUBw`X2gG@a_$E1}=v64B`xm44Mpj3#F&(s zbeQ%tSu?paons1Ry3drsRKirl)Xp@<%*@QiEW)h7yp!3C*^b$p`4aOj<`m|~%$3Y- z%%dzUENfWASX5c`SWqlDmUApOSRSwxvAknxXPH>UzKDO3^r9V$4lHt7bZSxPqJ%|- zi{35jTr|zPjCBL6GOHe|C95ZEAZrY3E^7sAJL@#tayAh*RW>6wJGPT-*V&TUO4yp% zhS}NK1=*F@_p#fupJ2bv{*e6z`$zW4#VZzzF4kOpXfb|qz~b1&j~CZ39$vC!$;Kty zmK<1uTN1D&eo66?mL(HQS1y%Us9rnt`#gRHm=yd!g9r#711k- zSG28USShqpb0vD^>6I}nOIEgXGINS>>Tud|UgS*Te8V}oYQ-wqRVJ%ERz<8TSoML6 zfomg|4wnO0AXge!E!Pw`FSj~3hWi3{GWR>~@zp%5x2?vk_FtW{x@Ps%8i6(2*VwPQ zx+ZH)^IFEWqHFi9bzggXZOPhR9!?$=9yE_XPa03dI{I~@>kQU;uZvz+zHXG4k5`-5 znfC^7F>fy)7vDBMJHBgtg?!!oEBV#~a;F-YS`gQAfuE(#x zv;NKcX+aS|W5H8`DT2*HY(k1cRzlZ=o(c^L^9$<=9~Vv(ZrH%OL2-l4hOiB#8^$+^ zY&6~Iw=rvDm&j@n9T6{)M3JUVOEw`l9ouwwQ}t%%&5E1tH{aU)R+L^;PSi#;LbO7R zUQAxhR_vBoPG z`p5M1_A&3%-xsm3!vJA$+@REOrJ=cDg5j8vhEbqVqwywVyzx^L4wFMB@h0P@TBbp! zANEV`_u2o-Y^|BCS@r>z111OV9~eEj{b0z!_Cs=q&K;^fEOOZ6@XI4>k2oADFy}Bw znWrCRI%;|};phxX4|NwcYN2Cs(_#> za7_7F$gx3}-7fcC>0A%HX5%QvCFk<+H9 zbIn+q}*Zd@SwTl$w>l)4ytapn^GQrTt1 zmm7Gl+W@uMi)fur47mkvi~9g=~dq3du!YMWc_MANM}7e$w{T{ApwH{^IIq`<}fi z*Iv!^-BI#X1QE>#%sCP8E@p@WL79tWWQBPIS*S@biRQKV%<@>IBhx)G#ZVl6oCz_a={F|3GhqkP1 zx!bzAHRXf+hk}n{XEltrejG*XeWPXe3x`re)o>NZc-E35xlIWA6iPe3JY0o1F--dxe+=8rWb$wq5t+_nET9Y zO;1lpPe1qIPZQ+F(DFreE9eCn=$1qD%jp=F(~+COYfiMt&*(r{3o+9(%!_nb7BMq1 zvNEuN*JiPUVrB*aA5@}#z#|40`bBiC5F7h4@G2e#Mmh!t7$bUSRy-X&1LJb070l~d zRtiFk5S;4LLaSK!X>g&0Ww;HFom_2kb%W-e)WMCiE^KR_RLY5bG?YK}HR!IEk?Zyy z3fkyR#wMm~)1JQjG-P=i7kma2onBnkwpr0?7%!@%yi;cv2-d7^Z0+3KJv_b6p7T3@ z!T(xFXxQ}|;W78_$Hv7cJj%$-%FfAsR`R^`#mlnln%cVe^$nlfJ370%zl@BIjZaKY z0rKe>=ouLqm>3xunVFd!0m{o6*RNngFhhbX)%USTqd1Q((l{w}b(OoaSfRN*I; znl6LfA5Y0{2r^ua*7|xkZKK>8Bl+!?B5bawgLmLye2p=96NNKpDF_d5UVAO((X;B$ zBO&)PN^06iH))$%DY~5ty`TBKwqwlN-7hRQtF*3jeCK`}kMq~#vR}OKno!a)v-P}i zBR=P4efOlO@~#7RUjE?;xn&JsrpOJ@Vjv#+fb zP0?g%PjVv}vV2R1-tu}AMaE2LW>kmC&>bfN8A|3OlJeBP5I*kd;F!MNLa6O8AntAF zpTfAcPH*%ho#<)pMy3^YejJD-vb&NYqVxE`X#Kb$8Dg`RA~Zc8CS~CVzPN89Lsep# zWT;*iIl^*;4CxR<$Pkj_I2r0X7)geD{E7(46}gcUhDxVN9SV`7c_{?L9BtB#!&#)4 zcgRqb^7xcqZ_4C^cPAOrXd**o=#c6((aoot3_ZP3&OeUGCqqfi-cz^AkRxS%MPs@g zM7p}7cLWTfqPP_~#RZy8eH>`*N$-y(alSc9hH@@<5}kTltNZtnq5GzeWGKys(6zLH z6g(|P^5vTZoXA3wp*jxVAH{NHK`IMUS+JD_TUqd63**YdxUw+XFT`LAG1x+63??l9 zKZ%UVZ$FYD4)L$tBz!?Jm|9qIkfC&r<91{ySlOqK(A8eXKQ09(Wd#JYi)4tUGc|Gu z%uedJAjfLziaxd%3X-8WS=oe<#b6FKh8k!cveqj|A+F2OBz15j$5VP*2YtQQkfBZ9 zuAcg1Um~ z6#Rg1PxC^-H-3=cEpX}gIzg^l;L;y(sd|=6X5&MxB*RF-qHyjh3|NafSar|MZ)zzS z(k8T2j6BKCdc!c`H?^BILx$){{ba~xs`H`RKp(P_Xx&V#Xz-YMI5CqO`JAJp5Z{o4 z>_U1rHX*C+t3Ha#ZB<=WldN?Q?{83uzb`7lM_rbd_ZVv2R*2oa10Ajs0|sI zT1$rX@~ZB+6Q+)lp`DS<$Ppxk|nhfcu8LgKFXabq$)u4J0|`HpRDG|t%jak z4;a3XY~KrrE$$&hZU>u0s=8`EC5Ru_#Z}$aPLf?)d)p}4W>tq1pw_gj$U~1|Vrpc< zp(9+@B=;)vl0nFD($*f9_r*~uf9B^Z(n0&P9PD5|ZWv6urrkCsu_b%^B`@}Aw$=e6ca!3Pqn@s{+`9&KM^E2Fz{WQy6*&8d35py z8Dj03yff(9W^H*qrtkLai6_}!WGE4wNgzX|gGBcNm4o8>_Q=A#aeI7=*n}F=WhD9C zQzM^3d$+3H`#N42cHPr4+Zx1l`Heik>)29@<|KJR{5NLodnD=33-{3mK}t4Hitd-6TT@ z^GRT^Y-DJ}VjLVLaSbaXq?n2k%9uZrzH$(;J*_?4%Oi(wp-JPCMBAR$5!Q-fV0Mue zgDGTahomPN8dvfjpBi<^nu&7aA6N!@CKW6|`hSLdU!suL-G@H+541-&L@300H{wQ* z^fu+SrNmDQtvp&LEPj|rD$1|!B8S-DCBQ^E49uSK_dwH|jnX9YL9@$lSLa->tHS$OZVT6r;cpWf^q`@{|5ZcEG zV<*Q-r$$^-X6~4Stq#Sa9(O%L62CMVDmxrD-4r>Rm_m5FiBRrJ^35s^B(C8tAwvx; z;AB~J2%#OAA?X+>07ucLDu*R!?$r|tfXyDr9VgQJ&6FZLdyXrDU5~3x=ENwUX`+{s zDM=sLVdpw?_{i4+lm(9cAFpF~3D?b6d2@f1e9=-m@uYFh;mC;Ir72Jz=+oG0cuP;UFoQf6XFYG~a4htv0OE9F;9*~Xi#!bh2{-SIvv;>gj4B!!E@R~@Zt zVif7}4qvIJFZK`DziHUp#gN~ppu*MZnsG!~?%4r5{h)%f-xRVj-1q4VgDS_RY0(}rn~l=OxccLtI_?Tj5V!}9 z*(Ss#JxqIAZoJdotK-d)_Q4%Jx!UUW&y<$C+t&1%o{4_tTRnx=1O zr64?VyH2L(%bM+EIK`P;Pb`@ZE67|PsvBz+YTmu;DPpW!|8wA@_%AyeiIIg@#GE1? z9V6_Jlkk1LN1tJgnfHM85yDebWZ1@duuXnq#jd@Si6=L@`kkl8Ojeh8`@IkQZ3*ye0W!@f-!%p zK7WUojAGHmUhAQ=rO&R`%%ICVc^y56ZVeAHud#e6(6jnTMe$R)m9F==ua@$a@i*`F zKpQvL_`X1qp)J1R~t8q8Rfqi$q09Ks%-ITgBd zl+KYsvSH2szlD{r^C+jK4qy~>YL62ub_{2w375qZQ-b-y+ol<$Svp%FK|4=h4pJ>A_ z>P^@X=f?6zg{t7$wE@QT*=-SII%Oi_V(s4xiTGY1a4^-+4mCfzvR1l ziH0hCeK4J3-G4cIMBVq&t8;NR-Y3K@Hl&Rg9^KaD#w1j$w1^B{O3NU$_^D4v_$h#G13~7^)r;$c8yXobX8anf>2)I3zw>Sg&5{|j=ujYa zU=wr$^Tc{~KD0aTD4|}=uY+G(5a3pUpVV{~4Ly1GX( zG2VoDhT+}HhTFlT@Z^y|u9=-5I^7{dfO0aF>qlt6M}~&Wr%%A=pl_Lz?h^XU;~zbpBu1&Q@u2$;u(Um-&^ zHC=?hu$g2o{%)X&iH>zu94*45*C>liMqprN1IG=rRA!36;7vz{o@{^TTS}@Ul#Qm6 zq1OY`+F?=1Y%(--AB!BeCZ&|rmGifl<1g~^>b0knA?&INK*7cMuV^wvxLq>F-%&AX zoD)V08Rs9xOl@rsoHSGNCV58zxbby$GA+yT*M0tsvN``1#XlpaO?u_mRzVWIEkcHT z2kgCH24axyN1BnHj{tdbQ>BsaWax7N;6nv4=fogL<`!Xfd%%_SZ_b2sB&LkhKYvd-H1twUIsdlY|SNL$MGxih3Es>Hc zXoh!@e7WOt?+Z>wii@ICFRW9Xkr!Pf7?5?$=~6rT$@xYV`?c13s(6RDRnf`1C}QOMbJ4F~lp2nUd!sWP z?Rnn}a)C92fM8-!WKd*a-*NsA>%8g>c`lctQb!aoZD-;VTXiWWHtKmB;?YC>wyz_y zSGRCJGLkh)Ez#A{(Pb0WUS}8Q4{q4>Z*=!ub9={@&(%S8I$L$rtmBo8_ZctWwrvyi znBncx`_m~VJuSq#-0>oOf5AYrH^uO11^%(+#E`FH$7bC74p$8oB}|c_46m@nscEk< ziBHe5uQSe9NFY}|8tZfO7BfAO@X}D%^z<7!KG`HyUCt{tF%4Utc=Xb5ooaKxh)eUs z$^l}F5?|Ha-G_h6L*X=!&tgP@8aFiLa&5w+f9O3w)5z22}%=? zD6bPyL>rvj&8Ln^i^|^9!*wHt=ajSGTo<1?j*2%9HQP7%zC)X~xrv>-) zNBac-o_ngiKH>LOA-mAgy}xu~pmG8c+H$ZgH9S$stn(t)p)Xwn9qf#CY`$`8%^Mj< z$1e&)x&o%5wg;3wRvftT@tnrxVeg0S#LPBalVufl^#`?$=)t>z^626hmO+s4T8GB% z{nOd%neVmDn!avbrOk!@9Cd8;@hah^g?EZxl}_SD_=i4qi}EFQ&uE#6SB0MDKiJTm z5pwsGYJ0=M`{CTCFEQ3TZly+e^9m2$7vWfZdH3a$jW_Ht@$qrR{Wcx9D#Ejv3ktn7 zV$Qd*WXh>&)&$5QUh!{())>D!o{=?F))$5iQbZ7rPZmZ?0*<2-1n}QY_&q7=Es)eGFH&oV2)ZcSAQ+wYW-k`obB) zr5kIea#E#E68fqob6@olwra5wU&Rr2?AIImDmIgw@7v~rI~Q3n5_!`lu=8WpF5Beq$!{#Zt$O9i zP^@&{hm4LA+Ub0vh9YpX~;ybZ1jlIB-3BVMQH41MKPn0~pwC`?<2S9p7nyy@kd z!@R4dm8BLxco1{Wg!x0jqA~uDr%R*XDDk?09kAM5GBkL{(ew*3 zli=bozmu8YYvs$t%4Rjc(AVK|8}qJ+RA`LnOiLvYs_?^p;~_q1ZAt_}u3PY||4q-j zoxhXR*%Tr2f$;irXL|bNt@ymmz-NRYo=Cg?%XvW$p7t-v%8^o4${)(!N@7O@gh#Hw zQ2ucUch$(C`iZcs`c}KHva&@g?bj``JNBAq-QM8AH^qcG%9i#hj_r!GI`f%z%PWym zuePi!D%4wiDR{%p@&_@e9tc@15)wFlWruoCJBZbnI)YWE0o6h@p?jA*IN58(H_R{< zT~;*mdOzXKqM|Oo)Pqx111oG*>fU5XDF&QM z&K;jo%7WMB^2a7Glc9T?n~=oo-s7X%A%yPmhh*sHa>83x@BeE_xme`v-s&-PrULD* zcYK`NdVEJmvBgU4Cj|~WY(YiQ@cwd6e2C}j!S^%wyI;18*?hIV@+CbfCYINPD-$=l7`WBXKK&Hu%`L~oC9~2$#@~-O zF#6<1_9f!0*0HX$Q8dz5JtzFR&?rzm{m*>2U@Fr^?^dV zRgsPb6cCSfL{1?O6AIu>mZd#2ZwLcQq@7^1vg{3^ZoromJ>*A}$&4JngdgY$lm!dA zQ$57q(SZqf^A1-sEm0i zInyj3N}m#^3(|AMEAz*To(%*<6uCP&yxv{gp}^JIRDeuRSDNWJNi(oae2E##NUPQp z^NI=GfqprDzUdXCe11t$@`S-?Y?^dAQohi{k;E0a*X=$XfA7WmF1GsOc1w^GN_ew2};q=P{@7=i@d)YvCA7&rc6H|8l&MWSl>8XbgJD9vXq+`z` zBTc_QWR>t_a4o_WDLc%Yg20;8Hr71d7ABE!=LN(p3wbTQ!2L5RohQW2fVGD`eX%ob zyvyftiBJrNMw!UzH-sSMlyrLJ=yYq*ysF+)ZLg6dzMzh`syB(ZZW3roi|fo)AdnD{ zOlct!wc9zStR0b^t9x4O_<(jrkJe4s1CR8h{te92za#(S`d7K7&$prX%}DF?=?w3S z$DPz(^!k9;K{Q2FxqXg()xWL^H8?>my66zFBj!;J^J&%#_wQZYH&RT$=>vxayO@}6 zZiAQ@JI=pS>>lU7?K)`nVd2O}Biinsc*3y_&Aol%uc{0Y@v;zGVZW@w&qH0Lg7_tlc-lVR+tSk5LH+w(dWo5&U2z?MPnw{zU{O$vK<(nB=(#@x}cQYOOf*O-(m(Xoi z%I&-Rh>tgD`KLX_8NS=lhF71c^F1)Kj>?jCwQ4LIySqC&`RkLxPlipc(ge2CC4ukh z6ni@BhA&ROI^H|kc&&UNmQ+_Z+G<#*BWt9}Uma2}9#Qud%^OjoougKkKGAtp@9t~i z8@UND^0RE#$7%>2y4l{M(f;Pp&W47Un1Xdy*Ov&$CujZ+j$tQ61g9| zSj>ClBd2A8VPzb+QPX!}lCC%*VN9lL!(6xxFA-^Tw8ak7PbPkqPVmPDMsCPMC#O~~ zO<7tM(=@8|rtn%cvw1;}&s!O9cA@*V%*SzO)dlvibP=x$^(1&NR?xl6dWais9rmzDK=5dHn(uz=bW=y_onDjA z8b%Mt*L$+|lgQAq(EzNVJjq4dx^C(q$(4>)`z| z;zfbAelMgmj=#rma=6{U=j{5{Ud>pJ6`x>2`@f!V-&NzhUF1GMP#v9qW4Hs8;3mbdn7zLM{ zz5U*$pi|tDyC}bJMzzfI%^iK43k|2DuGsB!e1tZx^E4|7KLHl`(r®M!1-3YMj}9wU@$@ArERmVqB(!J2oC$c)G6k(Lr(7UiEVw!y1!iIOCJ ze$H++Fl&|?2=Gyje4ea_GH}Z3z5V*$ZAo#ay-#{Xb+Q7?mjvsxvn^>gy>$Oc>bi3; zQ^clD?7r=O|GlRtAGKaU>CCMUJt2 ze#QiD(ACvEro6W1A;Sr13PQ%_OZJFQ4FET?jl0bJ>OqcArlq%=Ci&}Kl^yzH>T|@a z%yk%3)eqiG2`t^7m6<7_LxxbUDp|*B4bYo1>X#TF@;ZO;igmi9sY**XI^zIG-R*5r zlXNB5XF}A`Lo9cRbuL-;V?D3mbdfG?+CLTic++I+-M|~X$HUe3&&2da-ncdW-dxZ- zT7J@}yC`kQ*k3Uwazei5v0 z4)fabuU9_5TMC^!S-P-~@n6};STOwWR@q@)OUfjk$Tabyp0$5<)uW0`5PAoTDbZ1gVWi*2F6F+zUaU(k51zIE9YOLQteXkTgbEpTe& z;8}|+@nw$5cN*i3-us^iA@eoI+^j;uM(ynCXtr?A+?c#-g{)=6!xr50IMz&yN|1+a& zQVSXSxL#+MJo3%Um3l3iJrh$QTny$7rRV!PVyYc|)XYS(kO#?7YH7;x-9Fk99L0CB zjr$Wxdt=S5H-7+Qcu6w!nlP`vhA+3S4(@i-=DF##5`X-3 zV}{Eql5BGG>VT-1=r#=Bsi7y2ME!$bEOH!G>kLHS+jp$od1cE>29DG{V3W7hPd_F9 z7~=HN>q~1q!-i4d+(A|CmBJzJII(~DiGN)%cVvCReirQKf5?7{iarVwZ|uIWZ0WiAvvJbR|NYM~6EoPi%MEvB{fOGbM(LY7*==1Sh+59Y|oascA{h4Y)05(7y9Z zL264|y=QV&sgHb?=ury~`p=xm0lTP30i7=P{*7;@i?%d-Y)~c{CkM6 zZ^wU;D1UGprKhQruA)Jg86k7+`W2y)KJk}oDsuV`1ngP|*0Cj>eIZ#b#!bDSbWL{_ zZb6sl`&9GGAKr%WGi#`!I+7+WPMd_X55?Q~Q_m$V%~+_F^(r1WovHO`P2ug?JS?xz_RSC&xDXGnwx?4L9+>Pi+evuSc?eC}NGZ zRW9`o^SbEu51agHLD9llwEyl|w1qj`&xeU_^vp@*4L5~O{*tYF#%^Fso)82MsXp}Z zi7f24|8lK8tK;e2%Ls3wjLo4YGM|qmoLl`hCr499&}wt}ut#m-je{#y%iBfTo4W@b z?~)-rw}aW{C+phVCarUjcWuOCMuS^gTr~z7H4YroA@zwHiPc?)Sj@@s7n9K zH1T=CPE~l?wa-4zCJkqNy(xrOLX-E(y|_CmQOU9X$^NQ`=l(!@`nmc8^^ zuV}aEP>%0~rj1@sH=8ojxZ)zFF9%1TO3q6hT4fN%s)0&)B9njYS@w&4*IysH*WcHC zssvqrzK-kei9JOPair_AD>!axeibqMBG^H&cf=mp4Ngd&`docIaLj=a<#A^cv-RA` zTJSPkp~B6_FHT%8yx$WT#H(JQ9EQJhv(m8tIO@<|-|%pC&U)V1oVX+D4*fG4JD>Ot zaGROxCRU~B3+OePjAmd%KlRua26!AFxta3vTIIEw>kQTWIek2#70!-XDhlVY;+iZS z4^;LaufAG&e9X4eeeMM1Pp>}`{=+k4T_H1%NnkyHDao4=vaGs#I}(ekbk@6CTQ(pu1)k7Y3lm|PJ)@?~O;{b8}^kM3_atP}$~ z;2y}}BH||&5;#_S&77F03hs6#2dWY(he>gb;F4A{nEltb1tYt_%B3+_l}#!DxA8uZ z_JaFd=lQ4kN&5(6z2JsqWoOEi8li@VFa_S;wNU^6B>pS~4u=q2G1M_}q0vKPWa8`B zMk3$X{f4`5&<`VGi4yL~z0;zqFV81F?zlr@EmTo)=_`vYC^3D-6(9H6WAw|V#1oIR z+&Yu(TDMp>X6aUyq`R=1v#p9ZSX8zn=@i|QX)mcpC7IAn`xgUa%~{2H`rEK8Ornme z7pq99k9;ZjIg`st*^o0Rn%P7kH4T7s+TgWqEM$m@TW6Yo8tA`REl@s%qCUPOCrEAJ z2=$G8aBMnqs)*ZMis0!}y9I|whE@>sO+P4*Bw|Yfi6n3C_k;*!yGe)nlxY*8Cah~X z6xnXsJ}}vTnv@)CeyGA@do7Bx0nMa3P<{Ofsf*O!b?aqN87gxCkJq!nZzLd2%bu3= ze>$f2w%noj{_bV=-HDra7@YHy5q?Cn!CWj$Oj_e~&#BRSV}15}r+tEtGKYozm)Pua zSk16&?Ft!U`THM|)erwtkH@Fd}4+^*+C;w+@jbu3$$wfk1gtchoKtH=$+caj*aoPc#I}^aJ3g zS2_V~BpXK(!IUWJ7PxjSuQ#RCOsGM^uN;57fxuogAgrcOs3w6e*FJaf*6n(5{=71w zf|Nk0eFN@R@`w=E^%s4KgkRC!wW8>3>v$0VCgc|a=x!_z*z9*GffEo1mIRXm+|5Vz z;J1yBu$n&|n10D|jeiuGK$t!}Jw7!C);vb+(gDtqqv_xl8S_hU%t0k(3U~$Z*7PaH zl#lMj&wgbbQ;{`DVlr`>=&b-=2QFs@CUkmJ^}sEh1{)dCx9VW}z?;VZ!6hQ80PF}7 z*FFGyJF!FuaHCW`jZpcf2c{3aFr9Q#Yyv2Y=lY@3q}WkCaOl6t7u;P1eu;G1gfMDI z%ES+hM%5#`I`L!((Ac%~MC7%|!7ws(p1AUB*k^P1KCt35$rIMZt5B($*O0wsubpqY z;_>_F6lF5x?9^+evSpJS?*`lFCbgedY@U%Wk-QM0nYjP7cw{qi*rj<;}d}it0(>78H(#-D_|4`D<_{`uF zGGr1Q9p8(rr0##cjGjybdspR!fcj4rV*{ko9DdKlm*zupL!C2UOUMu}uLVC4NLeM& zk_w~9uWdEn-ki8~zuxtT=Ki|79eM0HV&HJ#5O=h~^2gYut4A!C8L=ivsYElG-rv&y zraAk?{aBJ@#yIaHsT%bpVe>t2byjKVzg}Z9n!X=9jelO3U6RnCJ{iAmjb8BP7s#uO zD_Cz=<{jw`8+4LiVVix4v}bFLU-;EiNQ4GmPxtUlX3>p64T5w)`2E&q%$3tlV>?=6 zqGJ16z|n7k2)EH%FOQL}{&$WBBh!X5mgiXvOFes7vtzN#J=H^a&WE2kAl)onKi6>B|F1WL6qgfa@7}vve?0gPloR>vacIk z)wP>4Z-a+>W}mDoUY%BNu?=;qb+wHm8S)bQ31Nf+V?qL z>ugklU#a0~+TOG4l@mb9;my``!TEzCoed4&TsOGaFKP|mUz}~)Re@E6< z<7%mC*T+-KueR5w@gu-Wq$qIHd7FpwQa)B#Ta&gr+0N8R;opprgz9;94V9`Z_o35j zj0xQDm7Wi-551G&~fN$uU{JB5!|c6eQMPqEE> zmE`J>rRyj;D0c+;kpHr8L(vO-f?v7bXW}q`$?&X1V9xi3& z$XC{+7O_DdGQ@58sgy*9R4?`-Uq=olx=Iqo`jKB=jd%hJO>-Ha8CM4zFor3~*7<@x zQd2*jhyE1xyRI|OfJ1MMR3?1g>${gQaIJ+@k#mq_;(G{ed`}ama&N5|7MV%RBSSM^ zfg3c5NVzJR-`ca3vIPCpF6Y=Y)j<%CoOU;TjGZwky2wA>CNG&U2<{sl@C+k`a`TUR zPL->HNq-17tf=!G$JC=+ym}~7pfZenp)UXHFj5O zodJ>)T|LVti%2Gyfj{;FM=JyQ5*yz~NBzO(ye1M1|5utTzS=(;YXt|@k6Pz8rpZ6( z*kkqKiIM1JH^%0*6OUX#oX*#X(@yOxq(VHV-djf}T(S+4=NdE5>2u?GeKXIu-65?( zu`JSDkYg3<^W#%n19xZkl}+2``A=iBZITU7@|Q1ve7a+iz+^zydy*MpFdCr9zp2}; z(`Y6;0z2a{Fj*oY5$Rf6Q^38$O-<*N_PY1CN`vEW;Lrx%%&>YgZsIXXc-5#rlh+GA({V}1W-XJ5CkGFgo{K(zbLRRC zBN<{}>xI~O%OQ_5RgcqEQ`l8g)^>}*vmRlC5<$O!ou4&~+wcOXSQ+_`ZDw4tsKVfc zzzOwIGu57NFD*JOotP*ThdF8-asq=vSv*+sgpp4hNG4vWQ(=g8f@4@?-Sf{Sy&i=M z;~O>{ zRU-OJ_Bs2!^WNF_yx+O+@o!-LRx;NbV}5gt@B4;!PV1O}{>G&!XDVj6!t*T!)X3B!oV$DTcAu*nU0Nk9kQKtUrLBuI5<-b^K>Cd7EdXp3$k;;b2V21=?;{5I}k@e5vH-6wJV~mA|Vt;lFK%h zy!v?r8Gxjwh%0O$ZO6Cmu|AFIP0{{*&au6YOGszi$kS&pW>p7_b!HZIC!E#t4j+}h zLz5zojT{6^i_|7hwgEE~9#8)r$m|T> zXAK?=xW|LA**N8)fIVCWkUt;Wk9PwYwDQAPLpeSfwk@%-FdZ)f zzOra35`T>V@Fb;hnLrj1gRR6}+M)wQ>QJOW?si-JE990285G_D7DH+f(_GxY#4qVnZIsV|=S7I{+(ZVEo{h$%3qW^&9x6 zTY#@EzB~=+x5Q0tP@RN##FJwI`}Hr^EElOmw5LQfL5Xdr$uxk2`!|bBz-4-Lg06PY z2pGq+f&}1ltF0Ni+TI7q>Q8Y~(v{#$ew$Q|Tafl-0L!Aj3UIrH0hz20=(^@5blY4& zA2LJu(@!RKQqQAv(_s*cd0_-zxn`I@Ij3qlNLyo6Ok2;TUTYzCAULhIqcx~eL)Er2 zx4a-Kx>Ts^vpcIYPNeUoGb#ImvUu-we=bI#>Nf_kZH{2fFl9Mzaa$%*f zs)hv6Do@D|v|2Sv$;K(X11}UW*Ck||BXrG4Vr#;^TA+~b$8EnyKAzVvD-@eRKD9qg zIc;UjkABrOuishjBB157uSBe8@S|#5SnK2pu_9%)v_<+foquXXQf6k-y|3wBVj=Qi zdTy{B|EGKz>RT(=eVVE&mrq>J+^5754H3RWqY-g0!B;6QSnZ@*OUrdlRURcS$exfp zkSS0?``cJ3Z2Num-2C$ob~ohyk3-HE)drn7u*mz=gP9mrgo$izdmWSPWQX#Fv5C#& z2P9p_;%}R8?Ef~%Sd}<@rbX<~KJPkv<#!Q=mm?cB>ftIXaOTi1I9vVMLP6@u2%jb~IE76U3UZsyQDj|#~BV36iECFH~`b^l3d*Z0^I1$4#f5v4%JZg?pQ!`rl-rGJ1 z#0tD6j9j^qbQPawPX2FTwtq`J_3N-{OQ1r=T6{)6%kt~rK8;L&=vaHGmdP>FUQE`} zhJ-ktN4LMJk>6Hqa%TM=zQw_Wm#r>}&@9CwbBZ<4bbSXB=^A;zS8VtQaR(yj>kB~X zEp-)gwy63ZAK9aZlL6b2MRN8I-|%#+7kQd!R&P6TZL6o1@wg4Dj6{+y!oR{BIX>A| zP31O`6lcq8y$(!aCDQnEHM_?+Fh!r7Cj=tmnPhIhi->>JVZ^3qd3fT}N3hcs4K^3e z#Mo=czN%uN{XYNK+~9v?~ZRZzFjEp2*eUJ^c1`Xcx9ER!WP$W6km4X*v@sZYM*=8aXzHIosXmsn@EqzU9A$D z%xYqpq_asV({VX>-(TTLZQ@td4n%|$j7wgO=a+W7JkL@Y-+y)XbI;JdTbTaAfhQOB zUk)<4O9f_qGGBCkXLc*hmG6$>X~QE@&XN~ov=7yaoM2Nr>8tsS73F#Y09WQGvTPLs zd$g$OWg1xh=@s@$JRb{GG<}-ppPi}5>Ps(A%Q|*!Lc(Hw^7ha2+ke_{?zY5tTjKwk zmiVv3?cW@+FXNb`ElB9i=cV%FoA}`&pRR6{TDa3@D>f!XKQ%U5F!AVQAKtWKw(^TF zy^gR50}mhHzREDWf&HyjawB#FHtIRthmMX=!fRQO{drTpHp3gX(eTqYxR6utuS=zq zh0kVr8m$$9xjgopnsr*y_obVO-#gn)(Ts`7k=Syvw`!(F25h=ye7BBOr>ucaOtYq@ zcf*&b9f~g)+3BlB-W#p!(}s*jEWEapK8%MNH|$er5RQ)tObtK{mF#1kIK-;$<9CX# zzavz3g-4+guIE5}RWlJY7$;=a2od3E@~akReV#-{hH^s3G1Y^H0#)L3ik8yqYxBpJ^$0d!GkU}q z$e~`z6{`hz)mcR=(=kGhy|o%V#dowKE{zl%xUY(+z|N&hHx}Hl&7UvSHV@D6hp!93 z&l2V9zcHVTHID7}LsXB24fBr;i#1qc<%`Xzw#}$IKg&T6eEVS8W-IMF#&F>tgBgc# zkPI~wz04RrVw~pQWUm1kNSc3hu-#2Cy9wt1c7pjW<0RIMPBu!fZKCmK-uG{=;kUCg zH`ZBSqC_#)6@p_K6=;!C+gcyA@;lC{fi<<8X*Qnnahblx2^F`l=R1Edn!|P{@FwatAue#SJ z(31#6?&*T^UU+p;jMSx83BB*)(JqrIk6$pn_GK=1g{`iYbAOU$MCP#afmFWLu)dBq z>3;pkUqhetN2TMfwceZhkVU0AC~x<^J45$+>=NhpD_h*#^|=Nft89^Ds#e|AjbZ{i8H6V>9x|gj^HgDgkqvB zCG14R3?sRDyc=JV=x)oxXE*)z=pj~0heCqrVOS@B=e1Sg(i#l2j}MK56(>>HPoOg0@k2TOw>jS+6NSG z^I{4XyGidhx6eWM^o19kd4QfpBnAgQbw*lV5T@-Ko1s)&G53GUIctipRXTRTgFcPZ zJ+yJAnWrNh?qn8$&{C+tGs-Eb9U1M7UF$%xs-MPCxXsm}M__H2NV^->{}y5Wv)xbzA7fdT5B$$SdT{SA5!%)*(hd+Avcb@9ZRYFh_h0L zZOp-tO+x*`_4Xi6-Tre;1ELyfY>InjuBoJx5aIT(3v6PlVIO)5UaX(#uVl1oX~fRm z!O@q!Mioh{t)JQOBAeU)sCxDsM6-HFC+Q}6MRQ*WNom;Qe?7SH)_o=~FF||Cx%E99 z`$i3l6d|ECxqjjmq#0VbKS|)+^(6f(Ptsi;_#dLf-*>G+ivQye@(jlnx3d!y(A`9h*|~3LG9*rK=M?cu8D2+tU;RRKp4TAEM`d_MwIkDl zo?7of&OT^Ih1v82+Z~LG83R<+ANeJ*hp-ebg)k?Nz;%8)6*%fk8?N6LzvH1w6zX5o zJaij+f0fJ5UL^S4d8-_3-U?pg?9(@7O;OFFj@sja1`3*|Iow72=8jO-igdWq5fdC> zj_xD6Sw^W-3*tAL9}WpLroXah_x!|xl&+F8SV_(np82!n9>6QvHT(Swv)|po`ZIww zWI;JzNx~Ig!HW}C4$S&9cZulO$m^l2uE_?aaT9rzvcBE03z zb4TG5psQp%)coFQyPq-Mn@l zW%7a9sDBVgJ;Hl`=n>5|RttK)SQTz}l_IgxRtE#&p5f18L0eYrH|Q`az>-d>>&d+L z6yH^I6*()o^Yn{eMTtRj*dF+nU6tMNa!I!N%%7yi?Cxs2yV^gprpb8)Xd@E1=8Y`r z#~u;$zJwsA{iwVxNp!g}CPw^ugGz8}3Yt)vY~VcKde_i5tA5O(yU5+0p_CWRW0~%o z7G2=WXl!P7I3HQ=(dycay)%q8YxHx7`>N`DB1s6HCqsRTo0je6aXK{^W)N$Mvx{sk z9eBfc{#n=A&imee!8d64G_ZEj(@t%W=7Hf@_PRiCj3`ceuQRh$@Uvbi8w5i?k6vB+T` z2v616&*g>>6l&KTdfksbB83pqa2?bOIqc-923O$;YGl7i-4f&Zy~M8lP%LKa;#cX1 zAJNMq4KQ}u~Qm!G>?&(-M6HpSM|W$^GiU{LVY0;L>s+_|-cQ z7x9)`l%9D)Sl^MxPQ#PmGr3npHs2MAx+4p))xl>a-U_*EGpYueiPhCN)|%Xn&rpm@ zimDzxWgeXQoh{I1L#)Qw*A{0UE+C#nn~|(=V9n&?J6F~mx_V_xOYu;0Mdfgc@3wP5 zLciRRqv!5UCHtaRo_z8U{U+^=y=-oKr@UX%;(^WW$~XObm(0H|#aLL)`5!rXWmb%8 z&#PqL7YuLeR68?eRpew9_9~p^9?>4YGzb^%TDd>i)aJl`%A7OxZFC46EoEv$FKc^P zYkleE^OHOoCn0;TLsqF$#W8L!@83X6te+&O1`i?E3%w*B+x4KiAI;#Sb7{aT4iyi!-Gd8Vj4&j$Z7jeX+C3nX;ky zNUE z4}ps<)eTx{lQaR_#0pGlQQ2*+J_-qY5wkIvM#X}dItLSp)`ZyD!(4o}l z;UQre_KQoLB0Mi&$eusL-p1n5FEx(5*Z9Xd`ZvYszoD?FDuA%~Ha-A1WleOfAJEaI z!wl{~xZJs(IMc*Etk6t0o;wheE2dA~blpU`8#s2VMWJSV_|CZLAikAg2TFQZ?iR>r zi#^H&&hPH=82?O9>mKE89Sq_$KiMSbLV0-nWTN{?&-NBrr&E4pX)c;K1!}Tpq2qF@ zHyh7V(i;OUT(^^@(AeJj*k39&T4FVz!s@y>;O%oB6>?Mi{Jna#{l{}%{RaAdw@OZl ztI1yZ+E9DX(@N&MRBLL^>}@b!=JAK8Ss4$uY1uR7iBy0|l~1{c7!b9CTg^(5mquZ_ zU*H#9loq0+?@M;)^Z7e_Qj!QUx?cWF`_t<>O@b0u!%VUUUt!$yTeqKTL{IQ$_=KU= z;j0aI-w^Zdo?%g#`#Byu-%3LIWhYOVkjHB>pckkzL+0o<72}MrX7ZHlO}rO-Pa|L{ zh)C>WxJOL5OR=>QH|QEJ6UpLVz3`}Aw-++}!Pa8Ii+=w|^BD9pbMcQkKL?SO=bmqP zelF$cTX=>#&jA>}0la5_j81wpjHDcYL8=j2x%$z0;S-`(DYHX}pkMep*9@B zmh3yaSgeMug&S|Ahxd7=1}v9sDK?Okbipi~H!16=w_TLj@ff<*Ww07rXwudj9{>-M zfklMd^y^-(e%P@`j$IB_6KCCyhD2RJPUUczkQA`6O6JUjslqA~N{A4J z(Jj+msU=$;ixq`_AA^1MOAhaXE(Y6>iZ#Mxi7UKxa&pYR*6RzZPOt3lWESvleF=44 zkg9#{$HEGg_c)>|PG%bnBDfRi4`a=%Yb&C4AnE;v*`|` zF6tF*m`;0O5wMQIDhQyw!~0^}3d?Pr^=Wzlw9 z7`$0(w=~>$u=`0TmPttY6xLj|SN$rz^PSbYJI3)Uu8;cAQDg>9kuNeL?uHHarGv69 z?nNR4$yU|=uwsXg4FE_aj*PXyUeX)G9Eja~tdU0j6FDTWkUSVZ@f*;3G93kTP=#sR zt%sG@P_aLCfV+g2|5|wQiw*l*LjJoSIOrBabOwA7DLTe1g z4M+vD{5s6nfI+zJ0L2w_MFYhRp>(coJ&Zr8j=uxwzq{AJk*g>ca(vHu8P-$ctb1KK zAWBrEAMPz{@f6*mnI$@mG`C|<$L8|^Cc}K^OK>O8k27coN8!T;YXi_BM2XA`Unyci z7KsUEYhEBcI&69NJtRD&u=Q|Z@&UbrR}1Y3d?i`LjR7v-3D?-^#{uX!vkv_qwBBAh z!}@6ElB+Qo5>V04mx#|juJ_dVWXb zThAP-7%alLgD?Y?fCrcXO)NxKhpo@kF_lrI zL0NeVCYH#%E6RQck`%w1LusxDCKN!I`fwq4lrU(xI!Oki zn<(1?7t|td1W91FCmq?ghYeENLhA)yzZkO9Cb&j!(9P>XnLaM9ZPZ0OZAu`EoN^pX z4t|MBRZvUEcr+FO<^KY1c%zCg;Oo?E@Jw=T_ad)abYuYUeJ!7yc-Ry`(_;&u-UdXO zc~s-4cOaH92b!(kC%xn|KoVYzBil}^??CQ*-U2f6HuBwgN-+TBv`C^P0OW>1JOv@j z0pSXqfa}4=;if?4PBUi*GGh-Q`0uXChLSE)5np>q66Yw5x!V_qaFlRd2Yg!)`28+y z){~R-k5fq=N^5^uSB0hSw<0OIxQQp6%`MO}n4`hwFkL`y!Ob+>A$VPu?sq$e)XU0&#V)Bmzz5(B`cd=_L$R3P+Qkr+= z9@5Lkv`@F`!XIz6U$&UzEbvNw#=SX_>PaE`=iw{oU(GP#L z=PJzN21Ra&&)Lqj5I2~Wbc#Q+up%@bFsFrHa7mJyUHYw%OaU zT`&=8Hs>~Da~KwQF#z1WbtqrF2f68~&QGGVuzBCp?;iQY9QMj+>alBf{9+5Iuxr(D zV02QZ?O8TorGsEt1(VJK=E!nWkCe8$PRr}!z1d3z8EDpnA^Vgdu0ax_eeWL>4zF7` zM|RpXblsVF*`Xz8E&>U?ejtH5{(NtT#UDHgKiKadM0Utuz4HG|nCxEj&!w0D$JWj9 zfJY?76V_yr=Xr(ntWQsN++_)YuiR28#(4MDA`@~$!l0ivPL20P&5E6dZs4WgCDnBx z=9Mwrq~a5D)NaL!)6en*`w_*HdiuRKW$|X6)Go&gp=YV&w5g*HD2Y%#quz4#aonH@ z6A){y8)g|URHF7xu70agK)>&n(ZSFO%ih+`VQnY>p}&u?ek93NolQ9s5G{o(sFE&i zzUdlzvmC!&*~enI^dg~r0bvAdM>fosEJ}?Ql&4$H<+S=xcwbB(jyugox-9M=2Q5uT zXQal+m!^gYXFFKDMU+lT&H)RK%3?g=@3>x0e%gL8tDz;$TU8E}miAuzAY~d++cubL zQDD>KB8iE4onx$U?qr>Rer8^V|BD;685~gdj(AY}0S7VQuLQOW$_F~&uarUt<)$1L z;ID+DWC6KT&oHPrL4m!}3h*qk0DsbV|AY8mSbGormB4P?ZH?R-=*9j13Xc^a#xSLA9FT`vMqmN9+3Vl3-`ASrUfS_Fvr7hSXX==q zF3e7)jSj0mt_=S?)QshSHRdKTg1PCGA!3wpOq1g*R8Wz)7U)s$VvoexZD2yIF%ctp z-Itn59B1iiw`pmT9A>wZ?);{c`kSuycSH{YjgJ+oa6r83(tlo2UXOUdT*d2RBh?t$ zALHwzqt2&lmKW}*nFUv+=gU7W)D#z~rKV8S>#P;ID3!C8{X|ck!Rc`NGApXEGxb!7 zi`L}}t+6$=k180?prLOQXH1~J$VD_PCRTF4xV?uj9(!n9zBl=pET>hOdX}VWXC1X- zK>7N69_&NYYpTywx@{Y+CLLUPR4$8`=DMxBMCLX(7sD@v)i-#iAQ$*#=^Cf5`KW1i z%wx7qPf0b=&VM^+u{s92-KrWCOZ5r2KCT4h$Q@j>A;vfMv$=Lo~|pQdPrMn28@HYIntSA?qK8__8gg~Wh(K^vE^h;s|} z=cRARbyHUKWmj03s2zikD-M|k%4rAQG@6?FDh#S%+1Y77ro}1C?Ds**lOA7jY6g|| z9|xr_Wzwtt0)ffrLvvEHMO<7Y7`W1AE%(Lc&yG{c@Ti)Yk_Q-X*nPCRXGPS zT}v~Q<_nr;IIm0J?;#GZYUf#5 zr4EEL#VGQ(pbFjj%RXz}UU3Md#d*QHka_t@7l{ETWhE4 z_kGQnqf;il6*&>JVlg@HnD6myZuTYii1qQ3)1BCJT=+^Ap9sclMS)m2^e+26PZJ}f zKSNphyEJ*$TCD{Bu-nYI#tK|B&r!UwbXu4&&e5m0l*CGWc`&^*Bh+J}b>;27fVxGp zloh){U;XyoPbjupR9oiKI`@?Luj<7As0;jNF8jYugTFg@{stcZ8((sONxV$b{k>PN zp>wXOjhw8beoU2%bRVsK=CojxGJP6piMSr(euyb|gQw{ttdp%|Q|7zI>5>S-yyzeh zpQoA|E*@)NK~WwcVM51J?&ZES6m$rdrwzP@Z1kK;3fOa2@n+g^ex}!vQYhRkr-@WF z7CAm}+|zjpN?b|aHzEDt7AM(_rpZ--MDDtk-qsdd))0M|&}tY__L^Dn>En3zZNKv; zXsYr$x)&}6zc7pmMBuMlN3x5eB4;&739pgQ-Lh7W?m$?R7b5+opC}?H=lv$;XFY2O zD>-*agqSvWjbtze$;HlpVk}la7u|Ee)yd|0|HQ|BWMar#C%*(-Ieh zTbUOFNXB0usET{rObwTva?2DbC-rM6XL9 zM+Rpt-R&^sh}{XE z)7O>#J_{eCwpDlRY*(O=Y-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ v4ip#hba4#fxSkxdHA|FPC?Uy#b;&2jxh_l`@A?jEgEV@&`njxgN@xNARl_7u diff --git a/client/src/js/App.jsx b/client/src/js/App.jsx deleted file mode 100644 index 7005fc773..000000000 --- a/client/src/js/App.jsx +++ /dev/null @@ -1,201 +0,0 @@ -import React from 'react'; -import { Provider } from 'react-redux'; -import { Router, Route, Redirect, hashHistory } from 'react-router'; -import { hot } from 'react-hot-loader/root'; - -import * as Api from './api'; -import * as Constant from './constants'; -import * as Action from './actionTypes'; -import store from './store'; - -import Main from './views/Main.jsx'; -import Home from './views/Home.jsx'; -import BusinessPortal from './views/BusinessPortal.jsx'; -import BusinessOwner from './views/BusinessOwner.jsx'; -import Equipment from './views/Equipment.jsx'; -import EquipmentDetail from './views/EquipmentDetail.jsx'; -import Owners from './views/Owners.jsx'; -import OwnersDetail from './views/OwnersDetail.jsx'; -import Projects from './views/Projects.jsx'; -import ProjectsDetail from './views/ProjectsDetail.jsx'; -import RentalRequests from './views/RentalRequests.jsx'; -import RentalRequestsDetail from './views/RentalRequestsDetail.jsx'; -import RentalAgreementsDetail from './views/RentalAgreementsDetail.jsx'; -import OvertimeRates from './views/OvertimeRates.jsx'; -import Users from './views/Users.jsx'; -import UsersDetail from './views/UsersDetail.jsx'; -import Roles from './views/Roles.jsx'; -import RolesDetail from './views/RolesDetail.jsx'; -import Rollover from './views/Rollover.jsx'; -import DistrictAdmin from './views/DistrictAdmin.jsx'; -import TimeEntry from './views/TimeEntry.jsx'; -import SeniorityList from './views/SeniorityList.jsx'; -import StatusLetters from './views/StatusLetters.jsx'; -import HiringReport from './views/HiringReport.jsx'; -import WcbCglCoverage from './views/WcbCglCoverage.jsx'; -import AitReport from './views/AitReport.jsx'; -import Version from './views/Version.jsx'; -import FourOhFour from './views/404.jsx'; - -hashHistory.listen(location => { - if (location.action !== 'POP') { return; } - - redirectIfRolloverActive(location.pathname); -}); - -// redirects regular users to rollover page if rollover in progress -function redirectIfRolloverActive(path) { - var onBusinessPage = path.indexOf(Constant.BUSINESS_PORTAL_PATHNAME) === 0; - var onRolloverPage = path === '/' + Constant.ROLLOVER_PATHNAME; - if (onBusinessPage || onRolloverPage) { return; } - - var user = store.getState().user; - if (!user.district) { return; } - - const districtId = user.district.id; - - Api.getRolloverStatus(districtId).then(() => { - const status = store.getState().lookups.rolloverStatus; - - if (status.rolloverActive) { - hashHistory.push('/' + Constant.ROLLOVER_PATHNAME); - } else if (status.rolloverComplete) { - // refresh fiscal years - Api.getFiscalYears(districtId); - } - }); -} - -function onEnterBusiness() { - // allow access to business users - if (store.getState().user.hasPermission(Constant.PERMISSION_BUSINESS_LOGIN)) { - return true; - } - - // redirect HETS users to home page - if (store.getState().user.hasPermission(Constant.PERMISSION_LOGIN)) { - hashHistory.push('/'); - return false; - } - - return false; - - // TODO: redirect other users to 'unauthorized access' page - //hashHistory.push('/'); -} - -function onEnterBusinessDetails(nextState, replace, callback) { - if (onEnterBusiness()) { - setActiveOwnerId(nextState, replace, callback); - } -} - -function onEnterApplication() { - // allow access to HETS users - if (store.getState().user.hasPermission(Constant.PERMISSION_LOGIN)) { - redirectIfRolloverActive(hashHistory.getCurrentLocation().pathname); - return; - } - - // redirect business users to business page - if (store.getState().user.hasPermission(Constant.PERMISSION_BUSINESS_LOGIN)) { - hashHistory.push(Constant.BUSINESS_PORTAL_PATHNAME); - } - - // TODO: redirect other users to 'unauthorized access' page - //hashHistory.push('/'); -} - -function setActiveRentalAgreementId(nextState, replace, callback) { - store.dispatch({ type: Action.SET_ACTIVE_RENTAL_AGREEMENT_ID_UI, rentalAgreementId: nextState.params.rentalAgreementId }); - // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay - // mounting the in order that `mapStateToProps` is called with the current store's state. - Promise.resolve().then(callback); -} - -function setActiveRentalRequestId(nextState, replace, callback) { - store.dispatch({ type: Action.SET_ACTIVE_RENTAL_REQUEST_ID_UI, rentalRequestId: nextState.params.rentalRequestId }); - // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay - // mounting the in order that `mapStateToProps` is called with the current store's state. - Promise.resolve().then(callback); -} - -function setActiveProjectId(nextState, replace, callback) { - store.dispatch({ type: Action.SET_ACTIVE_PROJECT_ID_UI, projectId: nextState.params.projectId }); - // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay - // mounting the in order that `mapStateToProps` is called with the current store's state. - Promise.resolve().then(callback); -} - -function setActiveOwnerId(nextState, replace, callback) { - store.dispatch({ type: Action.SET_ACTIVE_OWNER_ID_UI, ownerId: nextState.params.ownerId }); - // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay - // mounting the in order that `mapStateToProps` is called with the current store's state. - Promise.resolve().then(callback); -} - -function setActiveEquipmentId(nextState, replace, callback) { - store.dispatch({ type: Action.SET_ACTIVE_EQUIPMENT_ID_UI, equipmentId: nextState.params.equipmentId }); - // TODO: When react was updated (HETS-1100) it broke how this worked. We now need to delay - // mounting the in order that `mapStateToProps` is called with the current store's state. - Promise.resolve().then(callback); -} - -function keepAlive() { - Api.keepAlive(); -} - -window.setInterval(keepAlive, Constant.SESSION_KEEP_ALIVE_INTERVAL); - -function showSessionTimoutDialog() { - store.dispatch({ type: Action.SHOW_SESSION_TIMEOUT_DIALOG }); -} - -var sessionTimeoutTimer = window.setInterval(showSessionTimoutDialog, Constant.SESSION_TIMEOUT); - -export function resetSessionTimeoutTimer() { - window.clearInterval(sessionTimeoutTimer); - sessionTimeoutTimer = window.setInterval(showSessionTimoutDialog, Constant.SESSION_TIMEOUT); -} - -const App = () => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - - -export default hot(App); diff --git a/client/src/js/actionTypes.js b/client/src/js/actionTypes.js deleted file mode 100644 index 57d9d379b..000000000 --- a/client/src/js/actionTypes.js +++ /dev/null @@ -1,228 +0,0 @@ -// API Requests -export const REQUESTS_BEGIN = 'REQUESTS_BEGIN'; -export const REQUESTS_END = 'REQUESTS_END'; -export const REQUESTS_ERROR = 'REQUESTS_ERROR'; - -// UI -export const UPDATE_EQUIPMENT_LIST_UI = 'UPDATE_EQUIPMENT_LIST_UI'; -export const UPDATE_PHYSICAL_ATTACHMENTS_UI = 'UPDATE_PHYSICAL_ATTACHMENTS_UI'; -export const UPDATE_OWNERS_UI = 'UPDATE_OWNERS_UI'; -export const UPDATE_OWNER_CONTACTS_UI = 'UPDATE_OWNER_CONTACTS_UI'; -export const UPDATE_OWNER_EQUIPMENT_UI = 'UPDATE_OWNER_EQUIPMENT_UI'; -export const UPDATE_USERS_UI = 'UPDATE_USERS_UI'; -export const UPDATE_PROJECTS_UI = 'UPDATE_PROJECTS_UI'; -export const UPDATE_PROJECT_CONTACTS_UI = 'UPDATE_PROJECT_CONTACTS_UI'; -export const UPDATE_RENTAL_REQUESTS_UI = 'UPDATE_RENTAL_REQUESTS_UI'; -export const UPDATE_TIME_ENTRIES_UI = 'UPDATE_TIME_ENTRIES_UI'; -export const UPDATE_HIRING_RESPONSES_UI = 'UPDATE_HIRING_RESPONSES_UI'; -export const UPDATE_OWNERS_COVERAGE_UI = 'UPDATE_OWNERS_COVERAGE_UI'; -export const UPDATE_USER_ROLES_UI = 'UPDATE_USER_ROLES_UI'; -export const UPDATE_PERMISSIONS_LOOKUP = 'UPDATE_PERMISSIONS_LOOKUP'; -export const UPDATE_ROLES_UI = 'UPDATE_ROLES_UI'; -export const UPDATE_HISTORY_UI = 'UPDATE_HISTORY_UI'; -export const UPDATE_DOCUMENTS_UI = 'UPDATE_DOCUMENTS_UI'; -export const UPDATE_DISTRICT_EQUIPMENT_UI = 'UPDATE_DISTRICT_EQUIPMENT_UI'; -export const SET_ACTIVE_RENTAL_AGREEMENT_ID_UI = 'SET_ACTIVE_RENTAL_AGREEMENT_ID_UI'; -export const SET_ACTIVE_RENTAL_REQUEST_ID_UI = 'SET_ACTIVE_RENTAL_REQUEST_ID_UI'; -export const SET_ACTIVE_PROJECT_ID_UI = 'SET_ACTIVE_PROJECT_ID_UI'; -export const SET_ACTIVE_OWNER_ID_UI = 'SET_ACTIVE_OWNER_ID_UI'; -export const SET_ACTIVE_EQUIPMENT_ID_UI = 'SET_ACTIVE_EQUIPMENT_ID_UI'; -export const UPDATE_AIT_REPORT_UI = 'UPDATE_AIT_REPORT_UI'; - -// Search -export const UPDATE_EQUIPMENT_LIST_SEARCH = 'UPDATE_EQUIPMENT_LIST_SEARCH'; -export const UPDATE_OWNERS_SEARCH = 'UPDATE_OWNERS_SEARCH'; -export const UPDATE_PROJECTS_SEARCH = 'UPDATE_PROJECTS_SEARCH'; -export const UPDATE_RENTAL_REQUESTS_SEARCH = 'UPDATE_RENTAL_REQUESTS_SEARCH'; -export const UPDATE_TIME_ENTRIES_SEARCH = 'UPDATE_TIME_ENTRIES_SEARCH'; -export const UPDATE_HIRING_RESPONSES_SEARCH = 'UPDATE_HIRING_RESPONSES_SEARCH'; -export const UPDATE_OWNERS_COVERAGE_SEARCH = 'UPDATE_OWNERS_COVERAGE_SEARCH'; -export const UPDATE_USERS_SEARCH = 'UPDATE_USERS_SEARCH'; -export const UPDATE_ROLES_SEARCH = 'UPDATE_ROLES_SEARCH'; -export const UPDATE_AIT_SEARCH = 'UPDATE_AIT_SEARCH'; - -// Lookups -// export const UPDATE_CITIES_LOOKUP = 'UPDATE_CITIES'; -export const UPDATE_DISTRICTS_LOOKUP = 'UPDATE_DISTRICTS'; -export const UPDATE_REGIONS_LOOKUP = 'UPDATE_REGIONS'; -export const UPDATE_SERVICE_AREAS_LOOKUP = 'UPDATE_SERVICE_AREAS'; -export const UPDATE_LOCAL_AREAS_LOOKUP = 'UPDATE_LOCAL_AREAS'; -// export const OWNERS_LOOKUP_REQUEST = 'OWNERS_LOOKUP_REQUEST'; -// export const UPDATE_OWNERS_LOOKUP = 'UPDATE_OWNERS_LOOKUP'; -export const UPDATE_OWNERS_LITE_LOOKUP = 'UPDATE_OWNERS_LITE_LOOKUP'; -export const UPDATE_OWNERS_LITE_TS_LOOKUP = 'UPDATE_OWNERS_LITE_TS_LOOKUP'; -export const UPDATE_OWNERS_LITE_HIRES_LOOKUP = 'UPDATE_OWNERS_LITE_HIRES_LOOKUP'; -export const UPDATE_EQUIPMENT_LITE_LOOKUP = 'UPDATE_EQUIPMENT_LITE_LOOKUP'; -export const UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP'; -export const UPDATE_EQUIPMENT_TS_LOOKUP = 'UPDATE_EQUIPMENT_TS_LOOKUP'; -export const UPDATE_EQUIPMENT_HIRES_LOOKUP = 'UPDATE_EQUIPMENT_HIRES_LOOKUP'; -export const UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP = 'UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP'; -export const UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP'; -export const UPDATE_FISCAL_YEARS_LOOKUP = 'UPDATE_FISCAL_YEARS_LOOKUP'; -export const UPDATE_EQUIPMENT_TYPES_LOOKUP = 'UPDATE_EQUIPMENT_TYPES_LOOKUP'; -export const UPDATE_ROLES_LOOKUP = 'UPDATE_ROLES_LOOKUP'; -export const UPDATE_PROJECTS_LOOKUP = 'UPDATE_PROJECTS_LOOKUP'; -export const UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP = 'UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP'; -export const UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP = 'UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP'; -export const UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP = 'UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP'; -export const UPDATE_USERS_LOOKUP = 'UPDATE_USERS_LOOKUP'; -export const UPDATE_RENTAL_CONDITIONS_LOOKUP = 'UPDATE_RENTAL_CONDITIONS_LOOKUP'; -export const RENTAL_CONDITIONS_LOOKUP_REQUEST = 'RENTAL_CONDITIONS_LOOKUP_REQUEST'; -// export const UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP = 'UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP'; -export const UPDATE_OVERTIME_RATE_TYPES_LOOKUP = 'UPDATE_OVERTIME_RATE_TYPES_LOOKUP'; -export const UPDATE_ROLLOVER_STATUS_LOOKUP = 'UPDATE_ROLLOVER_STATUS_LOOKUP'; -export const UPDATE_SEARCH_SUMMARY_COUNTS = 'UPDATE_SEARCH_SUMMARY_COUNTS'; - -// Current User -export const UPDATE_CURRENT_USER = 'UPDATE_CURRENT_USER'; - -// Users -export const USERS_REQUEST = 'USERS_REQUEST'; -export const UPDATE_USERS = 'UPDATE_USERS'; -export const CLEAR_USERS = 'CLEAR_USERS'; -export const UPDATE_USER = 'UPDATE_USER'; -export const ADD_USER = 'ADD_USER'; -export const DELETE_USER = 'DELETE_USER'; -export const USER_DISTRICTS = 'USER_DISTRICTS'; -export const CURRENT_USER_DISTRICTS = 'CURRENT_USER_DISTRICTS'; - -// Favourites -export const UPDATE_FAVOURITES = 'UPDATE_FAVOURITES'; -export const ADD_FAVOURITE = 'ADD_FAVOURITE'; -export const UPDATE_FAVOURITE = 'UPDATE_FAVOURITE'; -export const DELETE_FAVOURITE = 'DELETE_FAVOURITE'; - -// Contacts -// export const UPDATE_CONTACTS = 'UPDATE_CONTACTS'; -// export const ADD_CONTACT = 'ADD_CONTACT'; -// export const UPDATE_CONTACT = 'UPDATE_CONTACT'; -export const DELETE_CONTACT = 'DELETE_CONTACT'; - -// Documents -export const UPDATE_DOCUMENTS = 'UPDATE_DOCUMENTS'; -export const ADD_DOCUMENT = 'ADD_DOCUMENT'; -export const UPDATE_DOCUMENT = 'UPDATE_DOCUMENT'; -export const DELETE_DOCUMENT = 'DELETE_DOCUMENT'; - -// Roles, Permissions -export const UPDATE_ROLES = 'UPDATE_ROLES'; -export const UPDATE_ROLE = 'UPDATE_ROLE'; -export const ADD_ROLE = 'ADD_ROLE'; -export const DELETE_ROLE = 'DELETE_ROLE'; -export const UPDATE_ROLE_PERMISSIONS = 'UPDATE_ROLE_PERMISSIONS'; - -// Equipment -export const EQUIPMENT_LIST_REQUEST = 'EQUIPMENT_LIST_REQUEST'; -export const UPDATE_EQUIPMENT_LIST = 'UPDATE_EQUIPMENT_LIST'; -export const CLEAR_EQUIPMENT_LIST = 'CLEAR_EQUIPMENT_LIST'; -export const ADD_EQUIPMENT = 'ADD_EQUIPMENT'; -export const UPDATE_EQUIPMENT = 'UPDATE_EQUIPMENT'; -export const UPDATE_EQUIPMENT_NOTES = 'UPDATE_EQUIPMENT_NOTES'; -export const UPDATE_EQUIPMENT_RENTAL_AGREEMENTS = 'UPDATE_EQUIPMENT_RENTAL_AGREEMENTS'; - -// Equipment Attachments -// export const UPDATE_EQUIPMENT_ATTACHMENTS = 'UPDATE_EQUIPMENT_ATTACHMENTS'; -// export const ADD_EQUIPMENT_ATTACHMENT = 'ADD_EQUIPMENT_ATTACHMENT'; -export const ADD_EQUIPMENT_ATTACHMENTS = 'ADD_EQUIPMENT_ATTACHMENTS'; -export const UPDATE_EQUIPMENT_ATTACHMENT = 'UPDATE_EQUIPMENT_ATTACHMENT'; -export const DELETE_EQUIPMENT_ATTACHMENT = 'DELETE_EQUIPMENT_ATTACHMENT'; - -// Owners -export const OWNERS_REQUEST = 'OWNERS_REQUEST'; -export const UPDATE_OWNERS = 'UPDATE_OWNERS'; -export const OWNERS_LITE_REQUEST = 'OWNERS_LITE_REQUEST'; -export const UPDATE_OWNER_EQUIPMENT = 'UPDATE_OWNER_EQUIPMENT'; -export const OWNER_EQUIPMENT_REQUEST = 'OWNER_EQUIPMENT_REQUEST'; -export const ADD_OWNER = 'ADD_OWNER'; -export const UPDATE_OWNER = 'UPDATE_OWNER'; -export const CLEAR_OWNERS = 'CLEAR_OWNERS'; -// export const DELETE_OWNER = 'DELETE_OWNER'; -export const ADD_OWNER_NOTE = 'ADD_OWNER_NOTE'; -export const UPDATE_OWNER_NOTES = 'UPDATE_OWNER_NOTES'; -export const ADD_OWNER_CONTACT = 'ADD_OWNER_CONTACT'; -export const UPDATE_OWNER_CONTACT = 'UPDATE_OWNER_CONTACT'; - -// Projects -export const PROJECTS_REQUEST = 'PROJECTS_REQUEST'; -export const UPDATE_PROJECTS = 'UPDATE_PROJECTS'; -export const CLEAR_PROJECTS = 'CLEAR_PROJECTS'; -export const ADD_PROJECT = 'ADD_PROJECT'; -export const UPDATE_PROJECT = 'UPDATE_PROJECT'; -// export const UPDATE_PROJECT_EQUIPMENT = 'UPDATE_PROJECT_EQUIPMENT'; -// export const UPDATE_PROJECT_TIME_RECORDS = 'UPDATE_PROJECT_TIME_RECORDS'; -export const ADD_PROJECT_NOTE = 'ADD_PROJECT_NOTE'; -export const UPDATE_PROJECT_NOTES = 'UPDATE_PROJECT_NOTES'; -export const UPDATE_PROJECT_RENTAL_AGREEMENTS ='UPDATE_PROJECT_RENTAL_AGREEMENTS'; -export const DELETE_PROJECT_RENTAL_REQUEST = 'DELETE_PROJECT_RENTAL_REQUEST'; -export const ADD_PROJECT_CONTACT = 'ADD_PROJECT_CONTACT'; -export const UPDATE_PROJECT_CONTACT = 'UPDATE_PROJECT_CONTACT'; - -// Rental Requests -export const RENTAL_REQUESTS_REQUEST = 'RENTAL_REQUESTS_REQUEST'; -export const UPDATE_RENTAL_REQUESTS = 'UPDATE_RENTAL_REQUESTS'; -export const CLEAR_RENTAL_REQUESTS = 'CLEAR_RENTAL_REQUESTS'; - -export const ADD_RENTAL_REQUEST = 'ADD_RENTAL_REQUEST'; -export const UPDATE_RENTAL_REQUEST = 'UPDATE_RENTAL_REQUEST'; -export const UPDATE_RENTAL_REQUEST_NOTES = 'UPDATE_RENTAL_REQUEST_NOTES'; -export const UPDATE_RENTAL_REQUEST_ROTATION_LIST = 'UPDATE_RENTAL_REQUEST_ROTATION_LIST'; - -// Time Entries -export const TIME_ENTRIES_REQUEST = 'TIME_ENTRIES_REQUEST'; -export const UPDATE_TIME_ENTRIES = 'UPDATE_TIME_ENTRIES'; -export const CLEAR_TIME_ENTRIES = 'CLEAR_TIME_ENTRIES'; - -// Hiring Responses -export const HIRING_RESPONSES_REQUEST = 'HIRING_RESPONSES_REQUEST'; -export const UPDATE_HIRING_RESPONSES = 'UPDATE_HIRING_RESPONSES'; -export const CLEAR_HIRING_RESPONSES = 'CLEAR_HIRING_RESPONSES'; - -// Owners' Coverage -export const OWNERS_COVERAGE_REQUEST = 'OWNERS_COVERAGE_REQUEST'; -export const UPDATE_OWNERS_COVERAGE = 'UPDATE_OWNERS_COVERAGE'; -export const CLEAR_OWNERS_COVERAGE = 'CLEAR_OWNERS_COVERAGE'; - -// Rental Agreements -export const UPDATE_RENTAL_AGREEMENT = 'UPDATE_RENTAL_AGREEMENT'; -// export const ADD_RENTAL_AGREEMENT = 'ADD_RENTAL_AGREEMENT'; -// export const GENERATE_ANOTHER_RENTAL_AGREEMENT = 'GENERATE_ANOTHER_RENTAL_AGREEMENT'; -export const RENTAL_AGREEMENT_TIME_RECORDS = 'RENTAL_AGREEMENT_TIME_RECORDS'; - -// AitReport -export const AIT_REPORT_REQUEST = 'AIT_REPORT_REQUEST'; -export const UPDATE_AIT_REPORT = 'UPDATE_AIT_REPORT'; -export const CLEAR_AIT_REPORT = 'CLEAR_AIT_REPORT'; - -// Rental Rates, Conditions -export const ADD_RENTAL_RATES = 'ADD_RENTAL_RATES'; -export const UPDATE_RENTAL_RATES = 'UPDATE_RENTAL_RATES'; -export const DELETE_RENTAL_RATE = 'DELETE_RENTAL_RATE'; -export const ADD_RENTAL_CONDITIONS = 'ADD_RENTAL_CONDITIONS'; -export const UPDATE_RENTAL_CONDITIONS = 'UPDATE_RENTAL_CONDITIONS'; -export const DELETE_RENTAL_CONDITION = 'DELETE_RENTAL_CONDITION'; - -// Version -export const UPDATE_VERSION = 'UPDATE_VERSION'; - -// History -export const UPDATE_EQUIPMENT_HISTORY = 'UPDATE_EQUIPMENT_HISTORY'; -export const UPDATE_OWNER_HISTORY = 'UPDATE_OWNER_HISTORY'; -export const UPDATE_PROJECT_HISTORY = 'UPDATE_PROJECT_HISTORY'; -export const UPDATE_RENTAL_REQUEST_HISTORY = 'UPDATE_RENTAL_REQUEST_HISTORY'; - -// Notes -export const DELETE_NOTE = 'DELETE_NOTE'; - -// Time Records -export const DELETE_TIME_RECORD = 'DELETE_TIME_RECORD'; - -// Session Modal -export const SHOW_SESSION_TIMEOUT_DIALOG = 'SHOW_SESSION_TIMEOUT_DIALOG'; -export const CLOSE_SESSION_TIMEOUT_DIALOG = 'CLOSE_SESSION_TIMEOUT_DIALOG'; - -// Businesses -export const UPDATE_BUSINESS = 'UPDATE_BUSINESS'; - -// Error Dialog -export const SHOW_ERROR_DIALOG = 'SHOW_ERROR_DIALOG'; -export const CLOSE_ERROR_DIALOG = 'CLOSE_ERROR_DIALOG'; diff --git a/client/src/js/actions.js b/client/src/js/actions.js deleted file mode 100644 index aafe6af77..000000000 --- a/client/src/js/actions.js +++ /dev/null @@ -1,39 +0,0 @@ -import { SHOW_ERROR_DIALOG, CLOSE_ERROR_DIALOG, REQUESTS_ERROR, CLOSE_SESSION_TIMEOUT_DIALOG } from './actionTypes'; - - -export function showErrorDialog(exception) { - return { - type: SHOW_ERROR_DIALOG, - message: exception.message || String(exception), - }; -} - -export function closeErrorDialog() { - return { - type: CLOSE_ERROR_DIALOG, - }; -} - -export function unhandledApiError(err) { - var errorMessage = err.message || String(err); - if (err.json) { - errorMessage = err.json.error.description; - } - - return { - type: REQUESTS_ERROR, - error: { - message: errorMessage, - method: err.method, - path: err.path, - status: err.status, - json: err.json, - }, - }; -} - -export function closeSessionTimeoutDialog() { - return { - type: CLOSE_SESSION_TIMEOUT_DIALOG, - }; -} diff --git a/client/src/js/api.js b/client/src/js/api.js deleted file mode 100644 index 7bfd3ecb1..000000000 --- a/client/src/js/api.js +++ /dev/null @@ -1,2360 +0,0 @@ -import * as Action from './actionTypes'; -import * as Constant from './constants'; -import * as History from './history'; -import * as Log from './history'; -import store from './store'; - -import { ApiRequest } from './utils/http'; -import { lastFirstName, firstLastName, concat } from './utils/string'; -import { daysAgo, sortableDateTime, today } from './utils/date'; - -import _ from 'lodash'; -import Moment from 'moment'; - -function normalize(response) { - return _.fromPairs(response.map(object => [ object.id, object ])); -} - -//////////////////// -// Users -//////////////////// - -function parseUser(user) { - if (!user.district) { user.district = { id: 0, name: '' }; } - if (!user.userRoles) { user.userRoles = []; } - - user.name = lastFirstName(user.surname, user.givenName); - user.fullName = firstLastName(user.givenName, user.surname); - user.districtName = user.district.name; - - _.each(user.userRoles, userRole => { - userRole.roleId = userRole.role && userRole.role.id ? userRole.role.id : 0; - userRole.roleName = userRole.role && userRole.role.name ? userRole.role.name : ''; - userRole.effectiveDateSort = sortableDateTime(user.effectiveDate); - userRole.expiryDateSort = sortableDateTime(user.expiryDate); - }); - - user.path = `${ Constant.USERS_PATHNAME }/${ user.id }`; - user.url = `#/${ user.path }`; - user.historyEntity = History.makeHistoryEntity(Constant.HISTORY_USER, user); - - user.canEdit = true; - user.canDelete = true; -} - -export function getCurrentUser() { - return new ApiRequest('/users/current').get().then(response => { - var user = response.data; - - // Add display fields - parseUser(user); - - // Get permissions - var permissions = []; - _.each(user.userRoles, userRole => { - _.each(userRole.role.rolePermissions, rolePermission => { - permissions.push(rolePermission.permission.code); - }); - }); - user.permissions = _.uniq(permissions); - - user.hasPermission = function(permission) { - return user.permissions.indexOf(permission) !== -1; - }; - - store.dispatch({ type: Action.UPDATE_CURRENT_USER, user: user }); - return user; - }); -} - -export function keepAlive() { - // endpoint to keep session active - return new ApiRequest('/users/current').get(null, { keepAlive: true }); -} - -export function searchUsers(params) { - store.dispatch({ type: Action.USERS_REQUEST }); - return new ApiRequest('/users/search').get(params).then(response => { - var users = normalize(response.data); - - // Add display fields - _.map(users, user => { parseUser(user); }); - - store.dispatch({ type: Action.UPDATE_USERS, users: users }); - }); -} - -export function getUsers() { - return new ApiRequest('/users').get().then(response => { - var users = normalize(response.data); - - // Add display fields - _.map(users, user => { parseUser(user); }); - - store.dispatch({ type: Action.UPDATE_USERS_LOOKUP, users: users }); - }); -} - -export function getUser(userId) { - return new ApiRequest(`/users/${ userId }`).get().then(response => { - var user = response.data; - - // Add display fields - parseUser(user); - - store.dispatch({ type: Action.UPDATE_USER, user: user }); - }); -} - -export function addUser(user) { - return new ApiRequest('/users').post(user).then(response => { - var user = response.data; - - // Add display fields - parseUser(user); - - store.dispatch({ type: Action.ADD_USER, user: user }); - - return user; - }); -} - -export function updateUser(user) { - return new ApiRequest(`/users/${ user.id }`).put(user).then(response => { - var user = response.data; - - // Add display fields - parseUser(user); - - store.dispatch({ type: Action.UPDATE_USER, user: user }); - - return user; - }); -} - -export function deleteUser(user) { - return new ApiRequest(`/users/${ user.id }/delete`).post().then(response => { - var user = response.data; - - // Add display fields - parseUser(user); - - store.dispatch({ type: Action.DELETE_USER, user: user }); - }); -} - -export function addUserRole(userId, userRole) { - return new ApiRequest(`/users/${ userId }/roles`).post(userRole).then(() => { - // After updating the user's role, refresh the user state. - return getUser(userId); - }); -} - -export function updateUserRoles(userId, userRoleArray) { - return new ApiRequest(`/users/${ userId }/roles`).put(userRoleArray).then(() => { - // After updating the user's role, refresh the user state. - return getUser(userId); - }); -} - -export function getCurrentUserDistricts() { - return new ApiRequest('/userdistricts').get().then((response) => { - store.dispatch({ type: Action.CURRENT_USER_DISTRICTS, currentUserDistricts: response.data }); - return response; - }); -} - -export function getUserDistricts(userId) { - return new ApiRequest(`users/${userId}/districts`).get().then((response) => { - store.dispatch({ type: Action.USER_DISTRICTS, userDistricts: response.data }); - return response; - }); -} - -export function addUserDistrict(district) { - return new ApiRequest(`/userdistricts/${district.id}`).post(district).then((response) => { - store.dispatch({ type: Action.USER_DISTRICTS, userDistricts: response.data }); - return response; - }); -} - -export function editUserDistrict(district) { - return new ApiRequest(`/userdistricts/${district.id}`).post(district).then((response) => { - store.dispatch({ type: Action.USER_DISTRICTS, userDistricts: response.data }); - return response; - }); -} - -export function deleteUserDistrict(district) { - return new ApiRequest(`/userdistricts/${district.id}/delete`).post().then((response) => { - store.dispatch({ type: Action.USER_DISTRICTS, userDistricts: response.data }); - return response; - }); -} - -export function switchUserDistrict(districtId) { - return new ApiRequest(`/userdistricts/${districtId}/switch`).post(); -} - -export function getSearchSummaryCounts() { - return new ApiRequest('/counts').get().then((response) => { - store.dispatch({ type: Action.UPDATE_SEARCH_SUMMARY_COUNTS, searchSummaryCounts: response.data }); - return response; - }); -} - -//////////////////// -// Roles, Permissions -//////////////////// - -function parseRole(role) { - role.path = `${ Constant.ROLES_PATHNAME }/${ role.id }`; - role.url = `#/${ role.path }`; - role.historyEntity = History.makeHistoryEntity(Constant.HISTORY_ROLE, role); - - role.canEdit = true; - role.canDelete = false; -} - -export function searchRoles(params) { - return new ApiRequest('/roles').get(params).then(response => { - var roles = normalize(response.data); - - // Add display fields - _.map(roles, role => { parseRole(role); }); - - store.dispatch({ type: Action.UPDATE_ROLES, roles: roles }); - }); -} - -export function getRole(roleId) { - return new ApiRequest(`/roles/${ roleId }`).get().then(response => { - var role = response.data; - - // Add display fields - parseRole(role); - - store.dispatch({ type: Action.UPDATE_ROLE, role: role }); - }); -} - -export function addRole(role) { - return new ApiRequest('/roles').post(role).then(response => { - var role = response.data; - - // Add display fields - parseRole(role); - - store.dispatch({ type: Action.ADD_ROLE, role: role }); - }); -} - -export function updateRole(role) { - return new ApiRequest(`/roles/${ role.id }`).put(role).then(response => { - var role = response.data; - - // Add display fields - parseRole(role); - - store.dispatch({ type: Action.UPDATE_ROLE, role: role }); - }); -} - -export function deleteRole(role) { - return new ApiRequest(`/roles/${ role.id }/delete`).post().then(response => { - var role = response.data; - - // Add display fields - parseRole(role); - - store.dispatch({ type: Action.DELETE_ROLE, role: role }); - }); -} - -export function getRolePermissions(roleId) { - return new ApiRequest(`/roles/${ roleId }/permissions`).get().then(response => { - var permissions = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_ROLE_PERMISSIONS, rolePermissions: permissions }); - }); -} - -export function updateRolePermissions(roleId, permissionsArray) { - return new ApiRequest(`/roles/${ roleId }/permissions`).put(permissionsArray).then(() => { - // After updating the role's permissions, refresh the permissions state. - return getRolePermissions(roleId); - }); -} - -//////////////////// -// Favourites -//////////////////// - -export function getFavourites() { - return new ApiRequest('/users/current/favourites').get().then(response => { - var favourites = _.chain(response.data) - .groupBy('type') - .mapValues(type => _.chain(type) - .values() - .map(object => [ object.id, object ]) - .fromPairs() - .value()) - .value(); - - store.dispatch({ type: Action.UPDATE_FAVOURITES, favourites: favourites }); - }); -} - -export function addFavourite(favourite) { - return new ApiRequest('/users/current/favourites').post(favourite).then(response => { - store.dispatch({ type: Action.ADD_FAVOURITE, favourite: response.data }); - }); -} - -export function updateFavourite(favourite) { - return new ApiRequest('/users/current/favourites').put(favourite).then(response => { - store.dispatch({ type: Action.UPDATE_FAVOURITE, favourite: response.data }); - }); -} - -export function deleteFavourite(favourite) { - return new ApiRequest(`/users/current/favourites/${ favourite.id }/delete`).post().then(response => { - store.dispatch({ type: Action.DELETE_FAVOURITE, favourite: response.data }); - }); -} - -export function logoffUser() { - return new ApiRequest('/users/current/logoff').get().then(response => { - return response.error ? null : response.data.logoffUrl; - }); -} - -//////////////////// -// Equipment -//////////////////// -function getBlockDisplayName(blockNumber, numberOfBlocks, seniority) { - if (blockNumber === numberOfBlocks) { - return `Open - ${seniority}`; - } else if (blockNumber == 1) { - return `1 - ${seniority}`; - } else if (blockNumber == 2) { - return `2 - ${seniority}`; - } else if (seniority != null) { - return `Open - ${seniority}`; - } - return 'Open'; -} - -function parseEquipment(equipment) { - if (!equipment.owner) { equipment.owner = { id: 0, organizationName: '' }; } - if (!equipment.districtEquipmentType) { equipment.districtEquipmentType = { id: 0, districtEquipmentName: '' }; } - if (!equipment.localArea) { equipment.localArea = { id: 0, name: '' }; } - if (!equipment.localArea.serviceArea) { equipment.localArea.serviceArea = { id: 0, name: '' }; } - if (!equipment.localArea.serviceArea.district) { equipment.localArea.serviceArea.district = { id: 0, name: '' }; } - if (!equipment.localArea.serviceArea.district.region) { equipment.localArea.serviceArea.district.region = { id: 0, name: '' }; } - if (!equipment.status) { equipment.status = Constant.EQUIPMENT_STATUS_CODE_PENDING; } - if (!equipment.equipmentAttachments) { equipment.equipmentAttachments = []; } - - equipment.isApproved = equipment.status === Constant.EQUIPMENT_STATUS_CODE_APPROVED; - equipment.isNew = equipment.status === Constant.EQUIPMENT_STATUS_CODE_PENDING; - equipment.isArchived = equipment.status === Constant.EQUIPMENT_STATUS_CODE_ARCHIVED; - equipment.isMaintenanceContractor = equipment.owner.isMaintenanceContractor === true; - equipment.isDumpTruck = equipment.districtEquipmentType.equipmentType && equipment.districtEquipmentType.equipmentType.isDumpTruck || false; - - equipment.ownerStatus = equipment.owner.status; - - // UI display fields - equipment.serialNumber = equipment.serialNumber || ''; - equipment.equipmentCode = equipment.equipmentCode || ''; - equipment.licencePlate = equipment.licencePlate || ''; - equipment.operator = equipment.operator || ''; // TODO Needs review from business - equipment.organizationName = equipment.owner.organizationName; - equipment.ownerPath = equipment.owner.id ? `#/owners/${ equipment.owner.id }` : ''; - equipment.typeName = equipment.districtEquipmentType ? equipment.districtEquipmentType.districtEquipmentName : ''; - equipment.localAreaName = equipment.localArea.name; - equipment.districtName = equipment.localArea.serviceArea.district.name; - equipment.lastVerifiedDate = equipment.lastVerifiedDate || ''; - equipment.daysSinceVerified = daysAgo(equipment.lastVerifiedDate); - equipment.details = [equipment.make || '-', equipment.model || '-', equipment.size || '-', equipment.year || '-'].join('/'); - - // Seniority data - equipment.serviceHoursThisYear = equipment.serviceHoursThisYear || 0; - equipment.serviceHoursLastYear = equipment.serviceHoursLastYear || 0; - equipment.serviceHoursTwoYearsAgo = equipment.serviceHoursTwoYearsAgo || 0; - equipment.serviceHoursThreeYearsAgo = equipment.serviceHoursThreeYearsAgo || 0; - - equipment.isSeniorityOverridden = equipment.isSeniorityOverridden || false; - equipment.seniorityOverrideReason = equipment.seniorityOverrideReason || ''; - - // The number of years of active service of this piece of equipment at the time seniority is calculated - April 1 of the current fiscal year - equipment.yearsOfService = equipment.yearsOfService || 0; - equipment.receivedDate = equipment.receivedDate || ''; - equipment.approvedDate = equipment.approvedDate || ''; - // The max date of a time card for this fiscal year - can be null if there are none. - equipment.lastTimeRecordDateThisYear = equipment.lastTimeRecordDateThisYear || ''; - // e.g. "Open-500" or "1-744" - equipment.seniorityText = getBlockDisplayName(equipment.blockNumber, equipment.numberOfBlocks, equipment.seniority); - - equipment.currentYear = Moment().year(); - equipment.lastYear = equipment.currentYear - 1; - equipment.twoYearsAgo = equipment.currentYear - 2; - equipment.threeYearsAgo = equipment.currentYear - 3; - - // It is possible to have multiple instances of the same piece of equipment registered with HETS. - // However, the HETS clerks would like to know about it via this flag so they can deal with the duplicates. - equipment.hasDuplicates = equipment.hasDuplicates || false; - equipment.duplicateEquipment = equipment.duplicateEquipment || []; - - equipment.isHired = equipment.isHired || false; - // TODO Descriptive text for time entries. Needs to be added to backend - equipment.currentWorkDescription = equipment.currentWorkDescription || '' ; - - equipment.path = `${ Constant.EQUIPMENT_PATHNAME }/${ equipment.id }`; - equipment.url = `#/${ equipment.path }`; - equipment.name = `code ${ equipment.equipmentCode }`; - equipment.historyEntity = History.makeHistoryEntity(Constant.HISTORY_EQUIPMENT, equipment); - equipment.documentAdded = Log.equipmentDocumentAdded; - equipment.documentsAdded = Log.equipmentDocumentsAdded; - equipment.documentDeleted = Log.equipmentDocumentDeleted; - - equipment.getDocumentsPromise = getEquipmentDocuments; - equipment.uploadDocumentPath = `/equipment/${ equipment.id }/attachments`; - - equipment.canView = true; - equipment.canEdit = true; - equipment.canDelete = false; // TODO Needs input from Business whether this is needed. -} - -function generateSortableEquipmentCode(equipment) { - return equipment.equipmentPrefix && equipment.equipmentNumber ? `${equipment.equipmentPrefix}${_.padStart(equipment.equipmentNumber, 3, '0')}` : equipment.equipmentCode; -} - -export function searchEquipmentList(params) { - store.dispatch({ type: Action.EQUIPMENT_LIST_REQUEST }); - return new ApiRequest('/equipment/search').get(params).then(response => { - var equipmentList = normalize(response.data); - - _.map(equipmentList, equipment => { - equipment.details = [equipment.make || '-', equipment.model || '-', equipment.size || '-', equipment.year || '-'].join('/'); - equipment.sortableEquipmentCode = generateSortableEquipmentCode(equipment); - }); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST, equipmentList: equipmentList }); - }); -} - -export function getEquipment(equipmentId) { - return new ApiRequest(`/equipment/${ equipmentId }`).get().then(response => { - var equipment = response.data; - - // Add display fields - parseEquipment(equipment); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); - }); -} - -export function getEquipmentLite() { - const silent = store.getState().lookups.equipment.lite.loaded; - return new ApiRequest('/equipment/lite', { silent }).get().then(response => { - var equipment = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LITE_LOOKUP, equipment: equipment }); - }); -} - -export function getEquipmentAgreementSummary() { - const silent = store.getState().lookups.equipment.ts.loaded; - return new ApiRequest('/equipment/agreementSummary', { silent }).get().then(response => { - var equipment = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP, equipment: equipment }); - }); -} - -export function getEquipmentTs() { - const silent = store.getState().lookups.equipment.ts.loaded; - return new ApiRequest('/equipment/liteTs', { silent }).get().then(response => { - var equipment = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_TS_LOOKUP, equipment: equipment }); - }); -} - -export function getEquipmentHires() { - const silent = store.getState().lookups.equipment.hires.loaded; - return new ApiRequest('/equipment/liteHires', { silent }).get().then(response => { - var equipment = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_HIRES_LOOKUP, equipment: equipment }); - }); -} - -export function addEquipment(equipment) { - return new ApiRequest('/equipment').post(equipment).then(response => { - var equipment = response.data; - - // Add display fields - parseEquipment(equipment); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); - - getEquipmentLite(); - getEquipmentTs(); - getEquipmentHires(); - - return equipment; - }); -} - -export function updateEquipment(equipment) { - return new ApiRequest(`/equipment/${ equipment.id }`).put(equipment).then(response => { - var equipment = response.data; - - // Add display fields - parseEquipment(equipment); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); - - getEquipmentLite(); - getEquipmentTs(); - getEquipmentHires(); - }); -} - -export function addEquipmentHistory(equipmentId, history) { - return new ApiRequest(`/equipment/${ equipmentId }/history`).post(history).then((response) => { - var history = normalize(response.data); - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_HISTORY, history, id: equipmentId }); - }); -} - -export function getEquipmentHistory(equipmentId, params) { - return new ApiRequest(`/equipment/${ equipmentId }/history`).get(params).then(response => { - var history = normalize(response.data); - - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_HISTORY, history, id: equipmentId }); - }); -} - -export function getEquipmentDocuments(equipmentId) { - return new ApiRequest(`/equipment/${ equipmentId }/attachments`).get().then(response => { - var documents = normalize(response.data); - - // Add display fields - _.map(documents, document => { parseDocument(document); }); - - store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); - }); -} - -// XXX: Looks like this is unused -// export function addEquipmentDocument(equipmentId, files) { -// return new ApiRequest(`/equipment/${ equipmentId }/attachments`).post(files); -// } - -export function getEquipmentNotes(equipmentId) { - return new ApiRequest(`/equipment/${ equipmentId }/notes`).get().then((response) => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_NOTES, notes: response.data }); - return response.data; - }); -} - -export function addEquipmentNote(equipmentId, note) { - return new ApiRequest(`/equipment/${ equipmentId }/note`).post(note).then((response) => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_NOTES, notes: response.data }); - return response.data; - }); -} - -export function equipmentDuplicateCheck(id, serialNumber) { - return new ApiRequest(`/equipment/${id}/duplicates/${serialNumber}`).get(); -} - -export function changeEquipmentStatus(status) { - return new ApiRequest(`/equipment/${status.id}/status`).put(status).then((response) => { - var equipment = response.data; - // Add display fields - parseEquipment(equipment); - store.dispatch({ type: Action.UPDATE_EQUIPMENT, equipment: equipment }); - return response; - }); -} - -export function getEquipmentRentalAgreements(equipmentId) { - return new ApiRequest(`/equipment/${ equipmentId }/rentalAgreements`).get().then(response => { - var rentalAgreements = normalize(response.data); - store.dispatch({ type: Action.UPDATE_EQUIPMENT_RENTAL_AGREEMENTS, rentalAgreements: rentalAgreements }); - return rentalAgreements; - }); -} - -export function cloneEquipmentRentalAgreement(data) { - return new ApiRequest(`/equipment/${ data.equipmentId }/rentalAgreementClone`).post(data).then(response => { - var agreement = response.data; - // Add display fields - parseRentalAgreement(agreement); - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: agreement }); - return response; - }); -} - -export function equipmentSeniorityListDoc(localAreas, types, counterCopy) { - var params = { localareas: localAreas, types: types }; - if (counterCopy) { - params.counterCopy = counterCopy; - } - - return new ApiRequest('/equipment/seniorityListDoc').get(params, { responseType: Constant.RESPONSE_TYPE_BLOB }).then(response => { - return response; - }); -} - -//////////////////// -// Physical Attachments -//////////////////// - -// Introduce later -// function parsePhysicalAttachment(attachment) { -// if (!attachment.type) { attachment.type = { id: 0, code: '', description: ''}; } - -// attachment.typeName = attachment.type.description; -// // TODO Add grace period logic to editing/deleting attachments -// attachment.canEdit = true; -// attachment.canDelete = true; -// } - -// XXX: Looks like this is unused -// export function getPhysicalAttachment(id) { -// return new ApiRequest(`/equipment/${id}/equipmentAttachments`).get().then(response => { -// store.dispatch({ type: Action.UPDATE_EQUIPMENT_ATTACHMENTS, physicalAttachments: response.data }); -// }); -// } - -// XXX: Looks like this is unused -// export function addPhysicalAttachment(attachment) { -// return new ApiRequest('/equipmentAttachments').post(attachment).then(response => { -// store.dispatch({ type: Action.ADD_EQUIPMENT_ATTACHMENT, physicalAttachment: response.data }); -// }); -// } - -export function addPhysicalAttachments(equipmentId, attachmentTypeNames) { - const attachments = attachmentTypeNames.map((typeName) => { - // "concurrencyControlNumber": 0, - return { - typeName, - description: '', - equipmentId, - equipment: { id: equipmentId }, - }; - }); - - return new ApiRequest('/equipmentAttachments/bulk').post(attachments).then(response => { - store.dispatch({ type: Action.ADD_EQUIPMENT_ATTACHMENTS, physicalAttachments: response.data }); - }); -} - -export function updatePhysicalAttachment(attachment) { - return new ApiRequest(`/equipmentAttachments/${attachment.id}`).put(attachment).then(response => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_ATTACHMENT, physicalAttachment: response.data }); - }); -} - -export function deletePhysicalAttachment(attachmentId) { - return new ApiRequest(`/equipmentAttachments/${attachmentId}/delete`).post().then(response => { - store.dispatch({ type: Action.DELETE_EQUIPMENT_ATTACHMENT, physicalAttachment: response.data }); - }); -} - -//////////////////// -// Owners -//////////////////// - -function parseOwner(owner) { - // Rename properties - owner.equipmentList = owner.equipment; - delete owner.equipment; - - owner.workSafeBCExpiryDate = owner.workSafeBcexpiryDate; - delete owner.workSafeBcexpiryDate; - - owner.workSafeBCPolicyNumber = owner.workSafeBcpolicyNumber; - delete owner.workSafeBcpolicyNumber; - - owner.cglEndDate = owner.cglendDate; - delete owner.cglendDate; - - if (!owner.localArea) { owner.localArea = { id: 0, name: '' }; } - if (!owner.localArea.serviceArea) { owner.localArea.serviceArea = { id: 0, name: '' }; } - if (!owner.localArea.serviceArea.district) { owner.localArea.serviceArea.district = { id: 0, name: '' }; } - if (!owner.localArea.serviceArea.district.region) { owner.localArea.serviceArea.district.region = { id: 0, name: '' }; } - if (!owner.contacts) { owner.contacts = []; } - if (!owner.documents) { owner.documents = []; } - if (!owner.equipmentList) { owner.equipmentList = []; } - - owner.organizationName = owner.organizationName || ''; - owner.ownerCode = owner.ownerCode || ''; - owner.doingBusinessAs = owner.doingBusinessAs || ''; - owner.registeredCompanyNumber = owner.registeredCompanyNumber || ''; - owner.meetsResidency = owner.meetsResidency || false; - owner.workSafeBCPolicyNumber = owner.workSafeBCPolicyNumber || ''; - owner.workSafeBCExpiryDate = owner.workSafeBCExpiryDate || ''; - owner.cglEndDate = owner.cglEndDate || ''; - owner.address1 = owner.address1 || ''; - owner.address2 = owner.address2 || ''; - owner.city = owner.city || ''; - owner.province = owner.province || ''; - owner.postalCode = owner.postalCode || ''; - owner.fullAddress = `${owner.address1} ${owner.address2} ${owner.city} ${owner.province} ${owner.postalCode}`; - owner.ownerName = owner.givenName && owner.surname ? `${owner.givenName} ${owner.surname}` : ''; - - owner.path = `${ Constant.OWNERS_PATHNAME }/${ owner.id }`; - owner.url = `#/${ owner.path }`; - owner.name = owner.organizationName; - owner.historyEntity = History.makeHistoryEntity(Constant.HISTORY_OWNER, owner); - owner.documentAdded = Log.ownerDocumentAdded; - owner.documentsAdded = Log.ownerDocumentsAdded; - owner.documentDeleted = Log.ownerDocumentDeleted; - - // Add display fields for owner contacts - owner.contacts = owner.contacts.map((contact) => parseContact(contact, owner)); - - _.map(owner.documents, document => { parseDocument(document); }); - _.map(owner.equipmentList, equipment => { parseEquipment(equipment); }); - - // TODO Owner status needs to be populated in sample data. Setting to Approved for the time being... - owner.status = owner.status || Constant.OWNER_STATUS_CODE_APPROVED; - - // UI display fields - owner.isMaintenanceContractor = owner.isMaintenanceContractor || false; - owner.isApproved = owner.status === Constant.OWNER_STATUS_CODE_APPROVED; - owner.primaryContactName = owner.primaryContact ? firstLastName(owner.primaryContact.givenName, owner.primaryContact.surname) : ''; - owner.localAreaName = owner.localArea.name; - owner.districtName = owner.localArea.serviceArea.district.name; - owner.numberOfEquipment = Object.keys(owner.equipmentList).length; - owner.numberOfPolicyDocuments = owner.numberOfPolicyDocuments || 0; // TODO - - owner.getDocumentsPromise = getOwnerDocuments; - owner.uploadDocumentPath = `/owners/${ owner.id }/attachments`; - - owner.canView = true; - owner.canEdit = true; - owner.canDelete = false; // TODO Needs input from Business whether this is needed. -} - -export function searchOwners(params) { - store.dispatch({ type: Action.OWNERS_REQUEST }); - return new ApiRequest('/owners/search').get(params).then(response => { - var owners = normalize(response.data); - store.dispatch({ type: Action.UPDATE_OWNERS, owners: owners }); - }); -} - -export function getOwner(ownerId) { - return new ApiRequest(`/owners/${ ownerId }`).get().then((response) => { - var owner = response.data; - - // Add display fields - parseOwner(owner); - - store.dispatch({ type: Action.UPDATE_OWNER, owner }); - - return owner; - }); -} - -export function addOwner(owner) { - return new ApiRequest('/owners').post(owner).then(response => { - var owner = response.data; - - // Add display fields - parseOwner(owner); - - store.dispatch({ type: Action.ADD_OWNER, owner }); - - return owner; - }); -} - -export function updateOwner(owner) { - store.dispatch({ type: Action.UPDATE_OWNER, owner }); - - // Omit `contacts` to ensure that the existing contacts don't mess up the PUT call - return new ApiRequest(`/owners/${ owner.id }`).put(_.omit(owner, 'contacts')).then(response => { - var owner = response.data; - - // Add display fields - parseOwner(owner); - - store.dispatch({ type: Action.UPDATE_OWNER, owner }); - }); -} - -// XXX: Looks like this is unused -// export function deleteOwner(owner) { -// return new ApiRequest(`/owners/${ owner.id }/delete`).post().then(response => { -// var owner = response.data; - -// // Add display fields -// parseOwner(owner); - -// store.dispatch({ type: Action.DELETE_OWNER, owner }); -// }); -// } - -export function saveOwnerContact(owner, contact) { - const isNew = contact.id === 0; - - if (!isNew) { // don't update if this is a new contact - add after post() completes - store.dispatch({ type: Action.UPDATE_OWNER_CONTACT, ownerId: owner.id, contact }); - } - - return new ApiRequest(`/owners/${ owner.id }/contacts/${contact.isPrimary}`).post(contact).then(response => { - var updatedContact = response.data; - - // Add display fields - parseContact(updatedContact, owner); // owner's primary contact could be outdated - updatedContact.isPrimary = contact.isPrimary; - - if (isNew){ - // add newly created contact to Redux store's contacts - store.dispatch({ type: Action.ADD_OWNER_CONTACT, ownerId: owner.id, contact: updatedContact }); - } else { - // Update Redux store's data with the server's data - store.dispatch({ type: Action.UPDATE_OWNER_CONTACT, ownerId: owner.id, contact: updatedContact }); - } - - return updatedContact; - }); -} - -export function addOwnerHistory(ownerId, history) { - return new ApiRequest(`/owners/${ ownerId }/history`).post(history).then((response) => { - var history = normalize(response.data); - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_OWNER_HISTORY, history, id: ownerId }); - }); -} - -export function getOwnerHistory(ownerId, params) { - return new ApiRequest(`/owners/${ ownerId }/history`).get(params).then(response => { - var history = normalize(response.data); - - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_OWNER_HISTORY, history, id: ownerId }); - }); -} - -export function getOwnerDocuments(ownerId) { - return new ApiRequest(`/owners/${ ownerId }/attachments`).get().then(response => { - var documents = normalize(response.data); - - // Add display fields - _.map(documents, document => { parseDocument(document); }); - - store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); - }); -} - -// XXX: Looks like this is unused -// export function addOwnerDocument(ownerId, files) { -// return new ApiRequest(`/owners/${ ownerId }/attachments`).post(files); -// } - -export function getOwnerEquipment(ownerId) { - return new ApiRequest(`/owners/${ ownerId }/equipment`).get().then(response => { - var equipmentList = normalize(response.data); - - _.map(equipmentList, equipment => { - equipment.details = [equipment.make || '-', equipment.model || '-', equipment.size || '-', equipment.year || '-'].join('/'); - }); - - store.dispatch({ type: Action.UPDATE_OWNER_EQUIPMENT, equipment: equipmentList }); - }); -} - -export function updateOwnerEquipment(owner, equipmentArray) { - return new ApiRequest(`/owners/${ owner.id }/equipment`).put(equipmentArray).then(() => { - }); -} - -export function getOwnerNotes(ownerId) { - return new ApiRequest(`/owners/${ ownerId }/notes`).get().then((response) => { - store.dispatch({ type: Action.UPDATE_OWNER_NOTES, ownerId, notes: response.data }); - return response.data; - }); -} - -export function addOwnerNote(ownerId, note) { - store.dispatch({ type: Action.ADD_OWNER_NOTE, ownerId, note }); - return new ApiRequest(`/owners/${ ownerId }/note`).post(note).then((response) => { - return response.data; - }); -} - -// XXX: Looks like this is unused -// export function getOwnersByDistrict(districtId) { -// return new ApiRequest(`/districts/${districtId}/owners`).get().then((response) => { -// var owners = normalize(response.data); -// // Add display fields -// _.map(owners, owner => { parseOwner(owner); }); -// store.dispatch({ type: Action.UPDATE_OWNERS_LOOKUP, owners: owners }); -// }); -// } - -export function changeOwnerStatus(status) { - return new ApiRequest(`/owners/${status.id}/status`).put(status).then((response) => { - var owner = response.data; - // Add display fields - parseOwner(owner); - store.dispatch({ type: Action.UPDATE_OWNER, owner: owner }); - return response; - }); -} - -export function getStatusLettersDoc(params) { - return new ApiRequest('owners/verificationDoc').post(params, { responseType: Constant.RESPONSE_TYPE_BLOB }); -} - -export function getMailingLabelsDoc(params) { - return new ApiRequest('owners/mailingLabelsDoc').post(params, { responseType: Constant.RESPONSE_TYPE_BLOB }); -} - -export function transferEquipment(donorOwnerId, recipientOwnerId, equipment, includeSeniority) { - return new ApiRequest(`owners/${donorOwnerId}/equipmentTransfer/${recipientOwnerId}/${includeSeniority}`).post(equipment).then((response) => { - getEquipmentLite(); - getEquipmentTs(); - getEquipmentHires(); - - return response; - }); -} - -//////////////////// -// Contacts -//////////////////// - -function parseContact(contact, parent) { - contact.name = firstLastName(contact.givenName, contact.surname); - contact.phone = contact.workPhoneNumber ? - `${ contact.workPhoneNumber } (w)` : - (contact.mobilePhoneNumber ? `${ contact.mobilePhoneNumber } (c)` : ''); - - var parentPath = ''; - var primaryContactId = 0; - if (parent) { - parentPath = parent.path || ''; - primaryContactId = parent.primaryContact ? parent.primaryContact.id : 0; - } - - contact.isPrimary = contact.id === primaryContactId; - - contact.path = parentPath ? `${ parentPath }/${ Constant.CONTACTS_PATHNAME }/${ contact.id }` : null; - contact.url = contact.path ? `#/${ contact.path }` : null; - contact.historyEntity = History.makeHistoryEntity(Constant.HISTORY_CONTACT, contact); - - contact.canEdit = true; - contact.canDelete = true; - - return contact; -} - -// XXX: Looks like this is unused -// export function getContacts() { -// return new ApiRequest('/contacts').get().then(response => { -// var contacts = normalize(response.data); - -// // Add display fields -// _.map(contacts, contact => { parseContact(contact); }); - -// store.dispatch({ type: Action.UPDATE_CONTACTS, contacts: contacts }); -// }); -// } - -// XXX: Looks like this is unused -// export function getContact(contactId) { -// return new ApiRequest(`/contacts/${ contactId }`).get().then(response => { -// var contact = response.data; - -// // Add display fields -// parseContact(contact); - -// store.dispatch({ type: Action.UPDATE_CONTACT, contact: contact }); -// }); -// } - -// XXX: Looks like this is unused -// export function addContact(parent, contact) { -// return new ApiRequest('/contacts').post(contact).then(response => { -// var contact = response.data; - -// // Add display fields -// parseContact(contact, parent); - -// store.dispatch({ type: Action.ADD_CONTACT, contact: contact }); -// }); -// } - -// export function updateContact(parent, contact) { -// return new ApiRequest(`/contacts/${ contact.id }`).put(contact).then(response => { -// var contact = response.data; - -// // Add display fields -// parseContact(contact, parent); - -// store.dispatch({ type: Action.UPDATE_CONTACT, contact: contact }); -// }); -// } - -export function deleteContact(contact) { - store.dispatch({ type: Action.DELETE_CONTACT, contact }); - return new ApiRequest(`/contacts/${ contact.id }/delete`).post().then(response => { - var contact = response.data; - - // Add display fields - parseContact(contact); - - store.dispatch({ type: Action.DELETE_CONTACT, contact }); - }); -} - -//////////////////// -// Documents -//////////////////// - -function getFileSizeString(fileSizeInBytes) { - var bytes = parseInt(fileSizeInBytes, 10) || 0; - var kbytes = bytes >= 1024 ? bytes / 1024 : 0; - var mbytes = kbytes >= 1024 ? kbytes / 1024 : 0; - var gbytes = mbytes >= 1024 ? mbytes / 1024 : 0; - - var ceiling10 = function(num) { - var adjusted = Math.ceil(num * 10) / 10; - return adjusted.toFixed(1); - }; - - return gbytes ? - `${ ceiling10(gbytes) } GB` - : (mbytes ? `${ ceiling10(mbytes) } MB` - : (kbytes ? `${ Math.ceil(kbytes) } KB` - : `${ bytes } bytes`)); -} - -function parseDocument(document) { - document.fileSizeDisplay = getFileSizeString(document.fileSize); - document.timestampSort = sortableDateTime(document.lastUpdateTimestamp); - document.name = document.fileName; - - document.canDelete = true; - document.historyEntity = History.makeHistoryEntity(Constant.HISTORY_DOCUMENT, document); -} - -export function deleteDocument(document) { - return new ApiRequest(`/attachments/${ document.id }/delete`).post(); -} - -export function getDownloadDocumentURL(document) { - // Not an API call, per se, as it must be called from the browser window. - return `${ location.origin }${ location.pathname}api/attachments/${ document.id }/download`; -} - -//////////////////// -// History -//////////////////// - -function parseHistory(history) { - history.timestampSort = sortableDateTime(history.lastUpdateTimestamp); -} - -//////////////////// -// Projects -//////////////////// - -function parseProject(project) { - if (!project.district) { project.district = { id: 0, name: '' }; } - if (!project.district.region) { project.district.region = { id: 0, name: '' }; } - if (!project.contacts) { project.contacts = []; } - if (!project.rentalRequests) { project.rentalRequests = []; } - if (!project.rentalAgreements) { project.rentalAgreements = []; } - - project.name = project.name || ''; - project.provincialProjectNumber = project.provincialProjectNumber || ''; - project.information = project.information || ''; - - project.path = `${ Constant.PROJECTS_PATHNAME }/${ project.id }`; - project.url = `#/${ project.path }`; - project.historyEntity = History.makeHistoryEntity(Constant.HISTORY_PROJECT, project); - project.documentAdded = Log.projectDocumentAdded; - project.documentsAdded = Log.projectDocumentsAdded; - project.documentDeleted = Log.projectDocumentDeleted; - - // Add display fields for contacts - project.contacts = project.contacts.map((contact) => parseContact(contact, project)); - - // Add display fields for rental requests and rental agreements - _.map(project.rentalRequests, obj => { parseRentalRequest(obj); }); - _.map(project.rentalAgreements, obj => { parseRentalAgreement(obj); }); - - project.numberOfRequests = project.numberOfRequests || Object.keys(project.rentalRequests).length; - project.numberOfHires = project.numberOfHires || Object.keys(project.rentalAgreements).length; - - // UI display fields - project.label = `${ project.provincialProjectNumber } - ${ project.name }`; - project.status = project.status || Constant.PROJECT_STATUS_CODE_ACTIVE; - project.isActive = project.status === Constant.PROJECT_STATUS_CODE_ACTIVE; - project.districtName = project.district.name; - - project.primaryContactName = project.primaryContact ? firstLastName(project.primaryContact.givenName, project.primaryContact.surname) : ''; - project.primaryContactRole = project.primaryContact ? project.primaryContact.role : ''; - project.primaryContactEmail = project.primaryContact ? project.primaryContact.emailAddress : ''; - project.primaryContactPhone = project.primaryContact ? project.primaryContact.workPhoneNumber || project.primaryContact.mobilePhoneNumber || '' : ''; - - project.getDocumentsPromise = getProjectDocuments; - project.uploadDocumentPath = `/projects/${ project.id }/attachments`; - - project.canView = true; - project.canEdit = true; - project.canDelete = false; // TODO Needs input from Business whether this is needed. -} - -function formatTimeRecords(timeRecords, rentalRequestId) { - let formattedTimeRecords = Object.keys(timeRecords).map((key) => { - let timeRecord = {}; - timeRecord.workedDate = timeRecords[key].date; - timeRecord.hours = timeRecords[key].hours; - timeRecord.timePeriod = 'Week'; - timeRecord.rentalAgreement = { id: rentalRequestId }; - return timeRecord; - }); - return formattedTimeRecords; -} - -export function searchProjects(params) { - store.dispatch({ type: Action.PROJECTS_REQUEST }); - return new ApiRequest('/projects/search').get(params).then(response => { - var projects = normalize(response.data); - - // Add display fields - _.map(projects, project => { parseProject(project); }); - - store.dispatch({ type: Action.UPDATE_PROJECTS, projects: projects }); - }); -} - -export function searchTimeEntries(params) { - store.dispatch({ type: Action.TIME_ENTRIES_REQUEST }); - return new ApiRequest('/timeRecords/search').get(params).then(response => { - var timeEntries = normalize(response.data); - - _.map(timeEntries, entry => { - entry.localAreaLabel = `${ entry.serviceAreaId } - ${ entry.localAreaName }`; - entry.equipmentDetails = [entry.make || '-', entry.model || '-', entry.size || '-', entry.year || '-'].join('/'); - entry.sortableEquipmentCode = generateSortableEquipmentCode(entry); - }); - - store.dispatch({ type: Action.UPDATE_TIME_ENTRIES, timeEntries: timeEntries }); - }); -} - -export function searchHiringReport(params) { - store.dispatch({ type: Action.HIRING_RESPONSES_REQUEST }); - return new ApiRequest('/rentalRequests/hireReport').get(params).then(response => { - var hiringResponses = normalize(response.data); - - _.map(hiringResponses, entry => { - entry.localAreaLabel = `${ entry.serviceAreaId } - ${ entry.localAreaName }`; - entry.equipmentDetails = [entry.equipmentMake || '-', entry.equipmentModel || '-', entry.equipmentSize || '-', entry.equipmentYear || '-'].join('/'); - entry.sortableEquipmentCode = generateSortableEquipmentCode(entry); - }); - - store.dispatch({ type: Action.UPDATE_HIRING_RESPONSES, hiringResponses: hiringResponses }); - }); -} - -export function searchOwnersCoverage(params) { - store.dispatch({ type: Action.OWNERS_COVERAGE_REQUEST }); - return new ApiRequest('/owners/wcbCglReport').get(params).then(response => { - var ownersCoverage = normalize(response.data); - - _.map(ownersCoverage, entry => { - entry.localAreaLabel = `${ entry.serviceAreaId } - ${ entry.localAreaName }`; - }); - - store.dispatch({ type: Action.UPDATE_OWNERS_COVERAGE, ownersCoverage: ownersCoverage }); - }); -} - -export function getProjects() { - const silent = store.getState().lookups.projects.loaded; - return new ApiRequest('/projects', { silent }).get({ currentFiscal: false }).then(response => { - var projects = normalize(response.data); - - // Add display fields - _.map(projects, project => { parseProject(project); }); - - store.dispatch({ type: Action.UPDATE_PROJECTS_LOOKUP, projects: projects }); - }); -} - -export function getProjectsAgreementSummary() { - const silent = store.getState().lookups.projectsAgreementSummary.loaded; - return new ApiRequest('/projects/agreementSummary', { silent }).get().then(response => { - var projects = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP, projects: projects }); - }); -} - -export function getProjectsCurrentFiscal() { - const silent = store.getState().lookups.projectsCurrentFiscal.loaded; - return new ApiRequest('/projects', { silent }).get({ currentFiscal: true }).then(response => { - var projects = normalize(response.data); - - // Add display fields - _.map(projects, project => { parseProject(project); }); - - store.dispatch({ type: Action.UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP, projects: projects }); - }); -} - -export function getProject(projectId) { - return new ApiRequest(`/projects/${ projectId }`).get().then(response => { - var project = response.data; - - // Add display fields - parseProject(project); - - store.dispatch({ type: Action.UPDATE_PROJECT, project: project }); - - return project; - }); -} - -export function addProject(project) { - return new ApiRequest('/projects').post(project).then(response => { - var project = response.data; - - // Add display fields - parseProject(project); - - store.dispatch({ type: Action.ADD_PROJECT, project: project }); - - return project; - }); -} - -export function updateProject(project) { - const projectData = _.omit(project, 'notes', 'contacts', 'historyEntity', 'primaryContact', 'rentalAgreements', 'rentalRequests'); - projectData.projectId = project.id; - - return new ApiRequest(`/projects/${ project.id }`).put(projectData).then(response => { - var project = response.data; - - // Add display fields - parseProject(project); - - store.dispatch({ type: Action.UPDATE_PROJECT, project: project }); - }); -} - -// XXX: Looks like this is unused -// export function getProjectEquipment(projectId) { -// return new ApiRequest(`/projects/${projectId}/equipment`).get().then(response => { -// var projectEquipment = normalize(response.data); - -// store.dispatch({ type: Action.UPDATE_PROJECT_EQUIPMENT, projectEquipment: projectEquipment }); -// }); -// } - -// XXX: Looks like this is unused -// export function getProjectTimeRecords(projectId) { -// return new ApiRequest(`projects/${projectId}/timeRecords`).get().then(response => { -// var projectTimeRecords = normalize(response.data); - -// store.dispatch({ type: Action.UPDATE_PROJECT_TIME_RECORDS, projectTimeRecords: projectTimeRecords }); -// }); -// } - -// XXX: Looks like this is unused -// export function addProjectTimeRecords(projectId, rentalRequestId, timeRecords) { -// let formattedTimeRecords = formatTimeRecords(timeRecords, rentalRequestId); -// return new ApiRequest(`projects/${projectId}/timeRecords`).post(formattedTimeRecords).then(response => { -// var projectTimeRecords = normalize(response.data); - -// store.dispatch({ type: Action.UPDATE_PROJECT_TIME_RECORDS, projectTimeRecords: projectTimeRecords }); -// return projectTimeRecords; -// }); -// } - -export function saveProjectContact(project, contact) { - const isNew = contact.id === 0; - - if (!isNew) { // don't update if this is a new contact - add after post() completes - store.dispatch({ type: Action.UPDATE_PROJECT_CONTACT, projectId: project.id, contact }); - } - - return new ApiRequest(`/projects/${ project.id }/contacts/${contact.isPrimary}`).post(contact).then(response => { - var updatedContact = response.data; - - // Add display fields - parseContact(updatedContact, project); // project's primary contact could be outdated - updatedContact.isPrimary = contact.isPrimary; - - if (isNew){ - // add newly created contact to Redux store's contacts - store.dispatch({ type: Action.ADD_PROJECT_CONTACT, projectId: project.id, contact: updatedContact }); - } else { - // Update Redux store's data with the server's data - store.dispatch({ type: Action.UPDATE_PROJECT_CONTACT, projectId: project.id, contact: updatedContact }); - } - - return updatedContact; - }); -} - -export function addProjectHistory(projectId, history) { - return new ApiRequest(`/projects/${ projectId }/history`).post(history).then((response) => { - var history = normalize(response.data); - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_PROJECT_HISTORY, history, id: projectId }); - }); -} - -export function getProjectHistory(projectId, params) { - return new ApiRequest(`/projects/${ projectId }/history`).get(params).then(response => { - var history = normalize(response.data); - - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_PROJECT_HISTORY, history, id: projectId }); - }); -} - -export function getProjectDocuments(projectId) { - return new ApiRequest(`/projects/${ projectId }/attachments`).get().then(response => { - var documents = normalize(response.data); - - // Add display fields - _.map(documents, document => { parseDocument(document); }); - - store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); - }); -} - -// XXX: Looks like this is unused -// export function addProjectDocument(projectId, files) { -// return new ApiRequest(`/projects/${ projectId }/attachments`).post(files); -// } - -export function getProjectNotes(projectId) { - return new ApiRequest(`/projects/${ projectId }/notes`).get().then((response) => { - store.dispatch({ type: Action.UPDATE_PROJECT_NOTES, projectId, notes: response.data }); - return response.data; - }); -} - -export function addProjectNote(projectId, note) { - store.dispatch({ type: Action.ADD_PROJECT_NOTE, projectId, note }); - return new ApiRequest(`/projects/${ projectId }/note`).post(note); -} - -export function getProjectRentalAgreements(projectId) { - return new ApiRequest(`/projects/${ projectId }/rentalAgreements`).get().then(response => { - var rentalAgreements = normalize(response.data); - store.dispatch({ type: Action.UPDATE_PROJECT_RENTAL_AGREEMENTS, rentalAgreements: rentalAgreements }); - return rentalAgreements; - }); -} - -export function cloneProjectRentalAgreement(data) { - return new ApiRequest(`/projects/${ data.projectId }/rentalAgreementClone`).post(data).then(response => { - var agreement = response.data; - // Add display fields - parseRentalAgreement(agreement); - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: agreement }); - return response; - }); -} - -//////////////////// -// Rental Requests -//////////////////// - -function parseRentalRequest(rentalRequest) { - if (!rentalRequest.localArea) { rentalRequest.localArea = { id: 0, name: '' }; } - if (!rentalRequest.localArea.serviceArea) { rentalRequest.localArea.serviceArea = { id: 0, name: '' }; } - if (!rentalRequest.localArea.serviceArea.district) { rentalRequest.localArea.serviceArea.district = { id: 0, name: '' }; } - if (!rentalRequest.localArea.serviceArea.district.region) { rentalRequest.localArea.serviceArea.district.region = { id: 0, name: '' }; } - if (!rentalRequest.project) { rentalRequest.project = { id: 0, name: '' }; } - if (!rentalRequest.districtEquipmentType) { rentalRequest.districtEquipmentType = { id: 0, districtEquipmentName: '' }; } - if (!rentalRequest.primaryContact) { rentalRequest.primaryContact = { id: 0, givenName: '', surname: '' }; } - if (!rentalRequest.rentalRequestAttachments) { rentalRequest.rentalRequestAttachments = []; } - if (!rentalRequest.rentalRequestRotationList) { rentalRequest.rentalRequestRotationList = []; } - - // Add display fields for primary contact - parseContact(rentalRequest.primaryContact); - - // Add display fields for rotation list items - _.map(rentalRequest.rentalRequestRotationList, listItem => { parseRentalRequestRotationList(listItem, rentalRequest); }); - - rentalRequest.status = rentalRequest.status || Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS; - rentalRequest.equipmentCount = rentalRequest.equipmentCount || 0; - rentalRequest.expectedHours = rentalRequest.expectedHours || 0; - rentalRequest.expectedStartDate = rentalRequest.expectedStartDate || ''; - rentalRequest.expectedEndDate = rentalRequest.expectedEndDate || ''; - - rentalRequest.projectId = rentalRequest.projectId || rentalRequest.project.id; - rentalRequest.projectName = rentalRequest.projectName || rentalRequest.project.name; - rentalRequest.projectPath = rentalRequest.projectId ? `/projects/${ rentalRequest.projectId }`: ''; - - // UI display fields - rentalRequest.isActive = rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS; - rentalRequest.isCompleted = rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED; - rentalRequest.isCancelled = rentalRequest.status === Constant.RENTAL_REQUEST_STATUS_CODE_CANCELLED; - rentalRequest.localAreaName = rentalRequest.localAreaName || rentalRequest.localArea.name; - rentalRequest.equipmentTypeName = rentalRequest.equipmentTypeName || rentalRequest.districtEquipmentType.districtEquipmentName; - - // Primary contact for the rental request/project - rentalRequest.primaryContactName = rentalRequest.primaryContact ? firstLastName(rentalRequest.primaryContact.givenName, rentalRequest.primaryContact.surname) : ''; - rentalRequest.primaryContactEmail = rentalRequest.primaryContact ? rentalRequest.primaryContact.emailAddress : ''; - rentalRequest.primaryContactRole = rentalRequest.primaryContact ? rentalRequest.primaryContact.role : ''; - rentalRequest.primaryContactPhone = rentalRequest.primaryContact ? rentalRequest.primaryContact.workPhoneNumber || rentalRequest.primaryContact.mobilePhoneNumber || '' : ''; - - rentalRequest.projectPrimaryContactName = rentalRequest.project.primaryContact ? firstLastName(rentalRequest.project.primaryContact.givenName, rentalRequest.project.primaryContact.surname) : ''; - rentalRequest.projectPrimaryContactEmail = rentalRequest.project.primaryContact ? rentalRequest.project.primaryContact.emailAddress : ''; - rentalRequest.projectPrimaryContactRole = rentalRequest.project.primaryContact ? rentalRequest.project.primaryContact.role : ''; - rentalRequest.projectPrimaryContactPhone = rentalRequest.project.primaryContact ? rentalRequest.project.primaryContact.workPhoneNumber || rentalRequest.project.primaryContact.mobilePhoneNumber || '' : ''; - // Flag element as a rental request. - // Rental requests and rentals are merged and shown in a single list on Project Details screen - rentalRequest.isRentalRequest = true; - - rentalRequest.path = `${ Constant.RENTAL_REQUESTS_PATHNAME }/${ rentalRequest.id }`; - rentalRequest.url = `#/${ rentalRequest.path }`; - rentalRequest.name = 'TBD'; - rentalRequest.historyEntity = History.makeHistoryEntity(Constant.HISTORY_REQUEST, rentalRequest); - rentalRequest.documentAdded = Log.rentalRequestDocumentAdded; - rentalRequest.documentsAdded = Log.rentalRequestDocumentsAdded; - rentalRequest.documentDeleted = Log.rentalRequestDocumentDeleted; - - rentalRequest.getDocumentsPromise = getRentalRequestDocuments; - rentalRequest.uploadDocumentPath = `/rentalrequests/${ rentalRequest.id }/attachments`; - - rentalRequest.canView = true; - rentalRequest.canEdit = true; - // HETS-894: view-only requests and requests that have yet to be acted on can be deleted - rentalRequest.canDelete = rentalRequest.projectId === 0 || rentalRequest.yesCount === 0; -} - -export function searchRentalRequests(params) { - store.dispatch({ type: Action.RENTAL_REQUESTS_REQUEST }); - return new ApiRequest('/rentalrequests/search').get(params).then((response) => { - var rentalRequests = normalize(response.data); - - // Add display fields - _.map(rentalRequests, req => { parseRentalRequest(req); }); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS, rentalRequests: rentalRequests }); - }); -} - -export function getRentalRequest(id) { - return new ApiRequest(`/rentalrequests/${ id }`).get().then((response) => { - var rentalRequest = response.data; - // Add display fields - parseRentalRequest(rentalRequest); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST, rentalRequest, rentalRequestId: id }); - - return rentalRequest; - }); -} - -export function addRentalRequest(rentalRequest, viewOnly) { - var path = viewOnly ? '/rentalrequests/viewOnly' : '/rentalrequests'; - - return new ApiRequest(path).post(rentalRequest).then((response) => { - var rentalRequest = response.data; - // Add display fields - parseRentalRequest(rentalRequest); - store.dispatch({ type: Action.ADD_RENTAL_REQUEST, rentalRequest, rentalRequestId: rentalRequest.id }); - - getEquipmentHires(); - - return rentalRequest; - }); -} - -export function updateRentalRequest(rentalRequest) { - // remove properties that interfere with deserialization - const rentalRequestId = rentalRequest.id; - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST, rentalRequest, rentalRequestId }); - - return new ApiRequest(`/rentalrequests/${ rentalRequest.id }`).put(_.omit(rentalRequest, 'primaryContact')).then((response) => { - var rentalRequest = response.data; - // Add display fields - parseRentalRequest(rentalRequest); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST, rentalRequest, rentalRequestId }); - }); -} - -export function addRentalRequestHistory(requestId, history) { - return new ApiRequest(`/rentalrequests/${ requestId }/history`).post(history).then((response) => { - var history = normalize(response.data); - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_HISTORY, history, id: requestId }); - }); -} - -export function getRentalRequestHistory(requestId, params) { - return new ApiRequest(`/rentalrequests/${ requestId }/history`).get(params).then(response => { - var history = normalize(response.data); - - // Add display fields - _.map(history, history => { parseHistory(history); }); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_HISTORY, history, id: requestId }); - }); -} - -export function getRentalRequestDocuments(rentalRequestId) { - return new ApiRequest(`/rentalrequests/${ rentalRequestId }/attachments`).get().then(response => { - var documents = normalize(response.data); - - // Add display fields - _.map(documents, document => { parseDocument(document); }); - - store.dispatch({ type: Action.UPDATE_DOCUMENTS, documents: documents }); - }); -} - -// XXX: Looks like this is unused -// export function addRentalRequestDocument(rentalRequestId, files) { -// return new ApiRequest(`/rentalrequests/${ rentalRequestId }/attachments`).post(files); -// } - -export function getRentalRequestNotes(rentalRequestId) { - return new ApiRequest(`/rentalrequests/${ rentalRequestId }/notes`).get().then((response) => { - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_NOTES, notes: response.data, rentalRequestId }); - return response.data; - }); -} - -export function addRentalRequestNote(rentalRequestId, note) { - return new ApiRequest(`/rentalRequests/${ rentalRequestId }/note`).post(note).then((response) => { - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_NOTES, notes: response.data, rentalRequestId }); - return response.data; - }); -} - -export function cancelRentalRequest(rentalRequestId) { - return new ApiRequest(`rentalrequests/${rentalRequestId}/cancel`).get().then(() => { - getEquipmentHires(); - }); -} - -//////////////////// -// Rental Request Rotation List -//////////////////// - -function getSeniorityDisplayName(blockNumber, numberOfBlocks, seniority, numberInBlock) { - if (blockNumber === numberOfBlocks) { - return `Open-${seniority && seniority.toFixed(3)} (${numberInBlock})`; - } else if (blockNumber == 1) { - return `1-${seniority && seniority.toFixed(3)} (${numberInBlock})`; - } else if (blockNumber == 2) { - return `2-${seniority && seniority.toFixed(3)} (${numberInBlock})`; - } - return `Open-${seniority && seniority.toFixed(3)} (${numberInBlock})`; -} - -function parseRentalRequestRotationList(rotationListItem, rentalRequest = {}) { - if (!rotationListItem.rentalRequest) { rotationListItem.rentalRequest = _.extend({ id: 0 }, _.pick(rentalRequest, 'id')); } - if (!rotationListItem.equipment) { rotationListItem.equipment = { id: 0, equipmentCode: '' }; } - if (!rotationListItem.equipment.districtEquipmentType) { rotationListItem.equipment.districtEquipmentType = { id: 0, districtEquipmentName: '' }; } - if (!rotationListItem.equipment.owner) { rotationListItem.equipment.owner = { id: 0, organizationName: '' }; } - - // The rental agreement (if any) created for an accepted hire offer. - rotationListItem.rentalAgreement = rotationListItem.rentalAgreement || null; - - // The sort order of the piece of equipment on the rotaton list at the time the request was created. - // This is the order the equipment will be offered the available work. - rotationListItem.rotationListSortOrder = rotationListItem.rotationListSortOrder || 0; - - rotationListItem.isForceHire = rotationListItem.isForceHire || false; - rotationListItem.wasAsked = rotationListItem.wasAsked || false; - rotationListItem.askedDateTime = rotationListItem.askedDateTime || ''; - rotationListItem.offerResponseDatetime = rotationListItem.offerResponseDatetime || ''; - rotationListItem.offerResponse = rotationListItem.offerResponse || ''; - rotationListItem.offerRefusalReason = rotationListItem.offerRefusalReason || ''; - rotationListItem.offerResponseNote = rotationListItem.offerResponseNote || ''; - rotationListItem.note = rotationListItem.note || ''; - - var equipment = rotationListItem.equipment; - - // UI display fields - rotationListItem.isHired = rotationListItem.isHired || false; - rotationListItem.seniority = getSeniorityDisplayName(equipment.blockNumber, equipment.numberOfBlocks, equipment.seniority, equipment.numberInBlock); - rotationListItem.serviceHoursThisYear = rotationListItem.serviceHoursThisYear || equipment.serviceHoursThisYear || 0; // TODO calculated field from the server - rotationListItem.equipmentId = equipment.id; - rotationListItem.equipmentCode = equipment.equipmentCode; - - // String format: "{year} {make}/{model}/{serialNumber}/{size}" - e.g. "1991 Bobcat/KOM450/442K00547/Medium" - rotationListItem.equipmentDetails = concat(equipment.year, concat(equipment.make, concat(equipment.model, concat(equipment.serialNumber, equipment.size, '/'), '/'), '/'), ' '); - - // Primary contact for the owner of the piece of equipment - rotationListItem.contact = rotationListItem.contact || (equipment.owner ? equipment.owner.primaryContact : null); - rotationListItem.contactName = rotationListItem.contact ? firstLastName(rotationListItem.contact.givenName, rotationListItem.contact.surname) : ''; - rotationListItem.contactEmail = rotationListItem.contact ? rotationListItem.contact.emailAddress : ''; - rotationListItem.contactPhone = rotationListItem.contact ? rotationListItem.contact.workPhoneNumber || rotationListItem.contact.mobilePhoneNumber || '' : ''; - - // TODO Status TBD - rotationListItem.status = 'N/A'; -} - -function parseRotationListItem(item, numberOfBlocks) { - item.equipment = item.equipment || {}; - item.equipment = { - ...item.equipment, - historyEntity: History.makeHistoryEntity(Constant.HISTORY_EQUIPMENT, { - ...item.equipment, - name: item.equipment.equipmentCode, - path: `${ Constant.EQUIPMENT_PATHNAME }/${ item.equipment.id }`, - url: `#/${ Constant.EQUIPMENT_PATHNAME }/${ item.equipment.id }`, - }), - }; - - item.displayFields = {}; - item.displayFields.equipmentDetails = concat(item.equipment.year, concat(item.equipment.make, concat(item.equipment.model, concat(item.equipment.serialNumber, item.equipment.size, '/'), '/'), '/'), ' '); - item.displayFields.seniority = getSeniorityDisplayName(item.equipment.blockNumber, numberOfBlocks, item.equipment.seniority, item.equipment.numberInBlock); - - var primaryContact = item.equipment.owner && item.equipment.owner.primaryContact; - item.displayFields.primaryContactName = primaryContact ? firstLastName(primaryContact.givenName, primaryContact.surname) : ''; -} - -export function getRentalRequestRotationList(id) { - return new ApiRequest(`/rentalrequests/${id}/rotationList`).get().then(response => { - const rentalRequest = response.data; - const rotationList = rentalRequest.rentalRequestRotationList; - - rotationList.map((item) => parseRotationListItem(item, rentalRequest.numberOfBlocks)); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST, rotationList, rentalRequestId: id }); - }); -} - -export function updateRentalRequestRotationList(rentalRequestRotationList, rentalRequest) { - const rentalRequestId = rentalRequest.id; - return new ApiRequest(`/rentalrequests/${ rentalRequestId }/rentalRequestRotationList`).put(rentalRequestRotationList).then(response => { - var rotationList = response.data.rentalRequestRotationList; - - rotationList.map((item) => parseRotationListItem(item, rentalRequest.numberOfBlocks)); - - store.dispatch({ type: Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST, rotationList, rentalRequestId }); - - getEquipmentTs(); - getEquipmentHires(); - }); -} - -//////////////////// -// Rental Agreements -//////////////////// - -function parseRentalAgreement(agreement) { - if (!agreement.district) { agreement.district = { id: 0, name: '' }; } - if (!agreement.equipment) { agreement.equipment = { id: 0, equipmentCode: '' }; } - if (!agreement.equipment.owner) { agreement.equipment.owner = { id: 0, organizationName: '' }; } - if (!agreement.equipment.districtEquipmentType) { agreement.equipment.districtEquipmentType = { id: 0, districtEquipmentName: '' }; } - if (!agreement.equipment.equipmentAttachments) { agreement.equipment.equipmentAttachments = []; } - if (!agreement.equipment.localArea) { agreement.equipment.localArea = { id: 0, name: '' }; } - if (!agreement.equipment.localArea.serviceArea) { agreement.equipment.localArea.serviceArea = { id: 0, name: '' }; } - if (!agreement.equipment.localArea.serviceArea.district) { agreement.equipment.localArea.serviceArea.district = { id: 0, name: '' }; } - if (!agreement.equipment.localArea.serviceArea.district.region) { agreement.equipment.localArea.serviceArea.district.region = { id: 0, name: '' }; } - if (!agreement.project) { agreement.project = { id: 0, name: '' }; } - if (!agreement.rentalAgreementRates) { agreement.rentalAgreementRates = []; } - if (!agreement.rentalAgreementConditions) { agreement.rentalAgreementConditions = []; } - if (!agreement.timeRecords) { agreement.timeRecords = []; } - - agreement.path = `${ Constant.RENTAL_AGREEMENTS_PATHNAME }/${ agreement.id }`; - agreement.url = `#/${ agreement.path }`; - - agreement.number = agreement.number || ''; - agreement.note = agreement.note || ''; - agreement.datedOn = agreement.datedOn || today(); - agreement.equipmentRate = agreement.equipmentRate || 0.0; - agreement.ratePeriod = agreement.ratePeriod || ''; // e.g. hourly, daily, etc. - agreement.rateComment = agreement.rateComment || ''; - - agreement.estimateStartWork = agreement.estimateStartWork || ''; - agreement.estimateHours = agreement.estimateHours || 0; - - agreement.rentalAgreementRates.forEach(obj => parseRentalRate(obj, agreement)); - agreement.rentalAgreementConditions.forEach(obj => parseRentalCondition(obj, agreement)); - - agreement.equipment = { ...agreement.equipment, - historyEntity: History.makeHistoryEntity(Constant.HISTORY_EQUIPMENT, { - ...agreement.equipment, - name: agreement.equipment.equipmentCode, - path: `${ Constant.EQUIPMENT_PATHNAME }/${ agreement.equipment.id }`, - url: `#/${ Constant.EQUIPMENT_PATHNAME }/${ agreement.equipment.id }`, - }), - }; - - // UI display fields - agreement.status = agreement.status || Constant.RENTAL_AGREEMENT_STATUS_CODE_ACTIVE; // TODO - agreement.isActive = agreement.status === Constant.RENTAL_AGREEMENT_STATUS_CODE_ACTIVE; - agreement.isCompleted = agreement.status === Constant.RENTAL_AGREEMENT_STATUS_CODE_COMPLETED; - agreement.equipmentId = agreement.equipment.id; - agreement.equipmentCode = agreement.equipment.equipmentCode; - agreement.equipmentMake = agreement.equipment.make; - agreement.equipmentModel = agreement.equipment.model; - agreement.equipmentSize = agreement.equipment.size; - agreement.equipmentTypeName = agreement.equipment.districtEquipmentType.districtEquipmentName; - agreement.ownerId = agreement.equipment.owner.id || 0; - agreement.ownerName = agreement.equipment.owner.organizationName || ''; - agreement.workSafeBCPolicyNumber = agreement.equipment.owner.workSafeBCPolicyNumber || ''; - agreement.pointOfHire = agreement.equipment.localArea.name || ''; - - agreement.projectId = agreement.projectId || agreement.project.id; - agreement.projectName = agreement.projectName || agreement.project.name; - - agreement.projectPath = agreement.projectId ? `${ Constant.PROJECTS_PATHNAME }/${ agreement.projectId }` : ''; - agreement.projectUrl = agreement.projectPath ? `#/${ agreement.projectPath }` : ''; - - agreement.canEdit = true; - - // Flag element as a rental agreement - // Rental requests and rentals are merged and shown in a single list on Project Details screen - agreement.isRentalAgreement = true; - - // TODO HETS-115 Server needs to send this - agreement.lastTimeRecord = agreement.lastTimeRecord || ''; -} - -// reverse the transformations applied by the parse function -function convertRentalAgreement(agreement) { - return { - ...agreement, - rentalAgreementConditions: _.values(agreement.rentalAgreementConditions), - rentalAgreementRates: _.values(agreement.rentalAgreementRates), - overtimeRates: _.values(agreement.overtimeRates), - equipmentId: agreement.equipmentId || null, - projectId: agreement.projectId || null, - }; -} - -export function getRentalAgreementSummaryLite() { - return new ApiRequest('/rentalagreements/summaryLite').get().then(response => { - var agreements = response.data; - - store.dispatch({ type: Action.UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP, agreements }); - }); -} - -export function getRentalAgreement(id) { - return new ApiRequest(`/rentalagreements/${ id }`).get().then(response => { - var agreement = response.data; - - // Add display fields - parseRentalAgreement(agreement); - - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: agreement }); - }); -} - -export function getLatestRentalAgreement(equipmentId, projectId) { - return new ApiRequest(`/rentalagreements/latest/${ projectId }/${ equipmentId }`).get().then(response => { - var agreement = response.data; - - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: agreement }); - - return agreement; - }); -} - -// XXX: Looks like this is unused -// export function addRentalAgreement(agreement) { -// return new ApiRequest('/rentalagreements').post(agreement).then(response => { -// var agreement = response.data; - -// // Add display fields -// parseRentalAgreement(agreement); - -// store.dispatch({ type: Action.ADD_RENTAL_AGREEMENT, rentalAgreement: agreement }); -// }); -// } - -export function updateRentalAgreement(agreement) { - var preparedAgreement = convertRentalAgreement(agreement); - - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: preparedAgreement }); - - return new ApiRequest(`/rentalagreements/${ agreement.id }`).put(preparedAgreement).then(response => { - var agreement = response.data; - - // Add display fields - parseRentalAgreement(agreement); - - store.dispatch({ type: Action.UPDATE_RENTAL_AGREEMENT, rentalAgreement: agreement }); - }); -} - -export function getRentalAgreementTimeRecords(rentalAgreementId) { - return new ApiRequest(`rentalagreements/${rentalAgreementId}/timeRecords`).get().then(response => { - var rentalAgreementTimeRecords = response.data; - - store.dispatch({ type: Action.RENTAL_AGREEMENT_TIME_RECORDS, rentalAgreementTimeRecords: rentalAgreementTimeRecords }); - }); -} - -export function addRentalAgreementTimeRecords(rentalRequestId, timeRecords) { - let formattedTimeRecords = formatTimeRecords(timeRecords, rentalRequestId); - return new ApiRequest(`rentalagreements/${rentalRequestId}/timeRecords`).post(formattedTimeRecords).then(response => { - var rentalAgreementTimeRecords = normalize(response.data.timeRecords); - - store.dispatch({ type: Action.RENTAL_AGREEMENT_TIME_RECORDS, rentalAgreementTimeRecords: rentalAgreementTimeRecords }); - return rentalAgreementTimeRecords; - }); -} - -export function releaseRentalAgreement(rentalAgreementId) { - return new ApiRequest(`rentalagreements/${rentalAgreementId}/release`).post().then(response => { - return response; - }); -} - -export function generateRentalAgreementDocument(rentalAgreementId) { - return new ApiRequest(`rentalagreements/${rentalAgreementId}/doc`).get(null, { ignoreResponse: true }); -} - -export function searchAitReport(params) { - store.dispatch({ type: Action.AIT_REPORT_REQUEST }); - return new ApiRequest('/rentalAgreements/aitReport').get(params).then(response => { - var aitResponses = normalize(response.data); - store.dispatch({ type: Action.UPDATE_AIT_REPORT, aitResponses: aitResponses }); - }); -} - - -//////////////////// -// Rental Rates -//////////////////// - -function parseRentalRate(rentalRate, parent = {}) { - // Pick only the properties that we need - if (!rentalRate.rentalAgreement) { rentalRate.rentalAgreement = _.extend({ id: 0, equipmentRate: 0 }, _.pick(parent, 'id', 'number', 'path', 'equipmentRate')); } - if (!rentalRate.timeRecords) { rentalRate.timeRecords = []; } - - rentalRate.path = rentalRate.rentalAgreement.path ? `${ rentalRate.rentalAgreement.path }/${ Constant.RENTAL_RATES_PATHNAME }/${ rentalRate.id }` : null; - rentalRate.url = rentalRate.path ? `#/${ rentalRate.path }` : null; - - rentalRate.rate = rentalRate.rate || 0.0; - rentalRate.percentOfEquipmentRate = rentalRate.percentOfEquipmentRate || 0; - rentalRate.ratePeriod = rentalRate.ratePeriod || rentalRate.ratePeriodType.ratePeriodTypeCode; - rentalRate.comment = rentalRate.comment || ''; - - // UI display fields - rentalRate.rentalAgreementId = rentalRate.rentalAgreement.id; - rentalRate.rentalAgreementNumber = rentalRate.rentalAgreement.number; - - rentalRate.canEdit = true; - rentalRate.canDelete = true; -} - -// XXX: Looks like this is unused -// export function getRentalRate(id) { -// return new ApiRequest(`/rentalagreementrates/${ id }`).get().then(response => { -// var rentalRate = response.data; - -// // Add display fields -// parseRentalRate(rentalRate); - -// store.dispatch({ type: Action.UPDATE_RENTAL_RATE, rentalRate: rentalRate }); -// }); -// } - -// export function addRentalRate(rentalRate) { -// return new ApiRequest('/rentalagreementrates').post({ ...rentalRate, rentalAgreement: { id: rentalRate.rentalAgreement.id } }).then(response => { -// var rentalRate = response.data; - -// // Add display fields -// parseRentalRate(rentalRate); - -// store.dispatch({ type: Action.ADD_RENTAL_RATE, rentalRate }); -// }); -// } - -export function addRentalRates(rentalAgreementId, rentalRates) { - store.dispatch({ type: Action.ADD_RENTAL_RATES, rentalRates, rentalAgreementId }); - - return new ApiRequest(`rentalagreements/${rentalAgreementId}/rateRecords`).post(rentalRates).then((response) => { - const data = _.find(response.data, { rentalAgreementId }); - var rentalRates = data.rentalAgreement.rentalAgreementRates; - - // Add display fields - rentalRates.forEach((rentalRate) => parseRentalRate(rentalRate, data.rentalAgreement)); - - store.dispatch({ type: Action.UPDATE_RENTAL_RATES, rentalRates, rentalAgreementId }); - - return rentalRates; - }); -} - -export function updateRentalRate(rentalRate) { - const rentalAgreementId = rentalRate.rentalAgreement.id; - store.dispatch({ type: Action.UPDATE_RENTAL_RATES, rentalRates: [rentalRate], rentalAgreementId }); - - return new ApiRequest(`/rentalagreementrates/${ rentalRate.id }`).put(rentalRate).then((response) => { - var rentalRate = response.data; - - // Add display fields - parseRentalRate(rentalRate); - - store.dispatch({ type: Action.UPDATE_RENTAL_RATES, rentalRates: [rentalRate], rentalAgreementId }); - - return rentalRate; - }); -} - -export function deleteRentalRate(rentalRate) { - const rentalAgreementId = rentalRate.rentalAgreement.id; - store.dispatch({ type: Action.DELETE_RENTAL_RATE, rentalRate, rentalAgreementId }); - - return new ApiRequest(`/rentalagreementrates/${ rentalRate.id }/delete`).post().then((response) => { - const rentalRate = response.data; - - // Add display fields - parseRentalRate(rentalRate); - - store.dispatch({ type: Action.DELETE_RENTAL_RATE, rentalRate, rentalAgreementId }); - - return rentalRate; - }); -} - - -//////////////////// -// Rental Conditions -//////////////////// - -function parseRentalCondition(rentalCondition, parent = {}) { - // Pick only the properties that we need - if (!rentalCondition.rentalAgreement) { rentalCondition.rentalAgreement = _.extend({ id: 0 }, _.pick(parent, 'id', 'number', 'path')); } - - rentalCondition.conditionName = rentalCondition.conditionName || ''; - rentalCondition.comment = rentalCondition.comment || ''; - - // UI display fields - rentalCondition.rentalAgreementId = rentalCondition.rentalAgreement.id; - rentalCondition.rentalAgreementNumber = rentalCondition.rentalAgreement.number; - rentalCondition.path = rentalCondition.rentalAgreement.path ? `${ rentalCondition.rentalAgreement.path }/${ Constant.RENTAL_CONDITIONS_PATHNAME }/${ rentalCondition.id }` : null; - rentalCondition.url = rentalCondition.path ? `#/${ rentalCondition.path }` : null; - - rentalCondition.canEdit = true; - rentalCondition.canDelete = true; -} - -// XXX: Looks like this is unused -// export function getRentalCondition(id) { -// return new ApiRequest(`/rentalagreementconditions/${ id }`).get().then(response => { -// var rentalCondition = response.data; - -// // Add display fields -// parseRentalCondition(rentalCondition); - -// store.dispatch({ type: Action.UPDATE_RENTAL_CONDITION, rentalCondition: rentalCondition }); -// }); -// } - -// XXX: Looks like this is unused -// export function addRentalCondition(rentalCondition) { -// return new ApiRequest('/rentalagreementconditions').post({ ...rentalCondition, rentalAgreement: { id: rentalCondition.rentalAgreement.id } }).then(response => { -// var rentalCondition = response.data; - -// // Add display fields -// parseRentalCondition(rentalCondition); - -// store.dispatch({ type: Action.ADD_RENTAL_CONDITION, rentalCondition: rentalCondition }); -// }); -// } - -export function addRentalConditions(rentalAgreementId, rentalConditions) { - store.dispatch({ type: Action.ADD_RENTAL_CONDITIONS, rentalConditions, rentalAgreementId }); - - return new ApiRequest(`rentalagreements/${rentalAgreementId}/conditionRecords`).post(rentalConditions).then(response => { - const data = _.find(response.data, { rentalAgreementId }); - var rentalConditions = data.rentalAgreement.rentalAgreementConditions; - - // Add display fields - rentalConditions.forEach((rentalCondition) => parseRentalCondition(rentalCondition, data.rentalAgreement)); - - store.dispatch({ type: Action.UPDATE_RENTAL_CONDITIONS, rentalConditions, rentalAgreementId }); - - return rentalConditions; - }); -} - -export function updateRentalCondition(rentalCondition) { - const rentalAgreementId = rentalCondition.rentalAgreement.id; - store.dispatch({ type: Action.UPDATE_RENTAL_CONDITIONS, rentalConditions: [rentalCondition], rentalAgreementId }); - - return new ApiRequest(`/rentalagreementconditions/${ rentalCondition.id }`).put(rentalCondition).then(response => { - var rentalCondition = response.data; - - // Add display fields - parseRentalCondition(rentalCondition); - - store.dispatch({ type: Action.UPDATE_RENTAL_CONDITIONS, rentalConditions: [rentalCondition], rentalAgreementId }); - - return rentalCondition; - }); -} - -export function deleteRentalCondition(rentalCondition) { - const rentalAgreementId = rentalCondition.rentalAgreement.id; - store.dispatch({ type: Action.DELETE_RENTAL_CONDITION, rentalCondition, rentalAgreementId }); - - return new ApiRequest(`/rentalagreementconditions/${ rentalCondition.id }/delete`).post().then(response => { - var rentalCondition = response.data; - - // Add display fields - parseRentalCondition(rentalCondition); - - store.dispatch({ type: Action.DELETE_RENTAL_CONDITION, rentalCondition, rentalAgreementId }); - - return rentalCondition; - }); -} - -export function deleteCondition(id) { - return new ApiRequest(`/conditiontypes/${id}/delete`).post().then(response => { - return response; - }); -} - -export function addCondition(condition) { - return new ApiRequest('conditiontypes/0').post(condition).then(response => { - return response; - }); -} - -export function updateCondition(condition) { - return new ApiRequest(`conditiontypes/${condition.id}`).post(condition).then(response => { - return response; - }); -} - - -//////////////////// -// Business -//////////////////// - -export function getBusiness() { - return new ApiRequest('/business').get().then(response => { - var business = response.data; - - if (!_.isObject(business)) { - business = { }; - } - - _.map(business.owners, owner => { parseOwner(owner); }); - store.dispatch({ type: Action.UPDATE_BUSINESS, business: business }); - }); -} - -export function getOwnerForBusiness(ownerId) { - return new ApiRequest(`/business/owner/${ ownerId }`).get().then(response => { - var owner = response.data; - - parseOwner(owner); - store.dispatch({ type: Action.UPDATE_OWNER, owner: owner }); - }); -} - -export function validateOwner(secretKey, postalCode) { - return new ApiRequest('/business/validateOwner').get({ sharedKey: secretKey, postalCode: postalCode }).then(response => { - var business = response.data; - parseOwner(business.linkedOwner); - store.dispatch({ type: Action.UPDATE_BUSINESS, business: business }); - }); -} - - -//////////////////// -// Rollovers -//////////////////// - -function parseRolloverStatus(status) { - status.rolloverInactive = status.progressPercentage == null; - status.rolloverActive = status.progressPercentage != null && status.progressPercentage >= 0 && status.progressPercentage < 100; - status.rolloverComplete = status.progressPercentage == 100; -} - -export function getRolloverStatus(districtId) { - return new ApiRequest(`/districts/${districtId}/rolloverStatus`).get(null, {silent: true}).then(response => { - var status = response.data; - parseRolloverStatus(status); - store.dispatch({ type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, status: status }); - }); -} - -export function initiateRollover(districtId) { - return new ApiRequest(`/districts/${districtId}/annualRollover`).get().then(response => { - var status = response; - parseRolloverStatus(status); - store.dispatch({ type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, status: status }); - }); -} - -export function dismissRolloverMessage(districtId) { - return new ApiRequest(`/districts/${districtId}/dismissRolloverMessage`).post().then(response => { - var status = response.data; - parseRolloverStatus(status); - store.dispatch({ type: Action.UPDATE_ROLLOVER_STATUS_LOOKUP, status: status }); - }); -} - - -//////////////////// -// Look-ups -//////////////////// - -// XXX: Looks like this is unused -// export function getCities() { -// return new ApiRequest('/cities').get().then(response => { -// var cities = normalize(response.data); - -// store.dispatch({ type: Action.UPDATE_CITIES_LOOKUP, cities: cities }); -// }); -// } - -export function getDistricts() { - return new ApiRequest('/districts').get().then(response => { - var districts = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_DISTRICTS_LOOKUP, districts: districts }); - }); -} - -export function getRegions() { - return new ApiRequest('/regions').get().then(response => { - var regions = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_REGIONS_LOOKUP, regions: regions }); - }); -} - -export function getLocalAreas(id) { - return new ApiRequest(`/districts/${id}/localAreas`).get().then(response => { - var localAreas = normalize(response.data); - _.map(localAreas, area => area.name = `${ area.serviceAreaId } - ${ area.name }`); - - store.dispatch({ type: Action.UPDATE_LOCAL_AREAS_LOOKUP, localAreas: localAreas }); - }); -} - -export function getServiceAreas() { - return new ApiRequest('/serviceareas').get().then(response => { - var serviceAreas = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_SERVICE_AREAS_LOOKUP, serviceAreas: serviceAreas }); - }); -} - -export function getEquipmentTypes() { - const silent = store.getState().lookups.equipmentTypes.loaded; - return new ApiRequest('/equipmenttypes', { silent }).get().then(response => { - var equipmentTypes = _.mapValues(normalize(response.data), x => { - x.blueBookSectionAndName = `${x.blueBookSection} - ${x.name}`; - return x; - }); - - store.dispatch({ type: Action.UPDATE_EQUIPMENT_TYPES_LOOKUP, equipmentTypes }); - }); -} - -export function getDistrictEquipmentTypes() { - const silent = store.getState().lookups.districtEquipmentTypes.loaded; - return new ApiRequest('/districtequipmenttypes', { silent }).get().then(response => { - var districtEquipmentTypes = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP, districtEquipmentTypes: districtEquipmentTypes }); - }); -} - -export function getDistrictEquipmentTypesAgreementSummary() { - const silent = store.getState().lookups.districtEquipmentTypesAgreementSummary.loaded; - return new ApiRequest('/districtequipmenttypes/agreementSummary', { silent }).get().then(response => { - var districtEquipmentTypes = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP, districtEquipmentTypes }); - }); -} - -export function getFiscalYears(districtId) { - return new ApiRequest(`/districts/${districtId}/fiscalYears`).get().then(response => { - store.dispatch({ type: Action.UPDATE_FISCAL_YEARS_LOOKUP, fiscalYears: response.data }); - }); -} - -export function getOwnersLite() { - const silent = store.getState().lookups.owners.lite.loaded; - return new ApiRequest('/owners/lite', { silent }).get().then(response => { - var owners = normalize(response.data); - store.dispatch({ type: Action.UPDATE_OWNERS_LITE_LOOKUP, owners: owners }); - }); -} - -export function getOwnersLiteHires() { - const silent = store.getState().lookups.owners.hires.loaded; - return new ApiRequest('/owners/liteHires', { silent }).get().then(response => { - var owners = normalize(response.data); - store.dispatch({ type: Action.UPDATE_OWNERS_LITE_HIRES_LOOKUP, owners: owners }); - }); -} - -export function getOwnersLiteTs() { - const silent = store.getState().lookups.owners.ts.loaded; - return new ApiRequest('/owners/liteTs', { silent }).get().then(response => { - var owners = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_OWNERS_LITE_TS_LOOKUP, owners: owners }); - }); -} - -export function addDistrictEquipmentType(equipment) { - return new ApiRequest(`/districtequipmenttypes/${equipment.id}`).post(equipment).then(response => { - return response; - }); -} - -export function updateDistrictEquipmentType(equipment) { - return new ApiRequest(`/districtequipmenttypes/${equipment.id}`).post(equipment).then(response => { - return response; - }); -} - -export function deleteDistrictEquipmentType(equipment) { - return new ApiRequest(`/districtequipmenttypes/${equipment.id}/delete`).post().then(response => { - return response; - }); -} - -export function getRoles() { - return new ApiRequest('/roles').get().then(response => { - var roles = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_ROLES_LOOKUP, roles: roles }); - }); -} - -export function getPermissions() { - return new ApiRequest('/permissions').get().then(response => { - var permissions = normalize(response.data); - - store.dispatch({ type: Action.UPDATE_PERMISSIONS_LOOKUP, permissions: permissions }); - }); -} - -// XXX: Looks like this is unused -// export function getProvincialRateTypes() { -// return new ApiRequest('/provincialratetypes').get().then(response => { -// var rateTypeOther = { -// id: 10000, -// rateType: 'OTHER', -// description: Constant.NON_STANDARD_CONDITION, -// rate: null, -// isPercentRate: false, -// isRateEditable: true, -// isIncludedInTotal: false, -// isInTotalEditable: true, -// }; -// var provincialRateTypes = [ ...response.data, rateTypeOther ]; - -// store.dispatch({ type: Action.UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP, provincialRateTypes: provincialRateTypes }); -// }); -// } - -export function getOvertimeRateTypes() { - return new ApiRequest('/provincialratetypes/overtime').get().then(response => { - store.dispatch({ type: Action.UPDATE_OVERTIME_RATE_TYPES_LOOKUP, overtimeRateTypes: response.data }); - }); -} - -export function updateOvertimeRateType(rate) { - return new ApiRequest(`/provincialratetypes/${rate.id}`).put(rate).then(response => { - return response; - }); -} - -export function getRentalConditions() { - store.dispatch({ type: Action.RENTAL_CONDITIONS_LOOKUP_REQUEST }); - return new ApiRequest('/conditiontypes').get().then(response => { - var rentalConditions = response.data; - - store.dispatch({ type: Action.UPDATE_RENTAL_CONDITIONS_LOOKUP, rentalConditions: rentalConditions }); - }); -} - -//////////////////// -// Version -//////////////////// - -export function getVersion() { - return new ApiRequest('/version').get().then(response => { - store.dispatch({ type: Action.UPDATE_VERSION, version: response }); - }); -} - -//////////////////// -// Notes -//////////////////// - -export function deleteNote(id) { - store.dispatch({ type: Action.DELETE_NOTE, noteId: id }); - return new ApiRequest(`/notes/${id}/delete`).post().then((response) => { - return response.data; - }); -} - -export function updateNote(note) { - return new ApiRequest(`/notes/${note.id}`).put(note).then((response) => { - return response.data; - }); -} - -//////////////////// -// Set User -//////////////////// - -export function setDevUser(user) { - return new ApiRequest(`/authentication/dev/token/${user}`).get().then(response => { - return response; - }); -} - -//////////////////// -// Time Records -//////////////////// - -export function deleteTimeRecord(timeRecordId) { - return new ApiRequest(`/timerecords/${timeRecordId}/delete`).post().then((response) => { - store.dispatch({ type: Action.DELETE_TIME_RECORD, timeRecord: response.data }); - }); -} diff --git a/client/src/js/components/Authorize.jsx b/client/src/js/components/Authorize.jsx deleted file mode 100644 index 3aae79811..000000000 --- a/client/src/js/components/Authorize.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import * as Constant from '../constants'; - -class Authorize extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - children: PropTypes.node, - }; - - render() { - var authorized = this.props.currentUser.hasPermission(Constant.PERMISSION_WRITE_ACCESS); - - if (!authorized) { - return <>; - } else { - return this.props.children; - } - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - }; -} - -export default connect(mapStateToProps)(Authorize); diff --git a/client/src/js/components/BadgeLabel.jsx b/client/src/js/components/BadgeLabel.jsx deleted file mode 100644 index d2beb93c9..000000000 --- a/client/src/js/components/BadgeLabel.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Label } from 'react-bootstrap'; - - -class BadgeLabel extends React.Component { - static propTypes = { - bsClass: PropTypes.string, - bsStyle: PropTypes.string, - className: PropTypes.string, - children: PropTypes.node, - }; - - render() { - return ; - } -} - - -export default BadgeLabel; diff --git a/client/src/js/components/CheckboxControl.jsx b/client/src/js/components/CheckboxControl.jsx deleted file mode 100644 index a5ac68bea..000000000 --- a/client/src/js/components/CheckboxControl.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Checkbox } from 'react-bootstrap'; -import _ from 'lodash'; - - -class CheckboxControl extends React.Component { - static propTypes = { - type: PropTypes.string, - updateState: PropTypes.func, - onChange: PropTypes.func, - children: PropTypes.node, - }; - - changed = (e) => { - // On change listener - if (this.props.onChange) { - this.props.onChange(e); - } - - // Update state - if (this.props.updateState && e.target.id) { - // Use e.target.id insted of this.props.id because it comes from the controlId. - this.props.updateState({ [e.target.id]: e.target.checked }); - } - }; - - render() { - var props = _.omit(this.props, 'updateState'); - - return - { this.props.children } - ; - } -} - -export default CheckboxControl; diff --git a/client/src/js/components/ColDisplay.jsx b/client/src/js/components/ColDisplay.jsx deleted file mode 100644 index 6b957362e..000000000 --- a/client/src/js/components/ColDisplay.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Row, Col } from 'react-bootstrap'; -import _ from 'lodash'; - - -class ColDisplay extends React.Component { - static propTypes = { - label: PropTypes.node, - children: PropTypes.node, - labelProps: PropTypes.object, - fieldProps: PropTypes.object, - }; - - render() { - var props = _.omit(this.props, 'label', 'labelProps', 'fieldProps'); - - return - - { this.props.label } - - - { this.props.children } - - ; - } -} - - -export default ColDisplay; diff --git a/client/src/js/components/Confirm.jsx b/client/src/js/components/Confirm.jsx deleted file mode 100644 index 56bf69019..000000000 --- a/client/src/js/components/Confirm.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Popover, ButtonGroup, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - - -class Confirm extends React.Component { - static propTypes = { - onConfirm: PropTypes.func.isRequired, - onCancel: PropTypes.func, - hide: PropTypes.func, - children: PropTypes.node, - title: PropTypes.string, - }; - - confirmed = () => { - this.props.onConfirm(); - this.props.hide(); - }; - - canceled = () => { - if (this.props.onCancel) { this.props.onCancel(); } - this.props.hide(); - }; - - render() { - var props = _.omit(this.props, 'onConfirm', 'onCancel', 'hide', 'children'); - - return - { this.props.children } -
- - - - -
-
; - } -} - - -export default Confirm; diff --git a/client/src/js/components/Countdown.jsx b/client/src/js/components/Countdown.jsx deleted file mode 100644 index 5cdc7b65c..000000000 --- a/client/src/js/components/Countdown.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - - -class Countdown extends React.Component { - static propTypes = { - time: PropTypes.number, - onEnd: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - timeLeft: props.time, - minutes: parseInt(props.time / 60, 10), - seconds: parseInt(props.time % 60, 10) < 10 ? '0' + parseInt(props.time % 60, 10) : parseInt(props.time % 60, 10), - fired: false, - }; - } - - componentDidMount() { - this.startTimer(); - } - - componentWillUnmount() { - clearInterval(this.state.interval); - } - - startTimer = () => { - var timeLeft = this.state.timeLeft; - var interval = setInterval(function () { - var minutes = parseInt(timeLeft / 60, 10); - var seconds = parseInt(timeLeft % 60, 10); - - seconds = seconds < 10 ? '0' + seconds : seconds; - - this.setState({ minutes, seconds }); - - if (--timeLeft < 0 && !this.state.fired) { - this.props.onEnd(); - this.setState({ fired: true }); - } - }.bind(this), 1000); - this.setState({ interval }); - }; - - render() { - return ( - - { this.state.minutes > 0 && `${this.state.minutes}m`} {this.state.seconds}s - - ); - } -} - - -export default Countdown; diff --git a/client/src/js/components/DateControl.jsx b/client/src/js/components/DateControl.jsx deleted file mode 100644 index 6850a5e0b..000000000 --- a/client/src/js/components/DateControl.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { ControlLabel, InputGroup, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; -import DateTime from 'react-datetime'; - - -class DateControl extends React.Component { - static propTypes = { - id: PropTypes.string.isRequired, - date: PropTypes.string, - format: PropTypes.string, - className: PropTypes.string, - label: PropTypes.string, - onChange: PropTypes.func, - updateState: PropTypes.func, - placeholder: PropTypes.string, - title: PropTypes.string, - disabled: PropTypes.bool, - isValidDate: PropTypes.func, - }; - - clicked = () => { - if (!this.props.disabled) { - this.input.focus(); - } - }; - - dateChanged = (date) => { - // ignore invalid dates - if (_.isString(date) || !date || !date.isValid()) { - return; - } - - var dateString = date.format(this.props.format || 'YYYY-MM-DD'); - this.notifyValueChanged(dateString); - }; - - dateBlurred = (date) => { - // when focus leaves input, if date is invalid, reset value to empty string - if (_.isString(date) || !date || !date.isValid()) { - this.notifyValueChanged(''); - } - }; - - notifyValueChanged = (dateString) => { - // On change listener - if (this.props.onChange) { - this.props.onChange(dateString, this.props.id); - } - - // Update state - if (this.props.updateState) { - this.props.updateState({ - [this.props.id]: dateString, - }); - } - }; - - render() { - var date = Moment.utc(this.props.date); - var format = this.props.format || 'YYYY-MM-DD'; - - var placeholder = this.props.placeholder || 'yyyy-mm-dd'; - var disabled = this.props.disabled; - - return
- {(() => { - // Inline label - if (this.props.label) { return { this.props.label }; } - })()} - - { this.input = input; } }} isValidDate={ this.props.isValidDate } - /> - - - - -
; - } -} - - -export default DateControl; diff --git a/client/src/js/components/DeleteButton.jsx b/client/src/js/components/DeleteButton.jsx deleted file mode 100644 index f8251e987..000000000 --- a/client/src/js/components/DeleteButton.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import Confirm from '../components/Confirm.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; - - -class DeleteButton extends React.Component { - static propTypes = { - onConfirm: PropTypes.func.isRequired, - name: PropTypes.string, - hide: PropTypes.bool, - }; - - render() { - var props = _.omit(this.props, 'onConfirm', 'hide', 'name'); - - return }> - - ; - } -} - - -export default DeleteButton; diff --git a/client/src/js/components/DropdownControl.jsx b/client/src/js/components/DropdownControl.jsx deleted file mode 100644 index 613998b7f..000000000 --- a/client/src/js/components/DropdownControl.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Dropdown, MenuItem, Popover, OverlayTrigger } from 'react-bootstrap'; -import _ from 'lodash'; - - -class DropdownControl extends React.Component { - static propTypes = { - // This is used to update state - id: PropTypes.string.isRequired, - - // This can be an array of strings or objects. If the latter, will use id/name by default. - items: PropTypes.array.isRequired, - - // If present, then items is an array of objects with ids - selectedId: PropTypes.any, - - // If present. then items is an array of strings - title: PropTypes.string, - - // Assumes item field is 'name' unless specified here. - fieldName: PropTypes.string, - - // Displayed when there's no selection - placeholder: PropTypes.string, - - // If blankLine is supplied, include an "empty" line at the top; - // If it has a string value, use that in place of blank. - blankLine: PropTypes.any, - - className: PropTypes.string, - disabled: PropTypes.bool, - onSelect: PropTypes.func, - updateState: PropTypes.func, - staticTitle: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - simple: _.has(props, 'title'), - - selectedId: props.selectedId || '', - title: this.buildTitle(props.title), - fieldName: props.fieldName || 'name', - open: false, - }; - } - - componentDidMount() { - if (!this.state.simple) { - // Have to wait until state is ready before initializing title. - this.setState({ - title: this.buildTitle(this.state.selectedId, this.props.items), - }); - } - } - - componentWillReceiveProps(nextProps) { - if (!_.isEqual(nextProps.items, this.props.items)) { - var items = nextProps.items || []; - this.setState({ - items: items, - title: this.buildTitle(this.state.simple ? this.state.title : this.state.selectedId, items), - }); - } else if (nextProps.selectedId !== this.props.selectedId) { - this.setState({ - selectedId: nextProps.selectedId, - title: this.buildTitle(nextProps.selectedId, this.props.items), - }); - } else if (!_.isEqual(nextProps.title, this.props.title)) { - this.setState({ title: this.buildTitle(nextProps.title) }); - } - } - - buildTitle = (keyEvent, items) => { - if (keyEvent) { - if (!items || this.state.simple) { - return keyEvent; - } else { - var selected = _.find(items, { id: keyEvent }); - if (selected) { - return selected[this.state.fieldName].toString(); - } - } - } - return this.props.placeholder || 'Select item'; - }; - - itemSelected = (keyEvent) => { - this.toggle(false); - - if (!this.props.staticTitle) { - this.setState({ - selectedId: keyEvent || '', - title: this.buildTitle(keyEvent, this.props.items), - }); - } - - var selected = this.state.simple ? keyEvent : _.find(this.props.items, { id: keyEvent }); - - // Send selected item to change listener - if (this.props.onSelect) { - this.props.onSelect(selected, this.props.id); - } - - // Update state with selected key - if (this.props.updateState) { - this.props.updateState({ - [this.props.id]: keyEvent, - }); - } - }; - - toggle = (open) => { - this.setState({ open: open }); - }; - - render() { - var props = _.omit(this.props, 'updateState', 'onSelect', 'items', 'selectedId', 'blankLine', 'fieldName', 'placeholder', 'staticTitle'); - - return - - - { this.props.items.length > 0 && -
    - { this.props.blankLine && - - { typeof this.props.blankLine === 'string' ? this.props.blankLine : ' ' } - - } - { - _.map(this.props.items, item => { - var menuItem = - { this.state.simple ? item : item[this.state.fieldName] } - ; - // Check for hover items - if (!this.state.simple && item.hoverText) { - return { item.hoverText } } - > - { menuItem } - ; - } - return menuItem; - }) - } -
- } -
-
; - } -} - -export default DropdownControl; diff --git a/client/src/js/components/EditButton.jsx b/client/src/js/components/EditButton.jsx deleted file mode 100644 index f43af8e7f..000000000 --- a/client/src/js/components/EditButton.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button, Glyphicon } from 'react-bootstrap'; -import { LinkContainer } from 'react-router-bootstrap'; -import _ from 'lodash'; - - -class EditButton extends React.Component { - static propTypes = { - pathname: PropTypes.string, - onClick: PropTypes.func, - view: PropTypes.bool, - name: PropTypes.string, - hide: PropTypes.bool, - }; - - render() { - var props = _.omit(this.props, 'view', 'name', 'hide', 'pathname'); - - var button = ; - - return this.props.pathname ? { button } : button; - } -} - - -export default EditButton; diff --git a/client/src/js/components/Favourites.jsx b/client/src/js/components/Favourites.jsx deleted file mode 100644 index cd45c0c61..000000000 --- a/client/src/js/components/Favourites.jsx +++ /dev/null @@ -1,225 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Alert, Dropdown, ButtonToolbar, Button } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import { Col, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../api'; - -import CheckboxControl from '../components/CheckboxControl.jsx'; -import DeleteButton from '../components/DeleteButton.jsx'; -import EditButton from '../components/EditButton.jsx'; -import FormDialog from '../components/FormDialog.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import RootCloseMenu from './RootCloseMenu.jsx'; - -import { isBlank } from '../utils/string'; - - -class EditFavouritesDialog extends React.Component { - static propTypes = { - favourite: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - name: props.favourite.name || '', - isDefault: props.favourite.isDefault || false, - nameError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.name !== this.props.favourite.name) { return true; } - if (this.state.isDefault !== this.props.favourite.isDefault) { return true; } - - return false; - }; - - isValid = () => { - if (isBlank(this.state.name)) { - this.setState({ nameError: 'Name is required' }); - return false; - } - return true; - }; - - onSubmit = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({isSaving: true}); - - const favourite = { - ...this.props.favourite, - name: this.state.name, - isDefault: this.state.isDefault, - }; - - const promise = favourite.id ? Api.updateFavourite(favourite) : Api.addFavourite(favourite); - promise.finally(() => { - this.setState({ isSaving: false }); - }); - - this.props.onSave(favourite); - } - - this.props.onClose(); - } - }; - - render() { - const { isSaving, name, nameError, isDefault } = this.state; - const { show, onClose } = this.props; - - return ( - - - Name * - - {nameError} - - - Default - - - ); - } -} - -class Favourites extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - title: PropTypes.string, - type: PropTypes.string.isRequired, - favourites: PropTypes.object.isRequired, - data: PropTypes.object.isRequired, - onSelect: PropTypes.func.isRequired, - pullRight: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - favouriteToEdit: {}, - showEditDialog: false, - open: false, - }; - } - - addFavourite = () => { - this.editFavourite({ - type: this.props.type, - name: '', - isDefault: false, - value: JSON.stringify(this.props.data), - }); - }; - - editFavourite = (favourite) => { - this.setState({ favouriteToEdit: favourite }); - this.openDialog(); - }; - - favoriteSaved = (favourite) => { - // Make sure there's only one default - if (favourite.isDefault) { - var oldDefault = _.find(this.props.favourites, f => f.isDefault); - if (oldDefault && (favourite.id !== oldDefault.id)) { - Api.updateFavourite({ - ...oldDefault, - isDefault: false, - }); - } - } - - this.closeDialog(); - }; - - deleteFavourite = (favourite) => { - Api.deleteFavourite(favourite); - }; - - selectFavourite = (favourite) => { - this.toggle(false); - this.props.onSelect(favourite); - }; - - openDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeDialog = () => { - this.setState({ showEditDialog: false }); - }; - - toggle = (open) => { - this.setState({ open: open }); - }; - - render() { - var title = this.props.title || 'Favourites'; - var className = `favourites ${ this.props.className || '' } ${ this.props.pullRight ? 'pull-right' : '' }`; - - return - { title } - -
- -
- {(() => { - if (Object.keys(this.props.favourites).length === 0) { return No favourites; } - - return
    - { - _.map(this.props.favourites, (favourite) => { - return
  • - - { favourite.isDefault ? : '' } - - - { favourite.name } - - - - - - - -
  • ; - }) - } -
; - })()} -
- { this.state.showEditDialog ? - : null - } -
; - } -} - - -export default Favourites; diff --git a/client/src/js/components/FileAttachDialog.jsx b/client/src/js/components/FileAttachDialog.jsx deleted file mode 100644 index 5030de092..000000000 --- a/client/src/js/components/FileAttachDialog.jsx +++ /dev/null @@ -1,84 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button, Glyphicon } from 'react-bootstrap'; - -import ModalDialog from './ModalDialog.jsx'; -import FilePicker from './FilePicker.jsx'; -import FileUpload from './FileUpload.jsx'; - - -class FileAttachDialog extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - parentName: PropTypes.string, - uploadPath: PropTypes.string, - show: PropTypes.bool.isRequired, - onClose: PropTypes.func.isRequired, - onUpload: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - files: [], - }; - } - - filesPicked = (files) => { - var existingFiles = this.state.files.slice(); - existingFiles.push.apply(existingFiles, files); - this.setState({ files: existingFiles }); - }; - - removeFile = (file) => { - var pos = this.state.files.indexOf(file); - var files = this.state.files.slice(); - files.splice(pos, 1); - this.setState({ files: files }); - }; - - filesUploaded = (result) => { - if (!(result instanceof Error)) { - this.setState({ files: [] }); - if (this.props.onUpload) { - this.props.onUpload(); - } - } - }; - - render() { - var fileList; - if (this.state.files.length > 0) { - fileList =
    { - this.state.files.map((file, i) => { - return
  1. - { file.name } - -
  2. ; - }) - } -
; - } - - var footer = - - - ; - - var titleAttr = `Attach files${ this.props.parentName ? ` to ${ this.props.parentName }` : '' }`; - - return { titleAttr } } onClose={ this.props.onClose } footer={ footer } - > - { fileList } -

-
- Select one or more files{ this.props.parentName ? ` to attach to ${ this.props.parentName }` : null } -

-
; - } -} - -export default FileAttachDialog; diff --git a/client/src/js/components/FilePicker.jsx b/client/src/js/components/FilePicker.jsx deleted file mode 100644 index e2bfb4dd6..000000000 --- a/client/src/js/components/FilePicker.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Glyphicon } from 'react-bootstrap'; - - -class FilePicker extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - label: PropTypes.string, - mimeTypes: PropTypes.array, - onFilesSelected: PropTypes.func, - }; - - filesPicked = (e) => { - this.props.onFilesSelected(e.target.files); - }; - - render() { - var classNames = [ 'file-picker' ]; - - if(this.props.className) { - classNames.push(this.props.className); - } - - return - - ; - } -} - -export default FilePicker; diff --git a/client/src/js/components/FileUpload.jsx b/client/src/js/components/FileUpload.jsx deleted file mode 100644 index f4f811c24..000000000 --- a/client/src/js/components/FileUpload.jsx +++ /dev/null @@ -1,105 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button, Glyphicon, OverlayTrigger, Tooltip, ProgressBar } from 'react-bootstrap'; - -import { request, buildApiPath } from '../utils/http'; -import { plural } from '../utils/string'; - - -const FILE_UPLOAD_PATH = '/test-file-upload'; - - -class FileUpload extends React.Component { - static displayName = 'FileUpload'; - - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - label: PropTypes.string, - files: PropTypes.array, - path: PropTypes.string, - onUploadProgress: PropTypes.func, - onUploadFinished: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - uploadInProgress: false, - percentUploaded: null, - fileUploadError: null, - }; - } - - uploadFiles = () => { - this.setState({ uploadInProgress: true, percentUploaded: 0 }); - - var options = { - method: 'POST', - files: this.props.files, - onUploadProgress: (percentComplete) => { - var percent = Math.round(percentComplete); - this.setState({ percentUploaded: percent }); - if (this.props.onUploadProgress) { - this.props.onUploadProgress(percent); - } - }, - }; - - this.uploadPromise = request(buildApiPath(this.props.path || FILE_UPLOAD_PATH), options).then(() => { - this.setState({ uploadInProgress: false, percentUploaded: null }); - if (this.props.onUploadFinished) { this.props.onUploadFinished(true); } - }, (err) => { - this.setState({ uploadInProgress: false, fileUploadError: err }); - if (this.props.onUploadFinished) { this.props.onUploadFinished(err); } - }); - }; - - reset = () => { - this.setState({ uploadInProgress: false, percentUploaded: null, fileUploadError: null }); - }; - - render() { - var classNames = [ 'file-upload', 'clearfix' ]; - - if(this.props.className) { - classNames.push(this.props.className); - } - - if(this.state.fileUploadError) { - classNames.push('file-upload-error'); - } - - var files = this.props.files || []; - var fileUploadButton, uploadProgressBar; - var error; - if (!this.state.fileUploadError) { - var uploadText = `Upload ${ files.length } ${ plural(files.length, 'File', 'Files') }`; - if (!this.state.uploadInProgress) { - var uploadTooltip = { uploadText }; - var notReady = files.length === 0; - - fileUploadButton = - - ; - } else { - uploadProgressBar = ; - } - } else { - error = { String(this.state.fileUploadError) } }> -

Upload Error

-
; - } - - return
- { fileUploadButton } - { uploadProgressBar } - { error } -
; - } -} - -export default FileUpload; diff --git a/client/src/js/components/FilterDropdown.jsx b/client/src/js/components/FilterDropdown.jsx deleted file mode 100644 index 2f580057b..000000000 --- a/client/src/js/components/FilterDropdown.jsx +++ /dev/null @@ -1,187 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; -import { Well, Dropdown, FormControl, MenuItem, OverlayTrigger, Tooltip } from 'react-bootstrap'; -import _ from 'lodash'; - -import RootCloseMenu from './RootCloseMenu.jsx'; - - -class FilterDropdown extends React.Component { - static propTypes = { - id: PropTypes.string.isRequired, - items: PropTypes.array.isRequired, - selectedId: PropTypes.number, - className: PropTypes.string, - // Assumes the 'name' field unless specified here. - fieldName: PropTypes.string, - placeholder: PropTypes.string, - // If blankLine is supplied, include an "empty" line at the top; - // If it has a string value, use that in place of blank. - blankLine: PropTypes.any, - disabled: PropTypes.bool, - disabledTooltip: PropTypes.node, - onSelect: PropTypes.func, - updateState: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - selectedId: props.selectedId || 0, - title: '', - filterTerm: '', - fieldName: props.fieldName || 'name', - open: false, - }; - } - - componentDidMount() { - // Have to wait until state is ready before initializing title. - var title = this.buildTitle(this.props.items, this.state.selectedId); - this.setState({ title: title }); - } - - componentDidUpdate(prevProps, prevState) { - if (!_.isEqual(this.props.items, prevProps.items)) { - var items = this.props.items || []; - var id = this.props.selectedId === undefined ? prevState.selectedId : this.props.selectedId; - this.setState({ - items: items, - title: this.buildTitle(items, id), - }); - } else if (this.props.selectedId !== prevProps.selectedId) { - this.setState({ - selectedId: this.props.selectedId, - title: this.buildTitle(prevProps.items, this.props.selectedId), - }); - } - } - - buildTitle = (items, selectedId) => { - if (selectedId) { - var selected = _.find(items, { id: selectedId }); - if (selected) { - return selected[this.state.fieldName].toString(); - } - } - return this.props.placeholder || 'Select item'; - }; - - itemSelected = (selectedId) => { - this.toggle(false); - - this.setState({ - selectedId: selectedId || '', - title: this.buildTitle(this.props.items, selectedId), - }); - - this.sendSelected(selectedId); - }; - - sendSelected = (selectedId) => { - var selected = _.find(this.props.items, { id: selectedId }); - - // Send selected item to change listener - if (this.props.onSelect) { - this.props.onSelect(selected, this.props.id); - } - - // Update state with selected Id - if (this.props.updateState) { - this.props.updateState({ - [this.props.id]: selectedId, - }); - } - }; - - toggle = (open) => { - this.setState({ - open: open, - filterTerm: '', - }, () => { - if (open) { - this.input.focus(); - this.input.value = ''; - } - }); - }; - - filter = (e) => { - this.setState({ - filterTerm: e.target.value.toLowerCase().trim(), - }); - }; - - keyDown = (e) => { - if (e.key === 'Enter') { - e.preventDefault(); - } - }; - - filterItems = () => { - const { items } = this.props; - - if (this.state.filterTerm.length > 0) { - return _.filter(items, item => { - return item[this.state.fieldName].toLowerCase().indexOf(this.state.filterTerm) !== -1; - }); - } - - return items; - }; - - render() { - const { id, className, disabled, blankLine, disabledTooltip } = this.props; - - const items = this.filterItems(); - - const dropdown = ( - - - - - { this.input = ref; }} onKeyDown={this.keyDown}/> - - { items.length > 0 && ( -
    - { blankLine && this.state.filterTerm.length === 0 && - - { typeof blankLine === 'string' ? blankLine : ' ' } - - } - { - _.map(items, item => { - return - { item[this.state.fieldName] } - ; - }) - } -
- )} -
-
- ); - - if (disabled && disabledTooltip) { - const tooltip = { disabledTooltip }; - - return ( - - {dropdown} - - ); - } - - return dropdown; - } -} - -export default FilterDropdown; diff --git a/client/src/js/components/Form.jsx b/client/src/js/components/Form.jsx deleted file mode 100644 index 669e1c46c..000000000 --- a/client/src/js/components/Form.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Form as BootstrapForm } from 'react-bootstrap'; - - -const Form = (props) => { - const { children, onSubmit, ...rest } = props; - - function formSubmited(e) { - e.preventDefault(); - - if (onSubmit) { onSubmit(e); } - } - - return ( - - { children } - - ); -}; - -Form.propTypes = { - children: PropTypes.node, - onSubmit: PropTypes.func, -}; - -export default Form; diff --git a/client/src/js/components/FormDialog.jsx b/client/src/js/components/FormDialog.jsx deleted file mode 100644 index 9a7bf9ff6..000000000 --- a/client/src/js/components/FormDialog.jsx +++ /dev/null @@ -1,84 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; -import { Modal, Button } from 'react-bootstrap'; - -import Form from './Form.jsx'; -import Spinner from './Spinner.jsx'; -import Authorize from './Authorize.jsx'; - - -class FormDialog extends React.Component { - static propTypes = { - show: PropTypes.bool.isRequired, - title: PropTypes.node, - id: PropTypes.string, - className: PropTypes.string, - bsSize: PropTypes.string, - isReadOnly: PropTypes.bool, - isSaving: PropTypes.bool, - onClose: PropTypes.func.isRequired, - onSubmit: PropTypes.func, - saveButtonLabel: PropTypes.string, - closeButtonLabel: PropTypes.string, - children: PropTypes.node, - }; - - closeDialog = () => { - this.props.onClose(); - }; - - formSubmitted = () => { - const { isSaving, onSubmit } = this.props; - - if (!isSaving) { - onSubmit(); - } - }; - - renderBody = () => { - const { children, saveButtonLabel, closeButtonLabel, isReadOnly, isSaving } = this.props; - - return ( -
- - {children} - - - - {!isReadOnly && ( - - - - )} - -
- ); - }; - - render() { - const { id, className, title, show, bsSize } = this.props; - - return ( - - - {title && ( - {title} - )} - - {show && this.renderBody()} - - ); - } -} - -export default FormDialog; diff --git a/client/src/js/components/FormInputControl.jsx b/client/src/js/components/FormInputControl.jsx deleted file mode 100644 index 6da82c681..000000000 --- a/client/src/js/components/FormInputControl.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormControl } from 'react-bootstrap'; -import _ from 'lodash'; - - -class FormInputControl extends React.Component { - static propTypes = { - type: PropTypes.string, - updateState: PropTypes.func, - inputRef: PropTypes.func, - autoFocus: PropTypes.bool, - autoComplete: PropTypes.string, - onChange: PropTypes.func, - children: PropTypes.node, - }; - - componentDidMount() { - if (this.props.autoFocus) { - this.input.focus(); - } - } - - changed = (e) => { - const { type, updateState, onChange } = this.props; - - // On change listener - if (onChange) { onChange(e); } - - if (updateState && e.target.id) { - // Use e.target.id insted of this.props.id because it comes from the controlId. - var value = e.target.value; - if (type === 'number' ) { - value = parseInt(value, 10); - if (_.isNaN(value)) { - value = ''; - } - } - if (type === 'float' ) { - value = parseFloat(value); - if (_.isNaN(value)) { - value = ''; - } - } - - // Update state - updateState({ [e.target.id]: value }); - } - }; - - refChanged = (ref) => { - this.input = ref; - if (this.props.inputRef) { this.props.inputRef(ref); } - } - - render() { - const { type, autoComplete, children } = this.props; - // XXX: eslint doesn't like `const { type, autoComplete, children, ...rest } = this.props;` - // using lodash omit for now - const rest = _.omit(this.props, 'type', 'autoComplete', 'children', 'updateState'); - - return ( - - {children} - - ); - } -} - -export default FormInputControl; diff --git a/client/src/js/components/History.jsx b/client/src/js/components/History.jsx deleted file mode 100644 index 17e525a42..000000000 --- a/client/src/js/components/History.jsx +++ /dev/null @@ -1,155 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Constant from '../constants'; -import * as History from '../history'; -import store from '../store'; - -import SortTable from './SortTable.jsx'; -import Spinner from './Spinner.jsx'; - -import { makeGetHistorySelector } from '../selectors/history-selectors.js'; - -import { formatDateTimeUTCToLocal } from '../utils/date'; -import { sortDir } from '../utils/array'; - - -// API limit: how many to fetch first time -const API_LIMIT = 10; - -class HistoryComponent extends React.Component { - static propTypes = { - historyEntity: PropTypes.object.isRequired, - refresh: PropTypes.bool.isRequired, - - // Used when displayed in a dialog - onClose: PropTypes.func, - - history: PropTypes.object, - users: PropTypes.object, - ui: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: !this.props.history, - fetchingMore: false, - - canShowMore: false, - - ui : { - sortField: props.ui.sortField || 'timestampSort', - sortDesc: props.ui.sortDesc !== false, - }, - }; - } - - componentWillReceiveProps(nextProps) { - if (nextProps.refresh && !this.props.refresh) { - this.fetch(true); - } - } - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_HISTORY_UI, history: this.state.ui }); - if (callback) { callback(); } - }); - }; - - fetch = (first) => { - // Easy mode: show 10 the first time and let the user load all of them with the - // "Show More" button. Can adapt for paginated / offset&limit calls if necessary. - - if (first) { - if (this.props.history) { - // if old data exists, update it in the background without displaying a loading spinner - this.setState({ loading: false }); - } else { - // if no data exists, display spinner while it loads - this.setState({ loading: true }); - } - } - - return History.get(this.props.historyEntity, 0, first ? API_LIMIT : null).finally(() => { - this.setState({ - loading: false, - canShowMore: first && Object.keys(this.props.history).length >= API_LIMIT, - }); - }); - }; - - showMore = () => { - this.setState({ fetchingMore: true }); - this.fetch().finally(() => { - this.setState({ fetchingMore: false }); - }); - }; - - render() { - const { loading, fetchingMore } = this.state; - - return ( -
- {(() => { - if (loading) { return
; } - - if (Object.keys(this.props.history).length === 0) { return No history; } - - var history = _.orderBy(this.props.history, [this.state.ui.sortField], sortDir(this.state.ui.sortDesc)); - - var headers = [ - { field: 'timestampSort', title: 'Timestamp' }, - { field: 'userName', title: 'User' }, - { field: 'event', noSort: true, title: 'Event' }, - { field: 'showMore', title: 'Show More', style: { textAlign: 'right' }, - node: fetchingMore? : ( - - ), - }, - ]; - return - { - history.map((history) => { - const event = History.renderEvent(history.historyText, this.props.onClose); - const formattedTimestamp = formatDateTimeUTCToLocal(history.lastUpdateTimestamp, Constant.DATE_TIME_LOG); - - return - { formattedTimestamp } - { history.lastUpdateUserid } - { event } - ; - }).concat(fetchingMore ? [ - - - , - ] : []) - } - ; - })()} -
- ); - } -} - -const makeMapStateToProps = () => { - const getHistorySelector = makeGetHistorySelector(); - const mapStateToProps = (state, props) => { - return { - history: getHistorySelector(state, props), - users: state.lookups.users, - ui: state.ui.history, - }; - }; - return mapStateToProps; -}; - -export default connect(makeMapStateToProps)(HistoryComponent); diff --git a/client/src/js/components/LinkControl.jsx b/client/src/js/components/LinkControl.jsx deleted file mode 100644 index 48f14d259..000000000 --- a/client/src/js/components/LinkControl.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormControl, InputGroup, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - - -class LinkControl extends React.Component { - static propTypes = { - // url(value) returns a URL, default is value. - url: PropTypes.func, - value: PropTypes.string, - id: PropTypes.string, - label: PropTypes.string, - title: PropTypes.string, - className: PropTypes.string, - updateState: PropTypes.func, - onChange: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - url: this.getUrl(props.value), - }; - } - - getUrl = (value) => { - return this.props.url ? this.props.url(value) : value; - }; - - changed = (e) => { - // On change listener - if (this.props.onChange) { - this.props.onChange(e); - } - - // Update state - if (this.props.updateState && e.target.id) { - // Use e.target.id insted of this.props.id because it comes from the controlId. - this.props.updateState({ [e.target.id]: e.target.value }); - } - - // Update href - this.setState({ - url: this.getUrl(e.target.value), - }); - }; - - render() { - var props = _.omit(this.props, 'updateState', 'url', 'id'); - - return
- {(() => { - // Inline label - if (this.props.label) { return { this.props.label }; } - })()} - - - - - - -
; - } -} - -export default LinkControl; diff --git a/client/src/js/components/Mailto.jsx b/client/src/js/components/Mailto.jsx deleted file mode 100644 index 0f5e541ab..000000000 --- a/client/src/js/components/Mailto.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -export const toSearchString = (searchParams = {}) => { - return Object.keys(searchParams).map(key => - `${key}=${encodeURIComponent(searchParams[key])}` - ).join('&'); -}; - -export const createMailtoLink = (email, headers) => { - let link = `mailto:${email}`; - if (headers) { - link += `?${toSearchString(headers)}`; - } - return link; -}; - -/** - * A react component to create and display a mailto link. - */ -class Mailto extends React.Component { - static propTypes = { - children: PropTypes.node.isRequired, - email: PropTypes.string.isRequired, - headers: PropTypes.object, - }; - - render() { - const { email, headers, children, ...others } = this.props; - return - { children } - ; - } -} - -export default Mailto; diff --git a/client/src/js/components/ModalDialog.jsx b/client/src/js/components/ModalDialog.jsx deleted file mode 100644 index 4dc424ed9..000000000 --- a/client/src/js/components/ModalDialog.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Modal } from 'react-bootstrap'; -import _ from 'lodash'; - - -class ModalDialog extends React.Component { - static propTypes = { - title: PropTypes.node, - footer: PropTypes.node, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool.isRequired, - children: PropTypes.node, - }; - - render() { - var props = _.omit(this.props, 'title', 'footer', 'onClose'); - - return - - { this.props.title && - - { this.props.title } - - } - - - { this.props.children } - - { this.props.footer && - - { this.props.footer } - - } - ; - } -} - -export default ModalDialog; diff --git a/client/src/js/components/MultiDropdown.jsx b/client/src/js/components/MultiDropdown.jsx deleted file mode 100644 index aa336c559..000000000 --- a/client/src/js/components/MultiDropdown.jsx +++ /dev/null @@ -1,182 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Well, Dropdown, FormControl, Checkbox } from 'react-bootstrap'; -import RootCloseMenu from './RootCloseMenu.jsx'; -import _ from 'lodash'; - - -const MAX_ITEMS_FOR_TITLE = 3; - - -class MultiDropdown extends React.Component { - static propTypes = { - items: PropTypes.array.isRequired, - placeholder: PropTypes.string, - id: PropTypes.string.isRequired, - className: PropTypes.string, - fieldName: PropTypes.string, - selectedIds: PropTypes.array, - onChange: PropTypes.func, - updateState: PropTypes.func, - showMaxItems: PropTypes.number, - disabled: PropTypes.bool, - }; - - constructor(props) { - super(props); - - var selectedIds = props.selectedIds || []; - var items = props.items || []; - var fieldName = props.fieldName || 'name'; - - this.state = { - selectedIds: selectedIds, - title: '', - filterTerm: '', - maxItemsForTitle: props.showMaxItems || MAX_ITEMS_FOR_TITLE, - allSelected: selectedIds.length === items.length && selectedIds.length > 0, - fieldName: fieldName, - open: false, - }; - } - - componentDidMount() { - // Have to wait until state is ready before initializing title. - var title = this.buildTitle(this.props.items, this.state.selectedIds); - this.setState({ title: title }); - } - - componentWillReceiveProps(nextProps) { - if (!_.isEqual(nextProps.items, this.props.items)) { - var items = nextProps.items || []; - this.setState({ - items: items, - title: this.buildTitle(items, this.state.selectedIds), - }); - } - if (!_.isEqual(nextProps.selectedIds, this.props.selectedIds)) { - this.setState({ - selectedIds: nextProps.selectedIds, - title: this.buildTitle(this.props.items, nextProps.selectedIds), - }); - } - } - - buildTitle = (items, selectedIds) => { - var num = selectedIds.length; - - if (items.length === 0 || num === 0) { - return this.props.placeholder || 'Select items'; - } else if (num === items.length) { - return 'All selected'; - } else if (num > this.state.maxItemsForTitle) { - return `(${num}) selected`; - } else { - return _.map(_.pickBy(items, item => selectedIds.includes(item.id)), this.state.fieldName).join(', '); - } - }; - - itemSelected = (e) => { - var id = parseInt(e.target.value, 10); - var selectedIds = this.state.selectedIds.slice(); - - if(e.target.checked) { - selectedIds.push(id); - } else { - _.pull(selectedIds, id); - } - - this.setState({ - selectedIds: selectedIds, - title: this.buildTitle(this.props.items, selectedIds), - allSelected: selectedIds.length === this.props.items.length && selectedIds.length > 0, - }); - - this.sendSelected(selectedIds); - }; - - selectAll = (e) => { - var selectedIds = e.target.checked ? _.map(this.props.items, 'id') : []; - - this.setState({ - selectedIds: selectedIds, - allSelected: e.target.checked, - title: this.buildTitle(this.props.items, selectedIds), - }); - - this.sendSelected(selectedIds); - }; - - sendSelected = (selectedIds) => { - var selected = this.props.items.filter(item => selectedIds.includes(item.id)); - - // Send selected items to change listener - if (this.props.onChange) { - this.props.onChange(selected, this.props.id); - } - - // Update state with selected Ids - if (this.props.updateState) { - this.props.updateState({ - [this.props.id]: selectedIds, - }); - } - }; - - toggle = (open) => { - this.setState({ open: open }, () => { - if (open) { - this.input.focus(); - } - }); - }; - - filter = (e) => { - this.setState({ - filterTerm: e.target.value.toLowerCase().trim(), - }); - }; - - keyDown = (e) => { - if (e.key === 'Enter') { - e.preventDefault(); - } - }; - - render() { - var items = this.props.items; - - if (this.state.filterTerm.length > 0) { - items = _.filter(items, item => { - return item[this.state.fieldName].toLowerCase().indexOf(this.state.filterTerm) !== -1; - }); - } - - return - - - - { this.input = ref; }} autoComplete="off" onKeyDown={this.keyDown}/> - Select All - - { items.length > 0 && -
    - { - _.map(items, item => { - return
  • - - { item[this.state.fieldName] } - -
  • ; - }) - } -
- } -
-
; - } -} - -export default MultiDropdown; diff --git a/client/src/js/components/OverlayTrigger.jsx b/client/src/js/components/OverlayTrigger.jsx deleted file mode 100644 index abb5615cb..000000000 --- a/client/src/js/components/OverlayTrigger.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { cloneElement } from 'react'; -import { Overlay, OverlayTrigger } from 'react-bootstrap'; - -// This is a SUPER hacky way to get around the fact that the standard (as of 0.29.5) React Bootstrap -// doesn't have any way of allowing the overlay to close itself. Adding hide prop -// to the `cloneElement` call that just calls the hide method on the default OverlayTrigger causes -// the overlay to be closed. - -class CloseableOverlayTrigger extends OverlayTrigger { - makeOverlay(overlay, props) { - overlay = cloneElement(this.props.overlay, { - // All this overriding just for this one property! - hide: this.handleHide, - }); - - return ( - - {overlay} - - ); - } -} - -export default CloseableOverlayTrigger; diff --git a/client/src/js/components/PageOrientation.jsx b/client/src/js/components/PageOrientation.jsx deleted file mode 100644 index 3e692a40a..000000000 --- a/client/src/js/components/PageOrientation.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - - -class PageOrientation extends React.Component { - static propTypes = { - type: PropTypes.string.isRequired, - }; - - render() { - var size = 'portrait'; - if (this.props.type === 'landscape') { - size = 'landscape'; - } - - return ; - } -} - -export default PageOrientation; diff --git a/client/src/js/components/PrintButton.jsx b/client/src/js/components/PrintButton.jsx deleted file mode 100644 index 2d4bb6716..000000000 --- a/client/src/js/components/PrintButton.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; -import { Glyphicon } from 'react-bootstrap'; - -import TooltipButton from './TooltipButton.jsx'; - - -class PrintButton extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - title: PropTypes.string, - disabled: PropTypes.bool, - disabledTooltip: PropTypes.node, - children: PropTypes.node, - }; - - print = () => { - window.print(); - }; - - render() { - const { id, className, disabled, disabledTooltip, children } = this.props; - - return ( - - - {children} - - ); - } -} - -PrintButton.defaultProps = { - disabledTooltip: 'Please perform a search to print', -}; - - -export default PrintButton; diff --git a/client/src/js/components/ReturnButton.jsx b/client/src/js/components/ReturnButton.jsx deleted file mode 100644 index 974970183..000000000 --- a/client/src/js/components/ReturnButton.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; -import { browserHistory } from 'react-router'; -import { Button, Glyphicon } from 'react-bootstrap'; - - -class ReturnButton extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - title: PropTypes.string, - }; - - render() { - const { id, className, title } = this.props; - - return ( - - ); - } -} - - -export default ReturnButton; diff --git a/client/src/js/components/RootCloseMenu.jsx b/client/src/js/components/RootCloseMenu.jsx deleted file mode 100644 index 242b61695..000000000 --- a/client/src/js/components/RootCloseMenu.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { RootCloseWrapper } from 'react-overlays'; - - -class RootCloseMenu extends React.Component { - static propTypes = { - open: PropTypes.bool, - pullRight: PropTypes.bool, - onClose: PropTypes.func, - children: PropTypes.node, - }; - - render() { - return -
- { this.props.children } -
-
; - } -} - - -export default RootCloseMenu; diff --git a/client/src/js/components/SearchControl.jsx b/client/src/js/components/SearchControl.jsx deleted file mode 100644 index 4b241ac88..000000000 --- a/client/src/js/components/SearchControl.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { InputGroup } from 'react-bootstrap'; -import _ from 'lodash'; - -import DropdownControl from '../components/DropdownControl.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; - -import { notBlank } from '../utils/string'; - - -class SearchControl extends React.Component { - static propTypes = { - // This is an array of objects { id, name } - items: PropTypes.array.isRequired, - - search: PropTypes.object.isRequired, - updateState: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - key: props.search.key || '', - text: props.search.text || '', - params: props.search.params || null, - }; - } - - componentDidMount() { - this.updated({ - params: this.getParams(), - }); - } - - getParams = () => { - var params = null; - - if (notBlank(this.state.key) && notBlank(this.state.text)) { - params = {}; - params[this.state.key] = this.state.text; - } - - return params; - }; - - updated = (state) => { - if (state.text) { - state.text = state.text.trim(); - } - // update state - this.setState(state, () => { - // then update params - this.setState({ - params: this.getParams(), - }, () => { - // then update parent state - this.props.updateState(this.state); - }); - }); - }; - - render() { - var props = _.omit(this.props, 'updateState', 'search', 'items'); - - return
- - - - -
; - } -} - -export default SearchControl; diff --git a/client/src/js/components/SortTable.jsx b/client/src/js/components/SortTable.jsx deleted file mode 100644 index e00fbf9a1..000000000 --- a/client/src/js/components/SortTable.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Table, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import Spinner from '../components/Spinner.jsx'; - - -class SortTable extends React.Component { - static propTypes = { - // Array of objects with key, title, style, children fields - headers: PropTypes.array.isRequired, - // This should be a from a state.ui object - sortField: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.array, - ]).isRequired, - // This should be a from a state.ui object - sortDesc: PropTypes.bool.isRequired, - onSort: PropTypes.func.isRequired, - id: PropTypes.string, - isRefreshing: PropTypes.bool, - children: PropTypes.node, - }; - - sort = (field) => { - this.props.onSort({ - sortField: field, - sortDesc: !this.props.sortDesc, - }); - }; - - preventSelection = (e) => { - e.preventDefault(); - }; - - renderTableHeader = () => { - const {headers, sortField, sortDesc} = this.props; - - return headers.map((header) => { - const key = Array.isArray(header.field) ? header.field.join('-') : header.field; - if (header.node) { - return {header.node}; - } - - var sortGlyph = ''; - if (_.isEqual(sortField, header.field)) { - sortGlyph =  ; - } - - return ( - this.sort(header.field) } - className={ header.class } - style={{ ...header.style, cursor: header.noSort ? 'default' : 'pointer' }}> - { header.title }{ sortGlyph } - - ); - }); - }; - - render() { - const {id, isRefreshing, children} = this.props; - - return ( -
- {isRefreshing &&
} - - - - {this.renderTableHeader()} - - - - {children} - -
-
- ); - } -} - -export default SortTable; diff --git a/client/src/js/components/Spinner.jsx b/client/src/js/components/Spinner.jsx deleted file mode 100644 index 5c9d97bcc..000000000 --- a/client/src/js/components/Spinner.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import _ from 'lodash'; - - -const Spinner = (params) => { - var styles = _.extend({}, _.pick(params, 'width', 'height')); - - var hide = ''; - - if(params.show !== undefined) { - hide = params.show ? '' : 'hide'; - } - - if(params.size !== undefined) { - styles.width = +params.size || 16; - styles.height = +params.size || 16; - } - - var spinner = ; - if(params.centre) { - return
{spinner}
; - } else { - return spinner; - } -}; - -Spinner.propTypes = { - width: PropTypes.number, - height: PropTypes.number, - show: PropTypes.bool, - centre: PropTypes.bool, -}; - -export default Spinner; diff --git a/client/src/js/components/StatusDropdown.jsx b/client/src/js/components/StatusDropdown.jsx deleted file mode 100644 index d3ca91cc2..000000000 --- a/client/src/js/components/StatusDropdown.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import {DropdownButton, MenuItem } from 'react-bootstrap'; - -import * as Constant from '../constants'; - -import TooltipButton from './TooltipButton.jsx'; - - -class StatusDropdown extends React.Component { - static propTypes = { - id: PropTypes.string, - className: PropTypes.string, - status: PropTypes.string.isRequired, - statuses: PropTypes.array.isRequired, - disabled: PropTypes.bool, - disabledTooltip: PropTypes.node, - onSelect: PropTypes.func.isRequired, - }; - - computeBsStyle = () => { - switch(this.props.status) { - case Constant.EQUIPMENT_STATUS_CODE_APPROVED: - case Constant.OWNER_STATUS_CODE_APPROVED: - case Constant.PROJECT_STATUS_CODE_ACTIVE: - return 'success'; - case Constant.EQUIPMENT_STATUS_CODE_PENDING: - case Constant.OWNER_STATUS_CODE_PENDING: - case Constant.PROJECT_STATUS_CODE_COMPLETED: - return 'danger'; - default: - return 'default'; - } - }; - - render() { - const { - id, - className, - status, - statuses, - disabled, - disabledTooltip, - } = this.props; - - const bsStyle = this.computeBsStyle(); - const title = status || ''; - - if (disabled) { - return ( - - {title} - - ); - } else { - return ( - - {statuses.map((item) => { - return {item}; - })} - - ); - } - } -} - - -export default StatusDropdown; diff --git a/client/src/js/components/TableControl.jsx b/client/src/js/components/TableControl.jsx deleted file mode 100644 index 0cc02115d..000000000 --- a/client/src/js/components/TableControl.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Table } from 'react-bootstrap'; -import _ from 'lodash'; - - -class TableControl extends React.Component { - static propTypes = { - // Array of objects with key, title, style, children fields - headers: PropTypes.array.isRequired, - id: PropTypes.string, - children: PropTypes.node, - }; - - render() { - return
- - - - { - _.map(this.props.headers, (header) => { - return ; - }) - } - - - - { this.props.children } - -
{ header.node ? header.node : header.title }
-
; - } -} - -export default TableControl; diff --git a/client/src/js/components/TooltipButton.jsx b/client/src/js/components/TooltipButton.jsx deleted file mode 100644 index fc0a1a575..000000000 --- a/client/src/js/components/TooltipButton.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap'; - - -// simplifies adding tooltips for enabled and disabled buttons -class TooltipButton extends React.Component { - static propTypes = { - disabled: PropTypes.bool, - children: PropTypes.node, - enabledTooltip: PropTypes.node, - disabledTooltip: PropTypes.node, - onClick: PropTypes.func, - className: PropTypes.string, - style: PropTypes.object, - bsSize: PropTypes.string, - bsStyle: PropTypes.string, - }; - - static defaultProps = { - style: {}, - }; - - render() { - var buttonStyle = this.props.disabled ? {...this.props.style, pointerEvents : 'none' } : this.props.style; - - var button = ( - - ); - - var tooltipContent = this.props.disabled ? this.props.disabledTooltip : this.props.enabledTooltip; - if (tooltipContent) { - return ( - { tooltipContent } }> -
- { button } -
-
- ); - } else { - return button; - } - } -} - - -export default TooltipButton; diff --git a/client/src/js/components/Unimplemented.jsx b/client/src/js/components/Unimplemented.jsx deleted file mode 100644 index 0bebf4f41..000000000 --- a/client/src/js/components/Unimplemented.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { OverlayTrigger, Tooltip } from 'react-bootstrap'; - - -class Unimplemented extends React.Component { - static propTypes = { - children: PropTypes.node, - }; - - render() { - return This feature has not been released yet. - }> - { this.props.children } - ; - } -} - - -export default Unimplemented; diff --git a/client/src/js/components/Watermark.jsx b/client/src/js/components/Watermark.jsx deleted file mode 100644 index 1a432f4ad..000000000 --- a/client/src/js/components/Watermark.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -class Watermark extends React.Component { - static propTypes = { - enable: PropTypes.bool, - }; - - render() { - if (this.props.enable) { - return ( -
- View Only -
- Not for Hiring -
- ); - } else { - return <>; - } - } -} - -export default Watermark; diff --git a/client/src/js/components/ui/AddButtonContainer.jsx b/client/src/js/components/ui/AddButtonContainer.jsx deleted file mode 100644 index 7d89a5bca..000000000 --- a/client/src/js/components/ui/AddButtonContainer.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - - -class AddButtonContainer extends React.Component { - static propTypes = { - children: PropTypes.node, - }; - - render() { - return ( -
- { this.props.children } -
- ); - } -} - - -export default AddButtonContainer; diff --git a/client/src/js/components/ui/PageHeader.jsx b/client/src/js/components/ui/PageHeader.jsx deleted file mode 100644 index a53419114..000000000 --- a/client/src/js/components/ui/PageHeader.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; - - -class PageHeader extends React.Component { - static propTypes = { - title: PropTypes.node, - subTitle: PropTypes.node, - id: PropTypes.string, - className: PropTypes.string, - children: PropTypes.node, - }; - - render() { - const { title, subTitle,id, className, children } = this.props; - - return ( -

- {title} - {subTitle ? ': ' : ''}{subTitle && { subTitle }} - {children} -

- ); - } -} - - -export default PageHeader; diff --git a/client/src/js/components/ui/SearchBar.jsx b/client/src/js/components/ui/SearchBar.jsx deleted file mode 100644 index 76ddb1f40..000000000 --- a/client/src/js/components/ui/SearchBar.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Well } from 'react-bootstrap'; - - -class SearchBar extends React.Component { - static propTypes = { - children: PropTypes.node, - id: PropTypes.string, - }; - - render() { - return ( - - { this.props.children } - - ); - } -} - - -export default SearchBar; diff --git a/client/src/js/components/ui/SubHeader.jsx b/client/src/js/components/ui/SubHeader.jsx deleted file mode 100644 index fa8c92784..000000000 --- a/client/src/js/components/ui/SubHeader.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import classNames from 'classnames'; -import { Glyphicon } from 'react-bootstrap'; - -import TooltipButton from '../TooltipButton.jsx'; - - -class SubHeader extends React.Component { - static propTypes = { - title: PropTypes.string, - id: PropTypes.string, - className: PropTypes.string, - editButtonTitle: PropTypes.string, - editButtonDisabled: PropTypes.bool, - editButtonDisabledTooltip: PropTypes.node, - editIcon: PropTypes.string, - onEditClicked: PropTypes.func, - children: PropTypes.node, - }; - - render() { - const { - title, - id, - className, - editButtonTitle, - editButtonDisabled, - editButtonDisabledTooltip, - editIcon, - children, - onEditClicked, - } = this.props; - - var editButton = children; - if (onEditClicked && !children) { - editButton = ( - - - - ); - } - - return ( -

- {title} - - {editButton} - -

- ); - } -} - - -SubHeader.defaultProps = { - editIcon: 'pencil', -}; - - -export default SubHeader; diff --git a/client/src/js/constants.js b/client/src/js/constants.js deleted file mode 100644 index ca0492aa8..000000000 --- a/client/src/js/constants.js +++ /dev/null @@ -1,142 +0,0 @@ -// Paths -export const HOME_PATHNAME = 'home'; -export const OWNERS_PATHNAME = 'owners'; -export const EQUIPMENT_PATHNAME = 'equipment'; -export const PROJECTS_PATHNAME = 'projects'; -export const CONTACTS_PATHNAME = 'contacts'; -export const RENTAL_REQUESTS_PATHNAME = 'rental-requests'; -export const RENTAL_AGREEMENTS_PATHNAME = 'rental-agreements'; -export const OVERTIME_RATES_PATHNAME = 'overtime-rates'; -export const USERS_PATHNAME = 'users'; -export const ROLES_PATHNAME = 'roles'; -export const ROLLOVER_PATHNAME = 'roll-over'; -export const DISTRICT_ADMIN_PATHNAME = 'district-admin'; -export const SENIORITY_LIST_PATHNAME = 'reports/seniority-list'; -export const STATUS_LETTERS_REPORT_PATHNAME = 'reports/status-letters'; -export const HIRING_REPORT_PATHNAME = 'reports/owners-equipment-reason'; -export const OWNERS_COVERAGE_PATHNAME = 'reports/wcb-cgl-coverage'; -export const TIME_ENTRY_PATHNAME = 'time-entry'; -export const VERSION_PATHNAME = 'version'; -export const BUSINESS_PORTAL_PATHNAME = '/business'; -export const BUSINESS_DETAILS_PATHNAME = '/business/details'; -export const AIT_REPORT_PATHNAME = 'reports/rental-agreement-summary'; - -// Permissions -export const PERMISSION_LOGIN = 'Login'; -export const PERMISSION_BUSINESS_LOGIN = 'BusinessLogin'; -export const PERMISSION_ADMIN = 'Admin'; -export const PERMISSION_USER_MANAGEMENT = 'UserManagement'; -export const PERMISSION_ROLES_AND_PERMISSIONS = 'RolesAndPermissions'; -export const PERMISSION_IMPORT_DATA = 'ImportData'; -export const PERMISSION_CODE_TABLE_MANAGEMENT = 'CodeTableManagement'; -export const PERMISSION_DISTRICT_CODE_TABLE_MANAGEMENT = 'DistrictCodeTableManagement'; -export const PERMISSION_DISTRICT_ROLLOVER = 'DistrictRollover'; -export const PERMISSION_VERSION = 'Version'; -export const PERMISSION_WRITE_ACCESS = 'WriteAccess'; - -// Roles -export const ADMINISTRATOR_ROLE = '4-HETS System Administrator'; - -// Equipments -export const EQUIPMENT_DAYS_SINCE_VERIFIED_WARNING = 270; -export const EQUIPMENT_DAYS_SINCE_VERIFIED_CRITICAL = 365; - -export const EQUIPMENT_STATUS_CODE_PENDING = 'Unapproved'; -export const EQUIPMENT_STATUS_CODE_APPROVED = 'Approved'; -export const EQUIPMENT_STATUS_CODE_ARCHIVED = 'Archived'; - -// Owners -export const OWNER_STATUS_CODE_PENDING = 'Unapproved'; -export const OWNER_STATUS_CODE_APPROVED = 'Approved'; -export const OWNER_STATUS_CODE_ARCHIVED = 'Archived'; - -// Projects -export const PROJECT_STATUS_CODE_ACTIVE = 'Active'; -export const PROJECT_STATUS_CODE_COMPLETED = 'Completed'; - -// Rental Requests -export const RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS = 'In Progress'; -export const RENTAL_REQUEST_STATUS_CODE_COMPLETED = 'Complete'; -export const RENTAL_REQUEST_STATUS_CODE_CANCELLED = 'Cancelled'; - -// Hiring Refusal Reasons -export const HIRING_REFUSAL_EQUIPMENT_NOT_AVAILABLE = 'Equipment Not Available'; -export const HIRING_REFUSAL_EQUIPMENT_NOT_SUITABLE = 'Equipment Not Suitable'; -export const HIRING_REFUSAL_NO_RESPONSE = 'No Response'; -export const HIRING_REFUSAL_MAXIMUM_HOURS_REACHED = 'Maximum Hours Reached'; -export const HIRING_REFUSAL_MAINTENANCE_CONTRACTOR = 'Maintenance Contractor'; -export const HIRING_REFUSAL_OTHER = 'Other (Reason to be mentioned in note)'; - -// Rental Agreements -export const RENTAL_AGREEMENT_STATUS_CODE_ACTIVE = 'Active'; -export const RENTAL_AGREEMENT_STATUS_CODE_COMPLETED = 'Completed'; -export const RENTAL_RATE_PERIOD_HOURLY = 'Hr'; -export const RENTAL_RATE_PERIOD_DAILY = 'Daily'; -export const RENTAL_RATE_PERIOD_WEEKLY = 'Weekly'; -export const RENTAL_RATE_PERIOD_MONTHLY = 'Monthly'; -export const RENTAL_RATE_PERIOD_NEGOTIATED = 'Negotiated'; -export const RENTAL_RATE_PERIOD_SET = 'Set'; - -// Users -export const USER_STATUS_ACTIVE = 'Active'; -export const USER_STATUS_ARCHIVED = 'Archived'; - -// Date Formats -export const DATE_FULL_MONTH_DAY_YEAR = 'MMMM D, YYYY'; -export const DATE_SHORT_MONTH_DAY_YEAR = 'MMM D, YYYY'; -export const DATE_YEAR_SHORT_MONTH_DAY = 'YYYY-MMM-DD'; -export const DATE_ISO_8601 = 'YYYY-MM-DD'; - -export const DATE_ZULU = 'YYYY-MM-DDThh:mm:ss[Z]'; - -export const DATE_TIME_ISO_8601 = 'YYYY-MM-DDTHH:mm:ss'; -export const DATE_TIME_READABLE = 'MMMM D, YYYY [at] h:mm:ss A'; -export const DATE_TIME_LOG = 'YYYY/MM/DD HH:mm:ss'; -export const DATE_TIME_FILENAME = 'YYYY-MM-DD-HHmmss'; - -// RegEx -export const EMAIL_REGEX = /\S+@\S+\.\S+/; -export const NANP_REGEX = /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/; -export const MONEY_REGEX = /^\d+(\.\d\d?)?$/; -export const POSTAL_CODE_REGEX = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/; - -// Conditions -export const NON_STANDARD_CONDITION = 'Other'; - -// ResponseTypes - -export const RESPONSE_TYPE_BLOB = 'blob'; - -// Cloning -export const BY_PROJECT = 'By Project'; -export const BY_EQUIPMENT = 'By Equipment'; - -export var headerHeight = 0; -export function setHeaderHeight(num) { - headerHeight = num; -} - -// History -export const HISTORY_OWNER = 'Owner'; -export const HISTORY_PROJECT = 'Project'; -export const HISTORY_EQUIPMENT = 'Equipment'; -export const HISTORY_REQUEST = 'Request'; -export const HISTORY_USER = 'User'; -export const HISTORY_ROLE = 'Role'; -export const HISTORY_CONTACT = 'Contact'; -export const HISTORY_DOCUMENT = 'Document'; - -// Session -export const SESSION_TIMEOUT = 7200000; // 120 minutes -export const SESSION_KEEP_ALIVE_INTERVAL = 600000; // 10 minutes - -// Max Field Lengths -export const MAX_LENGTH_CGL_COMPANY_NAME = 150; -export const MAX_LENGTH_NOTE_TEXT = 2048; -export const MAX_LENGTH_PHONE_NUMBER = 20; -export const MAX_LENGTH_RENTAL_AGREEMENT_NOTE = 150; -export const MAX_LENGTH_STATUS_COMMENT = 255; - -// Max File Sizes -export const MAX_ATTACHMENT_FILE_SIZE = 5242880; // 5 MB -export const MAX_ATTACHMENT_FILE_SIZE_READABLE = '5 MB'; diff --git a/client/src/js/history.js b/client/src/js/history.js deleted file mode 100644 index 158036a9a..000000000 --- a/client/src/js/history.js +++ /dev/null @@ -1,328 +0,0 @@ -import React from 'react'; - -import * as Api from './api'; -import * as Constant from './constants'; - - -// History Events -export const OWNER_ADDED = 'Owner %e was added.'; -export const OWNER_MODIFIED = 'Owner %e was modified.'; -export const OWNER_MODIFIED_STATUS = 'Owner %e status changed to "%e". Comment: %e'; -export const OWNER_MODIFIED_NAME = 'Owner %e is now %e'; -export const OWNER_EQUIPMENT_ADDED = 'Owner %e added equipment %e.'; -export const OWNER_EQUIPMENT_VERIFIED = 'Owner %e verified equipment %e.'; -export const OWNER_MODIFIED_POLICY = 'Owner %e modified policy.'; -export const OWNER_DOCUMENT_ADDED = 'Owner %e added document %e.'; -export const OWNER_DOCUMENTS_ADDED = 'Owner %e added documents.'; -export const OWNER_DOCUMENT_DELETED = 'Owner %e removed document %e.'; -export const OWNER_CONTACT_ADDED = 'Owner %e added contact %e.'; -export const OWNER_CONTACT_UPDATED = 'Owner %e modified contact %e.'; -export const OWNER_CONTACT_DELETED = 'Owner %e removed contact %e.'; - -export const PROJECT_ADDED = 'Project %e was added.'; -export const PROJECT_MODIFIED = 'Project %e was modified.'; -export const PROJECT_MODIFIED_STATUS = 'Project %e status changed to %e.'; -export const PROJECT_MODIFIED_NAME = 'Project %e is now %e'; -export const PROJECT_EQUIPMENT_ADDED = 'Project %e added equipment %e.'; -export const PROJECT_CONTACT_ADDED = 'Project %e added contact %e.'; -export const PROJECT_CONTACT_UPDATED = 'Project %e modified contact %e.'; -export const PROJECT_CONTACT_DELETED = 'Project %e removed contact %e.'; -export const PROJECT_DOCUMENT_ADDED = 'Project %e added document %e.'; -export const PROJECT_DOCUMENTS_ADDED = 'Project %e added documents.'; -export const PROJECT_DOCUMENT_DELETED = 'Project %e removed document %e.'; -export const PROJECT_EQUIPMENT_RELEASED = 'Project %e released equipment %e.'; -export const PROJECT_RENTAL_REQUEST_ADDED = 'Project %e added rental request %e.'; - -export const USER_ADDED = 'User %e was added.'; -export const USER_MODIFIED = 'User %e was modified.'; -export const USER_DELETED = 'User %e was deleted.'; - -export const EQUIPMENT_ADDED = 'Equipment %e was added.'; -export const EQUIPMENT_MODIFIED = 'Equipment %e was modified.'; -export const EQUIPMENT_STATUS_MODIFIED = 'Equipment %e status changed to "%e". Comment: %e'; -export const EQUIPMENT_SENIORITY_MODIFIED = 'Equipment %e seniority was modified.'; -export const EQUIPMENT_DOCUMENT_ADDED = 'Equipment %e added document %e.'; -export const EQUIPMENT_DOCUMENTS_ADDED = 'Equipment %e added documents.'; -export const EQUIPMENT_DOCUMENT_DELETED = 'Equipment %e removed document %e.'; -export const EQUIPMENT_ATTACHMENT_ADDED = 'Equipment %e added attachment %e.'; -export const EQUIPMENT_ATTACHMENT_UPDATED = 'Equipment %e modified attachment %e.'; -export const EQUIPMENT_ATTACHMENT_DELETED = 'Equipment %e removed attachment %e.'; - -export const RENTAL_REQUEST_ADDED = 'Rental request %e was added.'; -export const RENTAL_REQUEST_MODIFIED = 'Rental request was modified.'; -export const RENTAL_REQUEST_DOCUMENT_ADDED = 'Rental request %e added document %e.'; -export const RENTAL_REQUEST_DOCUMENTS_ADDED = 'Rental request %e added documents.'; -export const RENTAL_REQUEST_DOCUMENT_DELETED = 'Rental request %e removed document %e.'; -export const RENTAL_REQUEST_EQUIPMENT_HIRED = 'Rental request %e equipment %e was given a response of %e.'; - -// Helper to create an entity object -export function makeHistoryEntity(type, entity) { - return { - type: type, - id: entity.id, - description: entity.name, - path: entity.path, - url: entity.url, - }; -} - -// Log a history event -export function log(historyEntity, event, ...entities) { - // prepend the 'parent' entity - entities.unshift(historyEntity); - - // Build the history text - var historyText = JSON.stringify({ - // The event text, with entity placeholders - text: event, - // The array of entities - entities: entities, - }); - - // Choose the correct API call. - var addHistoryPromise = null; - - switch (historyEntity.type) { - case Constant.HISTORY_OWNER: - addHistoryPromise = Api.addOwnerHistory; - break; - - case Constant.HISTORY_PROJECT: - addHistoryPromise = Api.addProjectHistory; - break; - - case Constant.HISTORY_EQUIPMENT: - addHistoryPromise = Api.addEquipmentHistory; - break; - - case Constant.HISTORY_REQUEST: - addHistoryPromise = Api.addRentalRequestHistory; - break; - - case Constant.HISTORY_USER: - case Constant.HISTORY_ROLE: - break; - } - - if (addHistoryPromise) { - return addHistoryPromise(historyEntity.id, { - historyText: historyText, - }); - } - - return null; -} - -function buildLink(entity, closeFunc) { - // Return a link if the entity has a path; just the description otherwise. - return entity.path ? { entity.description } : { entity.description }; -} - -export function renderEvent(historyText, closeFunc) { - try { - // Unwrap the JSONed event - var event = JSON.parse(historyText); - - // Parse the text and return it inside a
, replacing field placeholders with linked content. - var tokens = event.text.split('%e'); - return
- { - tokens.map((token, index) => { - return - { token } - { index < tokens.length - 1 ? buildLink(event.entities[index], closeFunc || null) : null } - ; - }) - } -
; - } catch (err) { - // Not JSON so just push out what's in there. - return { historyText }; - } -} - -export function get(historyEntity, offset, limit) { - // If not showing all, then just fetch the first 10 entries - var params = { - offset: offset || 0, - limit: limit || null, - }; - - switch (historyEntity.type) { - case Constant.HISTORY_OWNER: - return Api.getOwnerHistory(historyEntity.id, params); - - case Constant.HISTORY_PROJECT: - return Api.getProjectHistory(historyEntity.id, params); - - case Constant.HISTORY_EQUIPMENT: - return Api.getEquipmentHistory(historyEntity.id, params); - - case Constant.HISTORY_REQUEST: - return Api.getRentalRequestHistory(historyEntity.id, params); - - case Constant.HISTORY_USER: - case Constant.HISTORY_ROLE: - break; - } - - return null; -} - -// Logging -export function ownerAdded(owner) { - return log(owner.historyEntity, OWNER_ADDED); -} - -export function ownerModified(owner) { - return log(owner.historyEntity, OWNER_MODIFIED); -} - -export function ownerModifiedStatus(owner, status, statusComment) { - return log(owner.historyEntity, OWNER_MODIFIED_STATUS, { description: status }, { description: statusComment }); -} - -export function ownerContactAdded(owner, contact) { - return log(owner.historyEntity, OWNER_CONTACT_ADDED, contact.historyEntity); -} - -export function ownerContactUpdated(owner, contact) { - return log(owner.historyEntity, OWNER_CONTACT_UPDATED, contact.historyEntity); -} - -export function ownerContactDeleted(owner, contact) { - return log(owner.historyEntity, OWNER_CONTACT_DELETED, contact.historyEntity); -} - -export function ownerModifiedPolicy(owner) { - return log(owner.historyEntity, OWNER_MODIFIED_POLICY); -} - -export function ownerEquipmentAdded(owner, equipment) { - return log(owner.historyEntity, OWNER_EQUIPMENT_ADDED, equipment.historyEntity); -} - -export function ownerEquipmentVerified(owner, equipment) { - return log(owner.historyEntity, OWNER_EQUIPMENT_VERIFIED, equipment.historyEntity); -} - -export function ownerDocumentAdded(owner, document) { - return log(owner.historyEntity, OWNER_DOCUMENT_ADDED, { description: document }); -} - -export function ownerDocumentsAdded(owner) { - return log(owner.historyEntity, OWNER_DOCUMENTS_ADDED); -} - -export function ownerDocumentDeleted(owner, document) { - return log(owner.historyEntity, OWNER_DOCUMENT_DELETED, document.historyEntity); -} - -export function projectAdded(project) { - return log(project.historyEntity, PROJECT_ADDED); -} - -export function projectModified(project) { - return log(project.historyEntity, PROJECT_MODIFIED); -} - -export function projectModifiedStatus(project) { - return log(project.historyEntity, PROJECT_MODIFIED_STATUS, { description: project.status }); -} - -export function projectContactAdded(project, contact) { - return log(project.historyEntity, PROJECT_CONTACT_ADDED, contact.historyEntity); -} - -export function projectContactUpdated(project, contact) { - return log(project.historyEntity, PROJECT_CONTACT_UPDATED, contact.historyEntity); -} - -export function projectContactDeleted(project, contact) { - return log(project.historyEntity, PROJECT_CONTACT_DELETED, contact.historyEntity); -} - -export function projectDocumentAdded(project, document) { - return log(project.historyEntity, PROJECT_DOCUMENT_ADDED, { description: document }); -} - -export function projectDocumentsAdded(project) { - return log(project.historyEntity, PROJECT_DOCUMENTS_ADDED); -} - -export function projectDocumentDeleted(project, document) { - return log(project.historyEntity, PROJECT_DOCUMENT_DELETED, document.historyEntity); -} - -export function projectEquipmentReleased(project, equipment) { - return log(project.historyEntity, PROJECT_EQUIPMENT_RELEASED, equipment.historyEntity); -} - -export function projectRentalRequestAdded(project, rentalRequest) { - return log(project.historyEntity, PROJECT_RENTAL_REQUEST_ADDED, rentalRequest.historyEntity); -} - -export function equipmentAdded(equipment) { - return log(equipment.historyEntity, EQUIPMENT_ADDED); -} - -export function equipmentModified(equipment) { - return log(equipment.historyEntity, EQUIPMENT_MODIFIED); -} - -export function equipmentSeniorityModified(equipment) { - return log(equipment.historyEntity, EQUIPMENT_SENIORITY_MODIFIED); -} - -export function equipmentStatusModified(equipment, status, statusComment) { - return log(equipment.historyEntity, EQUIPMENT_STATUS_MODIFIED, { description: status }, { description: statusComment }); -} - -export function equipmentDocumentAdded(equipment, document) { - return log(equipment.historyEntity, EQUIPMENT_DOCUMENT_ADDED, { description: document }); -} - -export function equipmentDocumentsAdded(equipment) { - return log(equipment.historyEntity, EQUIPMENT_DOCUMENTS_ADDED); -} - -export function equipmentDocumentDeleted(equipment, document) { - return log(equipment.historyEntity, EQUIPMENT_DOCUMENT_DELETED, document.historyEntity); -} - -export function equipmentAttachmentAdded(equipment, attachment) { - return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_ADDED, { description: attachment }); -} - -export function equipmentAttachmentUpdated(equipment, attachment) { - return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_UPDATED, { description: attachment }); -} - -export function equipmentAttachmentDeleted(equipment, attachment) { - return log(equipment.historyEntity, EQUIPMENT_ATTACHMENT_DELETED, { description: attachment }); -} - -export function rentalRequestAdded(rentalRequest) { - return log(rentalRequest.historyEntity, RENTAL_REQUEST_ADDED); -} - -export function rentalRequestModified(rentalRequest) { - return log(rentalRequest.historyEntity, RENTAL_REQUEST_MODIFIED); -} - -export function rentalRequestDocumentAdded(rentalRequest, document) { - return log(rentalRequest.historyEntity, RENTAL_REQUEST_DOCUMENT_ADDED, { description: document }); -} - -export function rentalRequestDocumentsAdded(rentalRequest) { - return log(rentalRequest.historyEntity, RENTAL_REQUEST_DOCUMENTS_ADDED); -} - -export function rentalRequestDocumentDeleted(rentalRequest, document) { - return log(rentalRequest.historyEntity, RENTAL_REQUEST_DOCUMENT_DELETED, document.historyEntity); -} - -export function rentalRequestEquipmentHired(rentalRequest, equipment, offerResponse) { - console.log(equipment); - return log(rentalRequest.historyEntity, RENTAL_REQUEST_EQUIPMENT_HIRED, equipment.historyEntity, { description: offerResponse }); -} diff --git a/client/src/js/init.js b/client/src/js/init.js deleted file mode 100644 index debc247cc..000000000 --- a/client/src/js/init.js +++ /dev/null @@ -1,115 +0,0 @@ -/* global module */ - -import React from 'react'; -import ReactDOM from 'react-dom'; -import Promise from 'bluebird'; - -Promise.config({ - cancellation: true, - warnings: { - wForgottenReturn: false, - }, -}); - -import App from './App.jsx'; -import * as Api from './api'; -import { ApiError } from './utils/http'; - -var initializationEl = document.querySelector('#initialization'); -var progressBarEl = initializationEl.querySelector('.progress-bar'); -var progress = +progressBarEl.getAttribute('aria-valuenow'); - -function incrementProgressBar(gotoPercent) { - progress = Math.min(gotoPercent || (progress + 20), 100); // cap to 100% - progressBarEl.style.width = `${progress}%`; - progressBarEl.setAttribute('aria-valuenow', progress); - progressBarEl.querySelector('span').textContent = `${progress}% Complete`; -} - -if (module.hot) { - // NOTE: this is a terrible hack to work around react-router v3's warning about changing routes - // because of Webpack HMR. See: - // https://github.com/gaearon/react-hot-loader/issues/298#issuecomment-236510239 for more - // information. - // This can be removed once HETS-1169 is completed. - - const orgError = console.error; // eslint-disable-line no-console - console.error = (...args) => { // eslint-disable-line no-console - const routeChangeWarning = args && args.length === 1 && typeof args[0] === 'string' && args[0].indexOf('You cannot change ;') > -1; - if (!routeChangeWarning) { - // Log the error as normally - orgError.apply(console, args); - } - }; -} - -export default function startApp() { - if (process.env.NODE_ENV === 'development' && process.env.DEV_USER) { //eslint-disable-line - return Api.setDevUser(process.env.DEV_USER).finally(() => { //eslint-disable-line - initializeApp(); - }); - } - - return initializeApp(); -} - -function initializeApp() { - incrementProgressBar(5); - - Api.getCurrentUser().then(user => { - incrementProgressBar(33); - - return getLookups(user).then(() => { - incrementProgressBar(100); - - initializationEl.addEventListener('transitionend', () => { - const appElement = document.querySelector('#app'); - - ReactDOM.render(, appElement); - initializationEl.classList.add('done'); - initializationEl.addEventListener('transitionend', () => { - initializationEl.parentNode.removeChild(initializationEl); - }); - }); - }); - }).catch(err => { - showError(err); - }); -} - -function getLookups(user) { - if (user.businessUser) { - return Promise.resolve(); - } else { - var districtId = user.district.id; - return Promise.all([ - Api.getDistricts(), - Api.getRegions(), - Api.getServiceAreas(), - Api.getLocalAreas(districtId), - Api.getFiscalYears(districtId), - Api.getPermissions(), - Api.getCurrentUserDistricts(), - Api.getFavourites(), - ]); - } -} - -function showError(err) { - progressBarEl.classList.add('progress-bar-danger'); - progressBarEl.classList.remove('active'); - console.error(err); - var errorMessage = String(err); - if (err instanceof ApiError) { - errorMessage = err.message; - } - - ReactDOM.render(( -
-

Error loading application

-

{errorMessage}

-
- ), document.getElementById('init-error')); -} - -window.onload = startApp; diff --git a/client/src/js/reducers/all.js b/client/src/js/reducers/all.js deleted file mode 100644 index 641951f2c..000000000 --- a/client/src/js/reducers/all.js +++ /dev/null @@ -1,18 +0,0 @@ -import { combineReducers } from 'redux'; - -import uiReducer from './ui'; -import userReducer from './user'; -import searchReducer from './search'; -import modelsReducer from './models'; -import lookupsReducer from './lookups'; -import versionReducer from './version'; - - -export default combineReducers({ - ui : uiReducer, - user : userReducer, - search : searchReducer, - models : modelsReducer, - lookups : lookupsReducer, - version : versionReducer, -}); diff --git a/client/src/js/reducers/lookups.js b/client/src/js/reducers/lookups.js deleted file mode 100644 index 59ef6f924..000000000 --- a/client/src/js/reducers/lookups.js +++ /dev/null @@ -1,205 +0,0 @@ -import _ from 'lodash'; - -import * as Action from '../actionTypes'; - - -const DEFAULT_LOOKUPS = { - // cities: {}, - districts: {}, - regions: {}, - serviceAreas: {}, - localAreas: {}, - equipmentTypes: { - data: {}, - loaded: false, - }, - equipment: { - lite: { - data: {}, - loaded: false, - }, - agreementSummary: { - data: {}, - loaded: false, - }, - ts: { - data: {}, - loaded: false, - }, - hires: { - data: {}, - loaded: false, - }, - }, - districtEquipmentTypes: { - data: {}, - loaded: false, - }, - districtEquipmentTypesAgreementSummary: { - data: {}, - loaded: false, - }, - fiscalYears: {}, - permissions: {}, - rentalConditions: { - data: [], - loaded: false, - loading: false, - }, - // provincialRateTypes: [], - overtimeRateTypes: [], - // owners: { - // data: {}, - // loading: false, - // }, - owners: { - lite: { - data: {}, - loaded: false, - }, - ts: { - data: {}, - loaded: false, - }, - hires: { - data: {}, - loaded: false, - }, - }, - roles: {}, - projects: { - data: {}, - loaded: false, - }, - projectsCurrentFiscal: { - data: {}, - loaded: false, - }, - projectsAgreementSummary: { - data: {}, - loaded: false, - }, - agreementSummaryLite: { - data: {}, - loaded: false, - }, - users: {}, - rolloverStatus: {}, - searchSummaryCounts: {}, -}; - -export default function lookupsReducer(state = DEFAULT_LOOKUPS, action) { - switch(action.type) { - - // Loaded once at init time, as they do not change very often, and - // certainly not within the app. - - // XXX: Looks like this is unused - // case Action.UPDATE_CITIES_LOOKUP: - // return { ...state, cities: action.cities }; - - case Action.UPDATE_DISTRICTS_LOOKUP: - return { ...state, districts: action.districts }; - - case Action.UPDATE_REGIONS_LOOKUP: - return { ...state, regions: action.regions }; - - case Action.UPDATE_SERVICE_AREAS_LOOKUP: - return { ...state, serviceAreas: action.serviceAreas }; - - case Action.UPDATE_LOCAL_AREAS_LOOKUP: - return { ...state, localAreas: action.localAreas }; - - case Action.UPDATE_EQUIPMENT_TYPES_LOOKUP: - return { ...state, equipmentTypes: { data: action.equipmentTypes, loaded: true } }; - - case Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_LOOKUP: - return { ...state, districtEquipmentTypes: { data: action.districtEquipmentTypes, loaded: true } }; - - case Action.UPDATE_DISTRICT_EQUIPMENT_TYPES_AGREEMENT_SUMMARY_LOOKUP: - return { ...state, districtEquipmentTypesAgreementSummary: { data: action.districtEquipmentTypes, loaded: true } }; - - case Action.UPDATE_FISCAL_YEARS_LOOKUP: - return { ...state, fiscalYears: action.fiscalYears }; - - case Action.UPDATE_PERMISSIONS_LOOKUP: - return { ...state, permissions: action.permissions }; - - case Action.UPDATE_ROLLOVER_STATUS_LOOKUP: - return { ...state, rolloverStatus: action.status }; - - // Not typical lookups, because they can change within the app, so - // ensure they're loaded/updated as needed. - // XXX: Looks like this is unused - // case Action.OWNERS_LOOKUP_REQUEST: - // return { ...state, owners: { ...state.owners, loading: true } }; - - // XXX: Looks like this is unused - // case Action.UPDATE_OWNERS_LOOKUP: - // return { ...state, owners: { data: action.owners, loading: false } }; - - case Action.UPDATE_OWNERS_LITE_LOOKUP: - return { ...state, owners: { ...state.owners, lite: { data: action.owners, loaded: true } } }; - - case Action.UPDATE_OWNERS_LITE_HIRES_LOOKUP: - return { ...state, owners: { ...state.owners, hires: { data: action.owners, loaded: true } } }; - - case Action.UPDATE_OWNERS_LITE_TS_LOOKUP: - return { ...state, owners: { ...state.owners, ts: { data: action.owners, loaded: true } } }; - - case Action.UPDATE_EQUIPMENT_LITE_LOOKUP: - return { ...state, equipment: { ...state.equipment, lite: { data: action.equipment, loaded: true } } }; - - case Action.UPDATE_EQUIPMENT_AGREEMENT_SUMMARY_LOOKUP: - return { ...state, equipment: { ...state.equipment, agreementSummary: { data: action.equipment, loaded: true } } }; - - case Action.UPDATE_EQUIPMENT_TS_LOOKUP: - return { ...state, equipment: { ...state.equipment, ts: { data: action.equipment, loaded: true } } }; - - case Action.UPDATE_EQUIPMENT_HIRES_LOOKUP: - return { ...state, equipment: { ...state.equipment, hires: { data: action.equipment, loaded: true } } }; - - case Action.UPDATE_ROLES_LOOKUP: - return { ...state, roles: action.roles }; - - case Action.UPDATE_PROJECTS_LOOKUP: - return { ...state, projects: { ...state.projects, data: action.projects, loaded: true } }; - - case Action.UPDATE_PROJECTS_AGREEMENT_SUMMARY_LOOKUP: - return { ...state, projectsAgreementSummary: { data: action.projects, loaded: true } }; - - case Action.UPDATE_PROJECTS_CURRENT_FISCAL_LOOKUP: - return { - ...state, - projectsCurrentFiscal: { - ...state.projectsCurrentFiscal, - data: _.sortBy(action.projects, 'name'), - loaded: true, - }, - }; - - case Action.UPDATE_AGREEMENT_SUMMARY_LITE_LOOKUP: - return { ...state, agreementSummaryLite: { data: action.agreements, loaded: true } }; - - case Action.UPDATE_USERS_LOOKUP: - return { ...state, users: action.users }; - - case Action.UPDATE_RENTAL_CONDITIONS_LOOKUP: - return { ...state, rentalConditions: { data: action.rentalConditions, loading: false, loaded: true } }; - - case Action.RENTAL_CONDITIONS_LOOKUP_REQUEST: - return { ...state, rentalConditions: { ...state.rentalConditions, loading: true } }; - - // XXX: Looks like this is unused - // case Action.UPDATE_PROVINCIAL_RATE_TYPES_LOOKUP: - // return { ...state, provincialRateTypes: action.provincialRateTypes }; - - case Action.UPDATE_OVERTIME_RATE_TYPES_LOOKUP: - return { ...state, overtimeRateTypes: action.overtimeRateTypes }; - - case Action.UPDATE_SEARCH_SUMMARY_COUNTS: - return { ...state, searchSummaryCounts: action.searchSummaryCounts }; - } - - return state; -} diff --git a/client/src/js/reducers/models.js b/client/src/js/reducers/models.js deleted file mode 100644 index 2fdbdace0..000000000 --- a/client/src/js/reducers/models.js +++ /dev/null @@ -1,605 +0,0 @@ -import _ from 'lodash'; -import produce from 'immer'; - -import * as Action from '../actionTypes'; -import { findAndUpdate } from '../utils/array'; - -const DEFAULT_MODELS = { - users: { - data: {}, - loading: false, - loaded: false, - }, - user: {}, - userDistricts: { - data: {}, - loading: false, - }, - currentUserDistricts: { - data: {}, - loading: false, - }, - - favourites: { - equipment: {}, - hiringReport: {}, - owner: {}, - ownersCoverage: {}, - project: {}, - rentalRequests: {}, - timeEntry: {}, - user: {}, - aitReport: {}, - }, - - equipmentList: { - data: {}, - loading: false, - loaded: false, - }, - equipment: {}, - equipmentSeniorityHistory: {}, - equipmentNotes: [], - equipmentAttachments: {}, - equipmentHistory: {}, - equipmentRentalAgreements: { - data: {}, - }, - - owners: { - data: {}, - loading: false, - loaded: false, - }, - owner: {}, - ownerEquipment: { - data: {}, - loading: false, - loaded: false, - }, - ownerAttachments: {}, - ownerHistory: {}, - - projects: { - data: {}, - loading: false, - loaded: false, - }, - project: {}, - // projectEquipment: { - // data: {}, - // loading: false, - // success: false, - // }, - // projectTimeRecords: { - // data: {}, - // loading: false, - // success: false, - // }, - // projectNotes: {}, - // projectAttachments: {}, - // projectHistory: {}, - projectRentalAgreements: { - data: {}, - }, - - rentalRequests: { - data: {}, - loading: false, - loaded: false, - }, - rentalRequest: {}, - // rentalRequestNotes: {}, - // rentalRequestAttachments: {}, - // rentalRequestHistory: {}, - // rentalRequestRotationList: { - // data: {}, - // loading: false, - // success: false, - // }, - - rentalAgreement: {}, - rentalAgreementTimeRecords: {}, - // rentalRate: {}, - rentalCondition: {}, - rentalConditions: {}, - - timeEntries: { - data: {}, - loading: false, - loaded: false, - }, - - hiringResponses: { - data: {}, - loading: false, - loaded: false, - }, - - ownersCoverage: { - data: {}, - loading: false, - loaded: false, - }, - - aitResponses: { - data: {}, - loading: false, - loaded: false, - }, - - roles: {}, - role: {}, - rolePermissions: {}, - - // XXX: Looks like this is unused - // contacts: {}, - // contact: {}, - - documents: {}, - document: {}, - - history: { - equipment: {}, - owner: {}, - project: {}, - rentalRequest: {}, - }, - - timeRecord: { - data: {}, - }, - - business: null, -}; - -export default function modelsReducer(state = DEFAULT_MODELS, action) { - switch(action.type) { - // Users - case Action.USERS_REQUEST: - return { ...state, users: { ...state.users, loading: true, loaded: false } }; - - case Action.UPDATE_USERS: - return { ...state, users: { data: action.users, loading: false, loaded: true } }; - - case Action.CLEAR_USERS: - return { ...state, users: { data: {}, loading: false, loaded: false } }; - - case Action.UPDATE_USER: - return { ...state, user: action.user }; - - case Action.ADD_USER: - return { ...state, user: action.user }; - - case Action.DELETE_USER: - return { ...state, user: action.user }; - - case Action.USER_DISTRICTS: - return { ...state, userDistricts: { data: action.userDistricts, loading: false } }; - - case Action.CURRENT_USER_DISTRICTS: - return { ...state, currentUserDistricts: { data: action.currentUserDistricts, loading: false } }; - - // Favourites - case Action.UPDATE_FAVOURITES: - return { ...state, favourites: { ...state.favourites, ...action.favourites } }; - - case Action.ADD_FAVOURITE: case Action.UPDATE_FAVOURITE: - return { ...state, favourites: { ...state.favourites, [action.favourite.type]: { ...state.favourites[action.favourite.type], [action.favourite.id]: action.favourite } } }; - - case Action.DELETE_FAVOURITE: - return { ...state, favourites: { ...state.favourites, [action.favourite.type]: _.omit(state.favourites[action.favourite.type], [ action.favourite.id ]) } }; - - // Contacts - - // XXX: Looks like this is unused - // case Action.ADD_CONTACT: - // return { ...state, contact: action.contact }; - - // XXX: Looks like this is unused - // case Action.UPDATE_CONTACT: - // return { ...state, contact: action.contact }; - - case Action.DELETE_CONTACT: - return produce(state, (draftState) => { - const contact = action.contact; - const contactId = contact.id; - - const existingOwner = draftState.owner[contact.ownerId]; - if (existingOwner) { - const updatedList = existingOwner.contacts.filter((contact) => contact.id !== contactId); - existingOwner.contacts = updatedList; - } - - const existingProject = draftState.project[contact.projectId]; - if (existingProject) { - const updatedList = existingProject.contacts.filter((contact) => contact.id !== contactId); - existingProject.contacts = updatedList; - } - }); - - // Documents - case Action.UPDATE_DOCUMENTS: - return { ...state, documents: action.documents }; - - case Action.ADD_DOCUMENT: - return { ...state, document: action.document }; - - case Action.UPDATE_DOCUMENT: - return { ...state, document: action.document }; - - case Action.DELETE_DOCUMENT: - return { ...state, document: action.document }; - - // Equipment - case Action.EQUIPMENT_LIST_REQUEST: - return { ...state, equipmentList: { ...state.equipmentList, loading: true, loaded: false } }; - - case Action.UPDATE_EQUIPMENT_LIST: - return { ...state, equipmentList: { data: action.equipmentList, loading: false, loaded: true } }; - - case Action.CLEAR_EQUIPMENT_LIST: - return { ...state, equipmentList: { data: {}, loading: false, loaded: false } }; - - case Action.ADD_EQUIPMENT: case Action.UPDATE_EQUIPMENT: - return produce(state, (draftState) => { - draftState.equipment[action.equipment.id] = action.equipment; - }); - - case Action.UPDATE_EQUIPMENT_NOTES: - return { ...state, equipmentNotes: action.notes }; - - case Action.UPDATE_EQUIPMENT_RENTAL_AGREEMENTS: - return { ...state, equipmentRentalAgreements: { data: action.rentalAgreements } }; - - // Owners - case Action.OWNERS_REQUEST: - return { ...state, owners: { ...state.owners, loading: true, loaded: false } }; - - case Action.UPDATE_OWNERS: - return { ...state, owners: { data: action.owners, loading: false, loaded: true } }; - - case Action.OWNER_EQUIPMENT_REQUEST: - return { ...state, ownerEquipment: { data: action.equipment, loading: true, loaded: false } }; - - case Action.UPDATE_OWNER_EQUIPMENT: - return { ...state, ownerEquipment: { data: action.equipment, loading: false, loaded: true } }; - - case Action.CLEAR_OWNERS: - return { ...state, owners: { data: {}, loading: false, loaded: false } }; - - // XXX: Looks like `Action.DELETE_OWNER` is unused - case Action.ADD_OWNER: case Action.UPDATE_OWNER:/* case Action.DELETE_OWNER: */ { - const ownerId = action.owner.id; - const owner = { notes: [], ...state.owner[ownerId], ...action.owner }; - return { ...state, owner: { ...state.owner, [ownerId]: owner } }; - } - - case Action.UPDATE_OWNER_NOTES: - return produce(state, (draftState) => { - const existingOwner = draftState.owner[action.ownerId] || {}; - existingOwner.notes = action.notes; - draftState.owner[action.ownerId] = existingOwner; - }); - - case Action.ADD_OWNER_NOTE: - return produce(state, (draftState) => { - const existingOwner = draftState.owner[action.ownerId]; - const existingNotes = existingOwner.notes || []; - existingNotes.push(action.note); - existingOwner.notes = existingNotes; - }); - - case Action.ADD_OWNER_CONTACT: - return produce(state, (draftState) => { - const existingOwner = draftState.owner[action.ownerId] || {}; - const updatedContacts = (existingOwner.contacts || []); - updatedContacts.push(action.contact); - - existingOwner.contacts = updatedContacts; - }); - - case Action.UPDATE_OWNER_CONTACT: - return produce(state, (draftState) => { - const existingOwner = draftState.owner[action.ownerId] || {}; - const updatedContacts = (existingOwner.contacts || []); - - if (action.contact.isPrimary) { - const previousPrimaryContact = _.find(updatedContacts, { isPrimary: true }); - if (previousPrimaryContact) { - previousPrimaryContact.isPrimary = false; - } - } - - const pos = _.findIndex(updatedContacts, (contact) => contact.id === action.contact.id); - updatedContacts[pos] = action.contact; - - existingOwner.contacts = updatedContacts; - }); - - - // Projects - case Action.PROJECTS_REQUEST: - return { ...state, projects: { ...state.projects, loading: true, loaded: false } }; - - case Action.UPDATE_PROJECTS: - return { ...state, projects: { data: action.projects, loading: false, loaded: true } }; - - case Action.CLEAR_PROJECTS: - return { ...state, projects: { data: {}, loading: false, loaded: false } }; - - case Action.ADD_PROJECT: case Action.UPDATE_PROJECT: { - const projectId = action.project.id; - const project = { notes: [], ...state.project[projectId], ...action.project }; - - return { ...state, project: { ...state.project, [projectId]: project } }; - } - - // case Action.UPDATE_PROJECT_EQUIPMENT: - // return { ...state, projectEquipment: { data: action.projectEquipment, loading: false, success: true } }; - - // XXX: Looks like this is unused - // case Action.UPDATE_PROJECT_TIME_RECORDS: - // return { ...state, projectTimeRecords: { data: action.projectTimeRecords, loading: false, success: true } }; - - case Action.ADD_PROJECT_NOTE: { - const existingProject = { ...state.project[action.projectId] || {} }; - const notes = (existingProject.notes || []).slice(); - notes.push(action.note); - - return { ...state, project: { ...state.project, [action.projectId]: existingProject } }; - } - - case Action.UPDATE_PROJECT_NOTES: { - const existingProject = { ...state.project[action.projectId] || {} }; - existingProject.notes = action.notes; - - return { ...state, project: { ...state.project, [action.projectId]: existingProject } }; - } - - case Action.UPDATE_PROJECT_RENTAL_AGREEMENTS: - return { ...state, projectRentalAgreements: { data: action.rentalAgreements } }; - - case Action.DELETE_PROJECT_RENTAL_REQUEST: { - const existingProject = { ...state.project[action.projectId] || {} }; - const updatedList = existingProject.rentalRequests.filter((rentalRequest) => rentalRequest.id !== action.requestId); - existingProject.rentalRequests = updatedList; - return { ...state, project: { ...state.project, [action.projectId]: existingProject } }; - } - - case Action.ADD_PROJECT_CONTACT: - return produce(state, (draftState) => { - const existingProject = draftState.project[action.projectId] || {}; - const updatedContacts = (existingProject.contacts || []); - updatedContacts.push(action.contact); - - existingProject.contacts = updatedContacts; - }); - - case Action.UPDATE_PROJECT_CONTACT: - return produce(state, (draftState) => { - const existingProject = draftState.project[action.projectId] || {}; - const updatedContacts = (existingProject.contacts || []); - - if (action.contact.isPrimary) { - const previousPrimaryContact = _.find(updatedContacts, { isPrimary: true }); - if (previousPrimaryContact) { - previousPrimaryContact.isPrimary = false; - } - } - - const pos = _.findIndex(updatedContacts, (contact) => contact.id === action.contact.id); - updatedContacts[pos] = action.contact; - - existingProject.contacts = updatedContacts; - }); - - // Rental Requests - case Action.RENTAL_REQUESTS_REQUEST: - return { ...state, rentalRequests: { ...state.rentalRequests, loading: true, loaded: false } }; - - case Action.UPDATE_RENTAL_REQUESTS: - return { ...state, rentalRequests: { data: action.rentalRequests, loading: false, loaded: true } }; - - case Action.CLEAR_RENTAL_REQUESTS: - return { ...state, rentalRequests: { data: {}, loading: false, loaded: false } }; - - // Rental Request - case Action.ADD_RENTAL_REQUEST: - case Action.UPDATE_RENTAL_REQUEST: - return produce(state, (draftState) => { - const rentalRequests = draftState.rentalRequest; - const rentalRequestId = action.rentalRequestId; - rentalRequests[rentalRequestId] = { - notes: [], - rotationList: [], - ...rentalRequests[rentalRequestId], - ...action.rentalRequest, - }; - }); - - case Action.UPDATE_RENTAL_REQUEST_NOTES: - return produce(state, (draftState) => { - const rentalRequests = draftState.rentalRequest; - const rentalRequestId = action.rentalRequestId; - rentalRequests[rentalRequestId] = { - ...rentalRequests[rentalRequestId], - notes: action.notes, - }; - }); - - case Action.UPDATE_RENTAL_REQUEST_ROTATION_LIST: - return produce(state, (draftState) => { - const rentalRequests = draftState.rentalRequest; - const rentalRequestId = action.rentalRequestId; - rentalRequests[rentalRequestId] = { - ...rentalRequests[rentalRequestId], - rotationList: action.rotationList, - }; - }); - - // Time Entries - case Action.TIME_ENTRIES_REQUEST: - return { ...state, timeEntries: { ...state.timeEntries, loading: true } }; - - case Action.UPDATE_TIME_ENTRIES: - return { ...state, timeEntries: { data: action.timeEntries, loading: false, loaded: true } }; - - case Action.CLEAR_TIME_ENTRIES: - return { ...state, timeEntries: { data: {}, loading: false, loaded: false } }; - - // Hiring Responses - case Action.HIRING_RESPONSES_REQUEST: - return { ...state, hiringResponses: { ...state.hiringResponses, loading: true, loaded: false } }; - - case Action.UPDATE_HIRING_RESPONSES: - return { ...state, hiringResponses: { data: action.hiringResponses, loading: false, loaded: true } }; - - case Action.CLEAR_HIRING_RESPONSES: - return { ...state, hiringResponses: { data: {}, loading: false, loaded: false } }; - - // Owners' Coverage - case Action.OWNERS_COVERAGE_REQUEST: - return { ...state, ownersCoverage: { ...state.ownersCoverage, loading: true, loaded: false } }; - - case Action.UPDATE_OWNERS_COVERAGE: - return { ...state, ownersCoverage: { data: action.ownersCoverage, loading: false, loaded: true } }; - - case Action.CLEAR_OWNERS_COVERAGE: - return { ...state, ownersCoverage: { data: {}, loading: false, loaded: false } }; - - // Rental Agreements - // XXX: Looks like this is unused - // case Action.ADD_RENTAL_AGREEMENT: - // return { ...state, rentalAgreement: { ...state.rentalAgreement, [action.rentalAgreement.id]: action.rentalAgreement } }; - - // case Action.GENERATE_ANOTHER_RENTAL_AGREEMENT: - // return { ...state, rentalAgreement: { ...state.rentalAgreement, [action.rentalAgreement.id]: action.rentalAgreement } }; - - case Action.UPDATE_RENTAL_AGREEMENT: - return produce(state, (draftState) => { - draftState.rentalAgreement[action.rentalAgreement.id] = action.rentalAgreement; - }); - - case Action.RENTAL_AGREEMENT_TIME_RECORDS: - return { ...state, rentalAgreementTimeRecords: action.rentalAgreementTimeRecords }; - - // Rental Rates, Conditions - case Action.ADD_RENTAL_RATES: - return produce(state, (draftState) => { - const rentalAgreementRates = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementRates; - rentalAgreementRates.push(...action.rentalRates); - }); - - case Action.UPDATE_RENTAL_RATES: - return produce(state, (draftState) => { - const rentalAgreementRates = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementRates; - action.rentalRates.forEach((rentalRate) => { - findAndUpdate(rentalAgreementRates, rentalRate, 'id'); - }); - }); - - case Action.DELETE_RENTAL_RATE: - return produce(state, (draftState) => { - const rentalAgreementRates = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementRates; - _.remove(rentalAgreementRates, { id: action.rentalRate.id }); - }); - - case Action.ADD_RENTAL_CONDITIONS: - return produce(state, (draftState) => { - const rentalAgreementConditions = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementConditions; - rentalAgreementConditions.push(...action.rentalConditions); - }); - - case Action.UPDATE_RENTAL_CONDITIONS: - return produce(state, (draftState) => { - const rentalAgreementConditions = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementConditions; - action.rentalConditions.forEach((rentalCondition) => { - findAndUpdate(rentalAgreementConditions, rentalCondition, 'id'); - }); - }); - - case Action.DELETE_RENTAL_CONDITION: - return produce(state, (draftState) => { - const rentalAgreementConditions = draftState.rentalAgreement[action.rentalAgreementId].rentalAgreementConditions; - _.remove(rentalAgreementConditions, { id: action.rentalCondition.id }); - }); - - - // AIT Report - case Action.AIT_REPORT_REQUEST: - return { ...state, aitResponses: { ...state.aitResponses, loading: true, loaded: false } }; - - case Action.UPDATE_AIT_REPORT: - return { ...state, aitResponses: { data: action.aitResponses, loading: false, loaded: true } }; - - case Action.CLEAR_AIT_REPORT: - return { ...state, aitResponses: { data: {}, loading: false, loaded: false } }; - - // Roles, Permissions - case Action.UPDATE_ROLES: - return { ...state, roles: action.roles }; - - case Action.ADD_ROLE: - return { ...state, role: action.role }; - - case Action.UPDATE_ROLE: - return { ...state, role: action.role }; - - case Action.DELETE_ROLE: - return { ...state, role: action.role }; - - case Action.UPDATE_ROLE_PERMISSIONS: - return { ...state, rolePermissions: action.rolePermissions }; - - // History - case Action.UPDATE_EQUIPMENT_HISTORY: - return produce(state, (draftState) => { - draftState.history.equipment[action.id] = action.history; - }); - - case Action.UPDATE_OWNER_HISTORY: - return produce(state, (draftState) => { - draftState.history.owner[action.id] = action.history; - }); - - case Action.UPDATE_PROJECT_HISTORY: - return produce(state, (draftState) => { - draftState.history.project[action.id] = action.history; - }); - - case Action.UPDATE_RENTAL_REQUEST_HISTORY: - return produce(state, (draftState) => { - draftState.history.rentalRequest[action.id] = action.history; - }); - - // Notes - case Action.DELETE_NOTE: { - let notesCollectionName = null; - - if (action.noteId in state.equipmentNotes) { - notesCollectionName = 'equipmentNotes'; - } - - if (notesCollectionName) { - const notes = state[notesCollectionName].slice(); - _.remove(notes, { id : action.noteId }); - - return { ...state, [notesCollectionName]: notes }; - } - - return state; - } - - // Time Record - case Action.DELETE_TIME_RECORD: - return { ...state, timeRecord: { data: action.timeRecord } }; - - // Businesses - case Action.UPDATE_BUSINESS: - return { ...state, business: action.business }; - } - return state; -} - -export const modelsSelector = (state) => state.models; diff --git a/client/src/js/reducers/search.js b/client/src/js/reducers/search.js deleted file mode 100644 index 9216a7df2..000000000 --- a/client/src/js/reducers/search.js +++ /dev/null @@ -1,50 +0,0 @@ -import * as Action from '../actionTypes'; - -const DEFAULT_SEARCHES = { - equipmentList: {}, - owners: {}, - projects: {}, - rentalRequests: {}, - timeEntries: {}, - hiringResponses: {}, - aitResponses: {}, - ownersCoverage: {}, - users: {}, - roles: {}, -}; - -export default function searchReducer(state = DEFAULT_SEARCHES, action) { - switch(action.type) { - case Action.UPDATE_EQUIPMENT_LIST_SEARCH: - return { ...state, equipmentList: action.equipmentList }; - - case Action.UPDATE_OWNERS_SEARCH: - return { ...state, owners: action.owners }; - - case Action.UPDATE_PROJECTS_SEARCH: - return { ...state, projects: action.projects }; - - case Action.UPDATE_RENTAL_REQUESTS_SEARCH: - return { ...state, rentalRequests: action.rentalRequests }; - - case Action.UPDATE_TIME_ENTRIES_SEARCH: - return { ...state, timeEntries: action.timeEntries }; - - case Action.UPDATE_HIRING_RESPONSES_SEARCH: - return { ...state, hiringResponses: action.hiringResponses }; - - case Action.UPDATE_OWNERS_COVERAGE_SEARCH: - return { ...state, ownersCoverage: action.ownersCoverage }; - - case Action.UPDATE_USERS_SEARCH: - return { ...state, users: action.users }; - - case Action.UPDATE_ROLES_SEARCH: - return { ...state, roles: action.roles }; - - case Action.UPDATE_AIT_SEARCH: - return { ...state, aitResponses: action.aitResponses }; - } - - return state; -} diff --git a/client/src/js/reducers/ui.js b/client/src/js/reducers/ui.js deleted file mode 100644 index 8a42bcd18..000000000 --- a/client/src/js/reducers/ui.js +++ /dev/null @@ -1,142 +0,0 @@ -import * as Action from '../actionTypes'; - -const DEFAULT_STATE = { - requests: { - waiting: false, - error: null, // ApiError - }, - - equipmentList: {}, - equipmentPhysicalAttachments: {}, - owners: {}, - ownerContacts: {}, - ownerEquipment: {}, - users: {}, - userRoles: {}, - projects: {}, - projectContacts: {}, - rentalRequests: {}, - timeEntries: {}, - hiringResponses: {}, - ownersCoverage: {}, - aitResponses: {}, - roles: {}, - history: {}, - documents: {}, - showSessionTimeoutDialog: false, - districtEquipment: {}, - appError: null, - showErrorDialog: false, - activeRentalAgreementId: null, - activeProjectId: null, - activeRentalRequestId: null, - activeOwnerId: null, - activeEquipmentId: null, -}; - -export default function uiReducer(state = DEFAULT_STATE, action) { - switch(action.type) { - // Requests - - case Action.REQUESTS_BEGIN: - return { ...state, requests: { ...state.requests, waiting: true } }; - - case Action.REQUESTS_END: - return { ...state, requests: { ...state.requests, waiting: false } }; - - case Action.REQUESTS_ERROR: - return { ...state, requests: { ...state.requests, error: action.error }, showErrorDialog: true }; - - // Screens - - case Action.UPDATE_EQUIPMENT_LIST_UI: - return { ...state, equipmentList: action.equipmentList }; - - case Action.UPDATE_PHYSICAL_ATTACHMENTS_UI: - return { ...state, equipmentPhysicalAttachments: action.equipmentPhysicalAttachments }; - - case Action.UPDATE_OWNERS_UI: - return { ...state, owners: action.owners }; - - case Action.UPDATE_USERS_UI: - return { ...state, users: action.users }; - - case Action.UPDATE_USER_ROLES_UI: - return { ...state, userRoles: action.userRoles }; - - case Action.UPDATE_OWNER_CONTACTS_UI: - return { ...state, ownerContacts: action.ownerContacts }; - - case Action.UPDATE_OWNER_EQUIPMENT_UI: - return { ...state, ownerEquipment: action.ownerEquipment }; - - case Action.UPDATE_PROJECTS_UI: - return { ...state, projects: action.projects }; - - case Action.UPDATE_PROJECT_CONTACTS_UI: - return { ...state, projectContacts: action.projectContacts }; - - case Action.UPDATE_RENTAL_REQUESTS_UI: - return { ...state, rentalRequests: action.rentalRequests }; - - case Action.UPDATE_TIME_ENTRIES_UI: - return { ...state, timeEntries: action.timeEntries }; - - case Action.UPDATE_HIRING_RESPONSES_UI: - return { ...state, hiringResponses: action.hiringResponses }; - - case Action.UPDATE_OWNERS_COVERAGE_UI: - return { ...state, ownersCoverage: action.ownersCoverage }; - - case Action.UPDATE_ROLES_UI: - return { ...state, roles: action.roles }; - - case Action.UPDATE_HISTORY_UI: - return { ...state, history: action.history }; - - case Action.UPDATE_DOCUMENTS_UI: - return { ...state, documents: action.documents }; - - case Action.UPDATE_DISTRICT_EQUIPMENT_UI: - return { ...state, districtEquipment: action.districtEquipment }; - - case Action.SET_ACTIVE_RENTAL_AGREEMENT_ID_UI: - return { ...state, activeRentalAgreementId: action.rentalAgreementId }; - - case Action.SET_ACTIVE_PROJECT_ID_UI: - return { ...state, activeProjectId: action.projectId }; - - case Action.SET_ACTIVE_RENTAL_REQUEST_ID_UI: - return { ...state, activeRentalRequestId: action.rentalRequestId }; - - case Action.SET_ACTIVE_OWNER_ID_UI: - return { ...state, activeOwnerId: action.ownerId }; - - case Action.SET_ACTIVE_EQUIPMENT_ID_UI: - return { ...state, activeEquipmentId: action.equipmentId }; - - case Action.UPDATE_AIT_REPORT_UI: - return { ...state, aitResponses: action.aitResponses }; - - // case Action.GENERATE_ANOTHER_RENTAL_AGREEMENT: - // return { ...state, activeRentalAgreementId: action.rentalAgreement.id }; - - // Modals - - case Action.SHOW_SESSION_TIMEOUT_DIALOG: - return { ...state, showSessionTimeoutDialog: true }; - - case Action.CLOSE_SESSION_TIMEOUT_DIALOG: - return { ...state, showSessionTimeoutDialog: false }; - - case Action.SHOW_ERROR_DIALOG: - return { ...state, appError: { ...action }, showErrorDialog: true }; - - case Action.CLOSE_ERROR_DIALOG: - return { ...state, showErrorDialog: false }; - } - - return state; -} - -export const uiSelector = (state) => state.ui; diff --git a/client/src/js/reducers/user.js b/client/src/js/reducers/user.js deleted file mode 100644 index 2ffb05492..000000000 --- a/client/src/js/reducers/user.js +++ /dev/null @@ -1,17 +0,0 @@ -import * as Action from '../actionTypes'; - -const DEFAULT_USER = { - firstName : null, - lastName : null, - fullName : null, - districtName : null, -}; - -export default function userReducer(state = DEFAULT_USER, action) { - switch(action.type) { - case Action.UPDATE_CURRENT_USER: - return { ...state, ...action.user }; - } - - return state; -} diff --git a/client/src/js/reducers/version.js b/client/src/js/reducers/version.js deleted file mode 100644 index e798f419f..000000000 --- a/client/src/js/reducers/version.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as Action from '../actionTypes'; - -const DEFAULT_VERSION = { - applicationVersions: [{ - - }], - databaseVersions: [{ - - }], -}; - -export default function versionReducer(state = DEFAULT_VERSION, action) { - switch(action.type) { - case Action.UPDATE_VERSION: - return { ...state, ...action.version }; - } - - return state; -} diff --git a/client/src/js/selectors/history-selectors.js b/client/src/js/selectors/history-selectors.js deleted file mode 100644 index 6571ef3d4..000000000 --- a/client/src/js/selectors/history-selectors.js +++ /dev/null @@ -1,37 +0,0 @@ -import { createSelector } from 'reselect'; - -import * as Constant from '../constants'; - -import { modelsSelector } from '../reducers/models'; - -import { activeEquipmentIdSelector, activeOwnerIdSelector, activeProjectIdSelector, activeRentalRequestIdSelector } from './ui-selectors'; - -const getHistoryType = (state, props) => { - return props.historyEntity.type; -}; - -export const makeGetHistorySelector = () => { - return createSelector( - [ modelsSelector, - getHistoryType, - activeEquipmentIdSelector, - activeOwnerIdSelector, - activeProjectIdSelector, - activeRentalRequestIdSelector, - ], - (models, historyType, activeEquipmentId, activeOwnerId, activeProjectId, activeRentalRequestId) => { - switch (historyType) { - case Constant.HISTORY_EQUIPMENT: - return models.history.equipment[activeEquipmentId]; - case Constant.HISTORY_OWNER: - return models.history.owner[activeOwnerId]; - case Constant.HISTORY_PROJECT: - return models.history.project[activeProjectId]; - case Constant.HISTORY_REQUEST: - return models.history.rentalRequest[activeRentalRequestId]; - default: - return null; - } - } - ); -}; diff --git a/client/src/js/selectors/ui-selectors.js b/client/src/js/selectors/ui-selectors.js deleted file mode 100644 index 4804c403b..000000000 --- a/client/src/js/selectors/ui-selectors.js +++ /dev/null @@ -1,64 +0,0 @@ -import { createSelector } from 'reselect'; - -import { uiSelector } from '../reducers/ui'; -import { modelsSelector } from '../reducers/models'; - - -export const activeRentalAgreementIdSelector = createSelector( - uiSelector, - (ui) => parseInt(ui.activeRentalAgreementId, 10) -); - -export const activeRentalAgreementSelector = createSelector( - activeRentalAgreementIdSelector, - modelsSelector, - (activeRentalAgreementId, models) => models.rentalAgreement[activeRentalAgreementId] || null -); - - -export const activeProjectIdSelector = createSelector( - uiSelector, - (ui) => parseInt(ui.activeProjectId, 10) -); - -export const activeProjectSelector = createSelector( - activeProjectIdSelector, - modelsSelector, - (activeProjectId, models) => models.project[activeProjectId] || null -); - - -export const activeRentalRequestIdSelector = createSelector( - uiSelector, - (ui) => parseInt(ui.activeRentalRequestId, 10) -); - -export const activeRentalRequestSelector = createSelector( - activeRentalRequestIdSelector, - modelsSelector, - (activeRentalRequestId, models) => models.rentalRequest[activeRentalRequestId] || null -); - - -export const activeOwnerIdSelector = createSelector( - uiSelector, - (ui) => parseInt(ui.activeOwnerId, 10) -); - -export const activeOwnerSelector = createSelector( - activeOwnerIdSelector, - modelsSelector, - (activeOwnerId, models) => models.owner[activeOwnerId] || null -); - - -export const activeEquipmentIdSelector = createSelector( - uiSelector, - (ui) => parseInt(ui.activeEquipmentId, 10) -); - -export const activeEquipmentSelector = createSelector( - activeEquipmentIdSelector, - modelsSelector, - (activeEquipmentId, models) => models.equipment[activeEquipmentId] || null -); diff --git a/client/src/js/store.js b/client/src/js/store.js deleted file mode 100644 index 991c7eee9..000000000 --- a/client/src/js/store.js +++ /dev/null @@ -1,40 +0,0 @@ -/* global process, require, module */ - -import { createStore, applyMiddleware, compose } from 'redux'; -import thunk from 'redux-thunk'; - -import allReducers from './reducers/all'; - - -const composeEnhancers = - typeof window === 'object' && - window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? - window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ - // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... - }) : compose; - -const middleware = [ - thunk, -]; - -if (process.env.NODE_ENV !== 'production') { - // Only add this redux store mutation detection middleware in dev - const freeze = require('redux-freeze'); - middleware.push(freeze); -} - -// Note passing middleware as the last argument to createStore requires redux@>=3.1.0 -const store = createStore( - allReducers, - composeEnhancers(applyMiddleware(...middleware)) -); - -if(process.env.NODE_ENV !== 'production') { - if(module.hot) { - module.hot.accept('./reducers/all', () => - store.replaceReducer(require('./reducers/all').default) - ); - } -} - -export default store; diff --git a/client/src/js/utils/array.js b/client/src/js/utils/array.js deleted file mode 100644 index fe8730797..000000000 --- a/client/src/js/utils/array.js +++ /dev/null @@ -1,35 +0,0 @@ -import _ from 'lodash'; - - -export function sort(arr, keys, dir, sortCompareFn) { - const flatKeys = Array.isArray(keys) ? _.flatten(keys) : [keys]; - - const comparators = flatKeys.map((key) => { - return (item) => { - const val = _.get(item, key); - return sortCompareFn ? sortCompareFn(val, item, key) : val; - }; - }); - const sortDirection = typeof dir === 'boolean' ? sortDir(dir) : dir; - return _.orderBy(arr, comparators, _.fill(Array(comparators.length), sortDirection || 'asc')); -} - -export function caseInsensitiveSort(val/* , item, key */) { - if (typeof val === 'string') { - return val.toLowerCase(); - } - return val; -} - -export function sortDir(isDescending) { - return isDescending ? 'desc' : 'asc'; -} - -export function findAndUpdate(arr, obj, key = 'id') { - const val = obj[key]; - const pos = _.findIndex(arr, (item) => item[key] === val); - if (pos !== -1) { - arr[pos] = { ...arr[pos], ...obj }; - } - return arr; -} diff --git a/client/src/js/utils/date.js b/client/src/js/utils/date.js deleted file mode 100644 index 5168a37f0..000000000 --- a/client/src/js/utils/date.js +++ /dev/null @@ -1,124 +0,0 @@ -import Moment from 'moment'; - -import * as Constant from '../constants'; - - -export function dateIsBetween(date, startDate, endDate) { - if (startDate && date.isBefore(startDate)) { return false; } - if (endDate && date.isAfter(endDate)) { return false; } - return true; -} - -export function formatDateTime(dateTime, format) { - if (!dateTime) { return ''; } - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return ''; } - if (!format) { format = Constant.DATE_TIME_ISO_8601; } - return dt.format(format); -} - -export function formatDateTimeUTCToLocal(dateTime, format) { - if (!dateTime) { return ''; } - var dt = Moment.utc(dateTime).local(); - if (!dt || !dt.isValid()) { return ''; } - if (!format) { format = Constant.DATE_TIME_ISO_8601; } - return dt.format(format); -} - -export function sortableDateTime(dateTime) { - if (!dateTime) { return 0; } - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return 0; } - return dt.unix(); -} - - -export function daysFromToday(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return 0; } - var today = Moment.utc().startOf('d'); - return dt.startOf('d').diff(today, 'd'); -} - -export function daysAgo(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return 0; } - var today = Moment().startOf('d'); - return today.diff(dt.startOf('d'), 'd'); -} - -export function hoursAgo(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return 0; } - var now = Moment(); - return now.diff(dt, 'h'); -} - -export function today(format) { - if (!format) { format = Constant.DATE_TIME_ISO_8601; } - var dt = Moment.utc().startOf('d'); - return dt.format(format); -} - -export function businessDayOnOrBefore(dateTime, format) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return ''; } - if (dt.day() === 6) { - // Saturday - dt.subtract(1, 'd'); - } else if (dt.day() === 0) { - // Sunday - dt.subtract(2, 'd'); - } - // TODO: Holidays - if (!format) { format = Constant.DATE_TIME_ISO_8601; } - return dt.format(format); -} - -export function isValidDate(dateTime) { - var dt = Moment.utc(dateTime); - return (dt && dt.isValid()); -} - -export function toZuluTime(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return ''; } - return dt.utc().format(Constant.DATE_ZULU); -} - -export function startOfCurrentFiscal(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return ''; } - // January-March - if (dt.quarter() == 1) { - dt.subtract(1, 'year'); - } - return dt.month('April').startOf('month'); -} - -export function endOfCurrentFiscal(dateTime) { - var dt = Moment.utc(dateTime); - if (!dt || !dt.isValid()) { return ''; } - // April-December - if (dt.quarter() > 1) { - dt.add(1, 'year'); - } - return dt.month('March').endOf('month'); -} - -export function startOfPreviousFiscal(dateTime) { - var fiscalStart = Moment.utc(startOfCurrentFiscal(dateTime)); - if (!fiscalStart || !fiscalStart.isValid()) { return ''; } - return fiscalStart.subtract(1, 'year').month('April').startOf('month'); -} - -export function endOfPreviousFiscal(dateTime) { - var fiscalEnd = Moment.utc(endOfCurrentFiscal(dateTime)); - if (!fiscalEnd || !fiscalEnd.isValid()) { return ''; } - return fiscalEnd.subtract(1, 'year').month('March').endOf('month'); -} - -export function isValidYear(year) { - let currentYear = new Date().getFullYear(); - return (year.length === 4 && year.match(/\d{4}/) && parseInt(year, 10) <= currentYear + 1 && parseInt(year, 10) >= 1900 ); -} diff --git a/client/src/js/utils/http.js b/client/src/js/utils/http.js deleted file mode 100644 index f820c5b10..000000000 --- a/client/src/js/utils/http.js +++ /dev/null @@ -1,241 +0,0 @@ -import _ from 'lodash'; -import Promise from 'bluebird'; - -import * as Action from '../actionTypes'; -import store from '../store'; - -import * as Constant from '../constants'; - -import { resetSessionTimeoutTimer } from '../App.jsx'; - -const ROOT_API_PREFIX = location.pathname === '/' ? '' : location.pathname.split('/').slice(0, -1).join('/'); - -var numRequestsInFlight = 0; - -function incrementRequests() { - numRequestsInFlight += 1; - if (numRequestsInFlight === 1) { - store.dispatch({ type: Action.REQUESTS_BEGIN }); - } -} - -function decrementRequests() { - numRequestsInFlight -= 1; - if (numRequestsInFlight <= 0) { - numRequestsInFlight = 0; // sanity check; - store.dispatch({ type: Action.REQUESTS_END }); - } -} - -export const HttpError = function(msg, method, path, status, body) { - this.message = msg || ''; - this.method = method; - this.path = path; - this.status = status || null; - this.body = body; -}; - -HttpError.prototype = Object.create(Error.prototype, { - constructor: { value: HttpError }, -}); - -export const ApiError = function(msg, method, path, status, errorCode, errorDescription, json) { - this.message = msg || ''; - this.method = method; - this.path = path; - this.status = status || null; - this.errorCode = errorCode || null; - this.errorDescription = errorDescription || null; - this.json = json || null; -}; - -ApiError.prototype = Object.create(Error.prototype, { - constructor: { value: ApiError }, -}); - -export const Resource404 = function(name, id) { - this.name = name; - this.id = id; -}; - -Resource404.prototype = Object.create(Error.prototype, { - constructor: { value: Resource404 }, - toString: { value() { - return `Resouce ${this.name} #${this.id} Not Found`; - }}, -}); - -export function request(path, options) { - options = options || {}; - - var xhr = new XMLHttpRequest(); - - // calling server service - // console.log('Calling service. Path: ' + path); - - if (!options.headers) { options.headers = {}; } - - if (!options.files) { - options.headers = Object.assign({ - 'Content-Type': 'application/x-www-form-urlencoded', - }, options.headers); - } - - var method = (options.method || 'GET').toUpperCase(); - - if (options.onUploadProgress) { - xhr.upload.addEventListener('progress', function(e) { - if (e.lengthComputable) { - options.onUploadProgress(e.loaded / e.total * 100); - } else { - options.onUploadProgress(null); - } - }); - - xhr.upload.addEventListener('load', function(/*e*/) { - options.onUploadProgress(100); - }); - } - - if (options.responseType && window.navigator.appName !== 'Netscape') { - xhr.responseType = options.responseType; - } else if (options.responseType && window.navigator.appName === 'Netscape') { - xhr.open(options.method, path); - xhr.responseType = options.responseType; - } - - return new Promise((resolve, reject, onCancel) => { - onCancel(function() { - if (!options.silent) { decrementRequests(); } - xhr.abort(); - }); - - xhr.addEventListener('load', function() { - if (xhr.status >= 400) { - var responseText = ''; - try { - responseText = xhr.responseText; - } catch(e) { /* swallow */} - - var err = new HttpError(`API ${method} ${path} failed (${xhr.status}) "${responseText}"`, method, path, xhr.status, responseText); - reject(err); - } else { - // console.log('Call complete! Path: ' + path); - resolve(xhr); - } - }); - - xhr.addEventListener('error', function() { - reject(new HttpError(`Request ${method} ${path} failed to send`, method, path)); - }); - - var qs = _.map(options.querystring, (value, key) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&'); - xhr.open(method, `${path}${qs ? '?' : ''}${qs}`, true); - - Object.keys(options.headers).forEach(key => { - xhr.setRequestHeader(key, options.headers[key]); - }); - - if (!options.silent) { - incrementRequests(); - } - - var payload = options.body || null; - - if (options.files) { - payload = new FormData(); - if (typeof options.body === 'object') { - Object.keys(options.body).forEach(key => { - payload.append(key, options.body[key]); - }); - } - options.files.forEach(file => { - payload.append('files', file, file.name); - }); - } - - xhr.send(payload); - }).finally(() => { - if (!options.silent) { decrementRequests(); } - }); -} - -export function jsonRequest(path, options) { - if (!options.keepAlive) { - resetSessionTimeoutTimer(); - } - - var jsonHeaders = { - 'Accept': 'application/json', - }; - - if (options.body) { - options.body = JSON.stringify(options.body); - jsonHeaders['Content-Type'] = 'application/json'; - } - - options.headers = Object.assign(options.headers || {}, jsonHeaders); - - return request(path, options).then((xhr) => { - if (xhr.status === 204) { - return; - } else if (xhr.responseType === Constant.RESPONSE_TYPE_BLOB) { - return xhr.response; - } else if (options.ignoreResponse) { - return null; - } else { - return xhr.responseText ? JSON.parse(xhr.responseText) : null; - } - }).catch((err) => { - if (err instanceof HttpError) { - var errMsg = `API ${err.method} ${err.path} failed (${err.status})`; - var json = null; - var errorCode = null; - var errorDescription = null; - try { - // Example error payload from server: - // { - // "responseStatus": "ERROR", - // "data": null, - // "error": { - // "error": "HETS-01", - // "description": "Record not found" - // } - // } - - json = JSON.parse(err.body); - errorCode = json.error.error; - errorDescription = json.error.description; - } catch(err) { /* not json */ } - - throw new ApiError(errMsg, err.method, err.path, err.status, errorCode, errorDescription, json); - } else { - throw err; - } - }); -} - -export function buildApiPath(path) { - return `${ROOT_API_PREFIX}/api/${path}`.replace('//', '/'); // remove double slashes -} - -export function ApiRequest(path, options) { - this.path = buildApiPath(path); - this.options = options; -} - -ApiRequest.prototype.get = function apiGet(params, options) { - return jsonRequest(this.path, { method: 'GET', querystring: params, ...this.options, ...options }); -}; - -ApiRequest.prototype.post = function apiPost(data, options) { - return jsonRequest(this.path, { method: 'POST', body: data, ...this.options, ...options }); -}; - -ApiRequest.prototype.put = function apiPut(data, options) { - return jsonRequest(this.path, { method: 'PUT', body: data, ...this.options, ...options }); -}; - -ApiRequest.prototype.delete = function apiDelete(data, options) { - return jsonRequest(this.path, { method: 'DELETE', body: data, ...this.options, ...options }); -}; diff --git a/client/src/js/utils/routes.js b/client/src/js/utils/routes.js deleted file mode 100644 index 1d7f480f1..000000000 --- a/client/src/js/utils/routes.js +++ /dev/null @@ -1,11 +0,0 @@ -import { hashHistory } from 'react-router'; - -export function currentPathStartsWith(path) { - if (path.charAt(0) !== '/') { - path = '/' + path; - } - - var currentPath = hashHistory.getCurrentLocation().pathname; - - return currentPath.indexOf(path) === 0; -} diff --git a/client/src/js/utils/string.js b/client/src/js/utils/string.js deleted file mode 100644 index 0afad67d5..000000000 --- a/client/src/js/utils/string.js +++ /dev/null @@ -1,83 +0,0 @@ -import * as Constant from '../constants'; - - -function toString(str) { - if (str === null || str === undefined) { return ''; } - return String(str); -} - -export function dasherize(str) { - return toString(str).trim().replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); -} - -export function titleCase(str) { - return toString(str).replace(/\b\w/g, l => l.toUpperCase()); -} - -export function plural(num, singular, plural) { - return num == 1 ? singular : plural; -} - -export function concat(left, right, sep) { - if (!sep) { sep = ' '; } - var a = toString(left).trim(); - var b = toString(right).trim(); - if (a && b) { return `${a}${sep}${b}`; } - if (a) { return a; } - if (b) { return b; } - return ''; -} - -export function firstLastName(first, last) { - return concat(first, last); -} - -export function lastFirstName(last, first) { - return concat(last, first, ', '); -} - -export function isBlank(str) { - return toString(str).trim().length === 0; -} - -export function isBlankOrZero(str) { - return toString(str).trim() == 0; -} - -export function notBlank(str) { - return !isBlank(str); -} - -export function padLeft(str, padChar, len) { - if (!str || !padChar || !len) { return ''; } - if (str.length >= len) { return str; } - var pad = Array(len + 1).join(padChar); - return pad.substring(str.length) + str; -} - -export function formatPhoneNumber(str) { - var phoneNumber = toString(str); - var match = phoneNumber.match(Constant.NANP_REGEX); - if (match) { - match.shift(); - - var extension = match.pop(); - var number = match.filter(x => { return x; }).join('-'); - return extension ? number + 'x' + extension : number; - } - return phoneNumber; -} - -export function onlyLetters(str) { - var a = toString(str).trim(); - return /^[a-zA-Z]+$/.test(a); -} - -export function formatCurrency(number) { - if (number === null || number === undefined) { return ''; } - return new Intl.NumberFormat('en-CA', { style: 'currency', currency: 'CAD' }).format(number); -} - -export function formatHours(number) { - return (number || 0).toFixed(2); -} diff --git a/client/src/js/utils/string_test.js b/client/src/js/utils/string_test.js deleted file mode 100644 index d767adc10..000000000 --- a/client/src/js/utils/string_test.js +++ /dev/null @@ -1,25 +0,0 @@ -/*global describe, it */ -/*eslint-env node*/ - -// Import currently not working - update needed in pipeline - -var assert = require('assert'); -import { dasherize, plural } from './string'; - -describe('String Utils', function() { - 'use strict'; - - describe('#dasherize()', function () { - it('should dasherize', function () { - assert.equal(dasherize('fooBarBaz'), 'foo-bar-baz'); - }); - }); - - describe('#plural()', function () { - it('should pluralize', function () { - assert.equal(plural(0, 'cat', 'cats'), 'cats'); - assert.equal(plural(1, 'cat', 'cats'), 'cat'); - assert.equal(plural(2, 'cat', 'cats'), 'cats'); - }); - }); -}); diff --git a/client/src/js/views/404.jsx b/client/src/js/views/404.jsx deleted file mode 100644 index e95de9e6a..000000000 --- a/client/src/js/views/404.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -class Main extends React.Component { - static propTypes = { - location: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - path: props.location.pathname, - }; - } - - render() { - return
-

Not found :(

- -

Sorry, but the page you were trying to view ({this.state.path}) does not exist. You can try going to the home page.

-
; - } -} - -export default Main; diff --git a/client/src/js/views/AitReport.jsx b/client/src/js/views/AitReport.jsx deleted file mode 100644 index d82599745..000000000 --- a/client/src/js/views/AitReport.jsx +++ /dev/null @@ -1,419 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Form } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import DateControl from '../components/DateControl.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; - -import { formatDateTime, startOfCurrentFiscal, endOfCurrentFiscal, startOfPreviousFiscal, endOfPreviousFiscal, toZuluTime, dateIsBetween } from '../utils/date'; - -const THIS_FISCAL = 'This Fiscal'; -const LAST_FISCAL = 'Last Fiscal'; -const CUSTOM = 'Custom'; - - -class AitReport extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - agreementSummaryLite: PropTypes.object, - projects: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - equipment: PropTypes.object, - aitResponses: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - var today = Moment(); - - this.state = { - search: { - projectIds: props.search.projectIds || [], - districtEquipmentTypes: props.search.districtEquipmentTypes || [], - equipmentIds: props.search.equipmentIds || [], - rentalAgreementNumber: props.search.rentalAgreementNumber || '', - dateRange: props.search.dateRange || THIS_FISCAL, - startDate: props.search.startDate || startOfCurrentFiscal(today).format('YYYY-MM-DD'), - endDate: props.search.endDate || endOfCurrentFiscal(today).format('YYYY-MM-DD'), - }, - ui : { - sortField: props.ui.sortField || 'rentalAgreementNumber', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = { - rentalAgreementNumber: this.state.search.rentalAgreementNumber || '', - }; - - if (this.state.search.projectIds.length > 0) { - searchParams.projects = this.state.search.projectIds; - } - - if (this.state.search.districtEquipmentTypes.length > 0) { - searchParams.districtEquipmentTypes = this.state.search.districtEquipmentTypes; - } - - if (this.state.search.equipmentIds.length > 0) { - searchParams.equipment = this.state.search.equipmentIds; - } - - var startDate = Moment(this.state.search.startDate); - var endDate = Moment(this.state.search.endDate); - - if (startDate && startDate.isValid()) { - searchParams.startDate = toZuluTime(startDate.startOf('day')); - } - - if (endDate && endDate.isValid()) { - searchParams.endDate = toZuluTime(endDate.startOf('day')); - } - return searchParams; - }; - - componentDidMount() { - Api.getRentalAgreementSummaryLite(); - Api.getProjectsAgreementSummary(); - Api.getDistrictEquipmentTypesAgreementSummary(); - Api.getEquipmentAgreementSummary(); - - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchAitReport(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var today = Moment(); - - var defaultSearchParameters = { - projectIds: [], - districtEquipmentTypes: [], - equipmentIds: [], - rentalAgreementNumber: '', - dateRange: THIS_FISCAL, - startDate: startOfCurrentFiscal(today).format('YYYY-MM-DD'), - endDate: endOfCurrentFiscal(today).format('YYYY-MM-DD'), - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_AIT_SEARCH, aitResponses: this.state.search }); - store.dispatch({ type: Action.CLEAR_AIT_REPORT }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_AIT_SEARCH, aitResponses: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_AIT_REPORT_UI, aitResponses: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - print = () => { - window.print(); - }; - - renderResults = () => { - if (Object.keys(this.props.aitResponses.data).length === 0) { - return No results; - } - - var aitResponses = _.sortBy(this.props.aitResponses.data, response => { - var sortValue = response[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(aitResponses); - } - - return - { - _.map(aitResponses, (entry) => { - return - { entry.rentalAgreementNumber} - { entry.equipmentCode } - { entry.districtEquipmentName } - { entry.projectNumber ? entry.projectNumber : 'N/A' } - { formatDateTime(entry.datedOn, 'YYYY-MMM-DD') } - { formatDateTime(entry.startDate, 'YYYY-MMM-DD') } - ; - }) - } - ; - }; - - matchesDateFilter = (agreementIds) => { - const startDate = Moment(this.state.search.startDate); - const endDate = Moment(this.state.search.endDate); - - const matchingAgreementIds = _.chain(this.props.agreementSummaryLite.data) - .filter(a => dateIsBetween(Moment(a.datedOn), startDate, endDate)) - .map('id') - .value(); - - return _.intersection(matchingAgreementIds, agreementIds).length > 0; - }; - - matchesProjectFilter = (projectIds) => { - if (this.state.search.projectIds.length == 0) { - return true; - } - - return _.intersection(this.state.search.projectIds, projectIds).length > 0; - }; - - matchesDistrictEquipmentTypeFilter = (districtEquipmentTypeId) => { - if (this.state.search.districtEquipmentTypes.length == 0){ - return true; - } - - return _.includes(this.state.search.districtEquipmentTypes, districtEquipmentTypeId); - } - - updateDateRangeSearchState = (state) => { - var today = Moment(); - var startDate; - var endDate; - - switch (state.dateRange) { - case THIS_FISCAL: - // Fiscal Year: Apr 1 - March 31 - startDate = startOfCurrentFiscal(today); - endDate = endOfCurrentFiscal(today); - break; - case LAST_FISCAL: - // Fiscal Year: Apr 1 - March 31 - startDate = startOfPreviousFiscal(today); - endDate = endOfPreviousFiscal(today); - break; - case CUSTOM: - startDate = today; - endDate = today; - break; - default: - break; - } - - this.updateSearchState({ ...state, startDate: startDate.format('YYYY-MM-DD'), endDate: endDate.format('YYYY-MM-DD') }, this.filterSelectedProjects); - } - - updateDateSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedProjects); - }; - - updateProjectSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedEquipmentType); - }; - - updateEquipmentTypeSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedEquipment); - }; - - filterSelectedProjects = () => { - var acceptableProjects = _.map(this.getFilteredProjects(), 'id'); - var projectIds = _.intersection(this.state.search.projectIds, acceptableProjects); - this.updateSearchState({ projectIds: projectIds }, this.filterSelectedEquipmentType); - }; - - filterSelectedEquipmentType = () => { - var acceptableDistrictEquipmentTypes = _.map(this.getFilteredDistrictEquipmentType(), 'id'); - var districtEquipmentTypes = _.intersection(this.state.search.districtEquipmentTypes, acceptableDistrictEquipmentTypes); - this.updateSearchState({ districtEquipmentTypes: districtEquipmentTypes }, this.filterSelectedEquipment); - }; - - filterSelectedEquipment = () => { - var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), 'id'); - var equipmentIds = _.intersection(this.state.search.equipmentIds, acceptableEquipmentIds); - this.updateSearchState({ equipmentIds: equipmentIds }); - }; - - getFilteredProjects = () => { - return _.chain(this.props.projects.data) - .filter(x => this.matchesDateFilter(x.agreementIds)) - .sortBy('name') - .value(); - }; - - getFilteredDistrictEquipmentType = () => { - return _.chain(this.props.districtEquipmentTypes.data) - .filter(x => this.matchesDateFilter(x.agreementIds) && this.matchesProjectFilter(x.projectIds)) - .sortBy('name') - .value(); - }; - - getFilteredEquipment = () => { - return _.chain(this.props.equipment.data) - .filter(x => this.matchesDateFilter(x.agreementIds) && this.matchesProjectFilter(x.projectIds) && this.matchesDistrictEquipmentTypeFilter(x.districtEquipmentTypeId)) - .sortBy('equipmentCode') - .value(); - }; - - render() { - var resultCount = ''; - if (this.props.aitResponses.loaded) { - resultCount = '(' + Object.keys(this.props.aitResponses.data).length + ')'; - } - - var projects = this.getFilteredProjects(); - var districtEquipmentTypes = this.getFilteredDistrictEquipmentType(); - var equipment = this.getFilteredEquipment(); - - return
- Rental Agreement Summary { resultCount } - - - - - -
- - - - - - - - - - - - - - {(() => { - if (this.state.search.dateRange === CUSTOM) { - return - - - - - ; - } - })()} - - - - - - - -
-
- - {(() => { - if (this.props.aitResponses.loading) { - return
; - } - - if (this.props.aitResponses.loaded) { - return this.renderResults(); - } - })()} -
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - agreementSummaryLite: state.lookups.agreementSummaryLite, - projects: state.lookups.projectsAgreementSummary, - districtEquipmentTypes: state.lookups.districtEquipmentTypesAgreementSummary, - equipment: state.lookups.equipment.agreementSummary, - aitResponses: state.models.aitResponses, - favourites: state.models.favourites.aitReport, - search: state.search.aitResponses, - ui: state.ui.aitResponses, - }; -} - -export default connect(mapStateToProps)(AitReport); diff --git a/client/src/js/views/BusinessOwner.jsx b/client/src/js/views/BusinessOwner.jsx deleted file mode 100644 index 245a99b6f..000000000 --- a/client/src/js/views/BusinessOwner.jsx +++ /dev/null @@ -1,304 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Row, Col, Alert, Glyphicon, Label } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import Main from './Main.jsx'; -import Spinner from '../components/Spinner.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import SortTable from '../components/SortTable.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { formatDateTime } from '../utils/date'; -import { sortDir } from '../utils/array'; -import { activeOwnerSelector } from '../selectors/ui-selectors'; - - -class BusinessOwner extends React.Component { - static propTypes = { - owner: PropTypes.object, - uiEquipment: PropTypes.object, - uiContacts: PropTypes.object, - params: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - - success: false, - - contact: {}, - - status: '', - - // Contacts - uiContacts : { - sortField: props.uiContacts.sortField || 'name', - sortDesc: props.uiContacts.sortDesc === true, - }, - - // Equipment - uiEquipment : { - sortField: props.uiEquipment.sortField || 'equipmentNumber', - sortDesc: props.uiEquipment.sortDesc === true, - }, - }; - } - - componentDidMount() { - const ownerLoaded = Boolean(this.props.owner); - this.setState({ loading: !ownerLoaded, success: ownerLoaded }); - - this.fetch().then(() => { - this.setState({ loading: false }); - }); - } - - componentDidUpdate(prevProps) { - if (this.props.params.ownerId !== prevProps.params.ownerId) { - this.fetch(); - } - } - - fetch = () => { - var {ownerId} = this.props.params; - - return Api.getOwnerForBusiness(ownerId).then(() => { - this.setState({ success: true }); - }).catch(() => { - this.setState({ success: false }); - }); - }; - - updateContactsUIState = (state, callback) => { - this.setState({ uiContacts: { ...this.state.uiContacts, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_OWNER_CONTACTS_UI, ownerContacts: this.state.uiContacts }); - if (callback) { callback(); } - }); - }; - - updateEquipmentUIState = (state, callback) => { - this.setState({ uiEquipment: { ...this.state.uiEquipment, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_OWNER_EQUIPMENT_UI, ownerEquipment: this.state.uiEquipment }); - if (callback) { callback(); } - }); - }; - - render() { - return ( -
-
- { this.state.loading &&
} - { !this.state.loading && this.state.success && this.renderPage() } - { !this.state.loading && !this.state.success && this.renderError() } -
-
- ); - } - - renderPage = () => { - var owner = this.props.owner; - - return
-
- - - - - - -
- - -
- -
- - - - - -
- - - { owner.organizationName } - - - { owner.fullAddress } - - - { owner.ownerName } - - - { owner.ownerCode } - - - { owner.primaryContactName } - - - { owner.doingBusinessAs } - - - { owner.registeredCompanyNumber } - - - { owner.districtName } - - - { owner.localAreaName } - - - { owner.isMaintenanceContractor ? 'Yes' : 'No' } - - - { owner.meetsResidency ? 'Yes' : 'No' } - - -
-
- - - - - { owner.workSafeBCPolicyNumber } - - - - { formatDateTime(owner.workSafeBCExpiryDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - - - { owner.cglCompanyName } - - - - - { owner.cglPolicyNumber } - - - - - { formatDateTime(owner.cglEndDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - - - - - {(() => { - if (!owner.contacts || Object.keys(owner.contacts).length === 0) { return No contacts; } - - var contacts = _.orderBy(owner.contacts, [this.state.uiContacts.sortField], sortDir(this.state.uiContacts.sortDesc)); - - var headers = [ - { field: 'name', title: 'Name' }, - { field: 'phone', title: 'Phone' }, - { field: 'mobilePhoneNumber', title: 'Cell' }, - { field: 'faxPhoneNumber', title: 'Fax' }, - { field: 'emailAddress', title: 'Email' }, - { field: 'role', title: 'Role' }, - ]; - - return - { - _.map(contacts, (contact) => { - return - { contact.isPrimary && } { contact.name } - { contact.phone } - { contact.mobilePhoneNumber } - { contact.faxPhoneNumber } - { contact.emailAddress } - { contact.role } - ; - }) - } - ; - })()} - - - - {(() => { - if (!owner.equipmentList || owner.equipmentList.length === 0) { return No equipment; } - - var equipmentList = _.orderBy(owner.equipmentList, [this.state.uiEquipment.sortField], sortDir(this.state.uiEquipment.sortDesc)); - - var headers = [ - { field: 'equipmentNumber', title: 'ID' }, - { field: 'localArea.name', title: 'Local Area' }, - { field: 'typeName', title: 'Equipment Type' }, - { field: 'details', title: 'Make/Model/Size/Year' }, - { field: 'attachments', title: 'Attachments' }, - { field: 'lastVerifiedDate', title: 'Last Verified' }, - ]; - - return - { - _.map(equipmentList, (equipment) => { - return - { equipment.equipmentCode } - { equipment.localArea.name } - { equipment.typeName } - { equipment.details } - { _.map(equipment.equipmentAttachments, a => a.description).join(', ') } - { equipment.isApproved ? formatDateTime(equipment.lastVerifiedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) : 'Not Approved' } - ; - }) - } - ; - })()} - -
-
; - }; - - renderError = () => { - return
-
- {(() => { - return - - - -
- -
- -
; - })()} - - {(() => { - return
- - -

This record does not exist or you do not have permission to access it.

- -
-
; - })()} -
-
; - }; -} - -function mapStateToProps(state) { - return { - owner: activeOwnerSelector(state), - uiEquipment: state.ui.ownerEquipment, - uiContacts: state.ui.ownerContacts, - }; -} - -export default connect(mapStateToProps)(BusinessOwner); diff --git a/client/src/js/views/BusinessPortal.jsx b/client/src/js/views/BusinessPortal.jsx deleted file mode 100644 index d3a481655..000000000 --- a/client/src/js/views/BusinessPortal.jsx +++ /dev/null @@ -1,221 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Well, Row, Col, FormGroup, Alert, Button } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import Main from './Main.jsx'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import Spinner from '../components/Spinner.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import SortTable from '../components/SortTable.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import Form from '../components/Form.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; - - -class BusinessPortal extends React.Component { - static propTypes = { - user: PropTypes.object, - business: PropTypes.object, - uiOwners: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - validating: false, - success: false, - secretKey: '', - postalCode: '', - errors: {}, - - // owners - uiOwners : { - sortField: props.uiOwners.sortField || 'organizationName', - sortDesc: props.uiOwners.sortDesc === true, - }, - }; - } - - componentDidMount() { - const businessLoaded = Boolean(this.props.business); - this.setState({ loading: !businessLoaded, success: businessLoaded }); - - this.fetch().then(() => { - this.setState({ loading: false }); - }); - } - - fetch = () => { - return Api.getBusiness().then(() => { - this.setState({ success: !_.isEmpty(this.props.business) }); - }); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateOwnersUIState = (state, callback) => { - this.setState({ uiOwners: { ...this.state.uiOwners, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_OWNERS_UI, owners: this.state.uiOwners }); - if (callback) { callback(); } - }); - }; - - validateOwner = (e) => { - e.preventDefault(); - - this.setState({ validating: true, errors: {} }); - - Api.validateOwner(this.state.secretKey, this.state.postalCode).then(() => { - // clear input fields - this.inputPostalCode.value = ''; - this.inputSecretKey.value = ''; - }).catch((error) => { - if (error.status === 400 && (error.errorCode === 'HETS-19' || error.errorCode === 'HETS-20' || error.errorCode === 'HETS-21')) { - this.setState({ errors: { secretKey: error.errorDescription } }); - } else if (error.status === 400 && error.errorCode === 'HETS-22') { - this.setState({ errors: { postalCode: error.errorDescription } }); - } else { - throw error; - } - }).finally(() => { - this.setState({ validating: false }); - }); - }; - - render() { - return
-
- Business Portal - { this.state.loading &&
} - { !this.state.loading && this.state.success && this.renderPage() } - { !this.state.loading && !this.state.success && this.renderError() } -
-
; - } - - renderPage = () => { - var business = this.props.business; - const hasErrors = Object.keys(this.state.errors).length > 0; - - return
- - - - - { business.bceidLegalName } - - - { business.bceidDoingBusinessAs } - - - - - - {(() => { - if (_.isEmpty(this.props.business.owners)) { return No district owners associated; } - - var owners = _.sortBy(this.props.business.owners, this.state.uiOwners.sortField); - if (this.state.uiOwners.sortDesc) { - _.reverse(owners); - } - - var headers = [ - { field: 'organizationName', title: 'Name' }, - { field: 'primaryContactName', title: 'Primary Contact' }, - { field: 'districtName', title: 'District' }, - { field: 'localAreaName', title: 'Local Area' }, - ]; - - return - { - _.map(owners, (owner) => { - return - {owner.organizationName} - { owner.primaryContactNameBusiness } - { owner.districtNameBusiness } - { owner.localAreaNameBusiness } - ; - }) - } - ; - })()} - - - -
- - -

- The Hired Equipment Program is for owners/operators who have a dump truck, bulldozer, backhoe or other piece of equipment they want to hire out to the Ministry Transportation and Infrastructure for day labour and emergency projects. -

-

- The Hired Equipment Program distributes available work to local equipment owners. The program is based on seniority and is designed to deliver work to registered users fairly and efficiently through the development of local area call-out lists. Details about the Hired Equipment Program can be found here. -

-
-

- If you are NEW to the Hired Equipment Program, contact your local district office to register your company and equipment. -

-

- If you are REGISTERED with the Hired Equipment Program and this is your first time to the site, enter your Secret Key and Postal Code to validate your account, then select your account. -

-

- For RETURNING equipment owners, select your company above to view your account. -

-
-
- - this.inputSecretKey = input} /> - - - this.inputPostalCode = input} /> - - -
- { hasErrors &&
Secret key validation failed.
} -
-
; - }; - - renderError = () => { - return

An error was encountered. You may not have permission to access this page.

; - }; -} - -function mapStateToProps(state) { - return { - user: state.user, - business: state.models.business, - uiOwners: state.ui.owners, - }; -} - -export default connect(mapStateToProps)(BusinessPortal); diff --git a/client/src/js/views/DistrictAdmin.jsx b/client/src/js/views/DistrictAdmin.jsx deleted file mode 100644 index c61992d20..000000000 --- a/client/src/js/views/DistrictAdmin.jsx +++ /dev/null @@ -1,295 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Button, ButtonGroup, Glyphicon, Well, Alert, Row, Col } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../api'; -import * as Constant from '../constants'; -import * as Action from '../actionTypes'; -// import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import ModalDialog from '../components/ModalDialog.jsx'; -import SortTable from '../components/SortTable.jsx'; -import TableControl from '../components/TableControl.jsx'; -import Spinner from '../components/Spinner.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import Confirm from '../components/Confirm.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import ConditionAddEditDialog from './dialogs/ConditionAddEditDialog.jsx'; -import DistrictEquipmentTypeAddEditDialog from './dialogs/DistrictEquipmentTypeAddEditDialog.jsx'; -import EquipmentTransferDialog from './dialogs/EquipmentTransferDialog.jsx'; - -import { caseInsensitiveSort, sort } from '../utils/array'; - - - -class DistrictAdmin extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - rentalConditions: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - equipmentTypes: PropTypes.object, - router: PropTypes.object, - uiEquipment: PropTypes.object, - dispatch: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - showConditionAddEditDialog: false, - showDistrictEquipmentTypeAddEditDialog: false, - showEquipmentTransferDialog: false, - condition: {}, - districtEquipmentType: {}, - - // Equipment - uiEquipment : { - sortField: props.uiEquipment.sortField || 'districtEquipmentName', - sortDesc: props.uiEquipment.sortDesc === true, - }, - }; - } - - componentDidMount() { - Api.getRentalConditions(); - Api.getDistrictEquipmentTypes(); - } - - updateEquipmentUIState = (state, callback) => { - this.setState({ uiEquipment: { ...this.state.uiEquipment, ...state }}, () => { - this.props.dispatch({ type: Action.UPDATE_DISTRICT_EQUIPMENT_UI, districtEquipment: this.state.uiEquipment }); - if (callback) { callback(); } - }); - }; - - addCondition = () => { - this.setState({ condition: { id: 0 } }, this.showConditionAddEditDialog); - }; - - editCondition = (condition) => { - this.setState({ condition: condition }, this.showConditionAddEditDialog); - }; - - deleteCondition = (condition) => { - Api.deleteCondition(condition.id).then(() => { - Api.getRentalConditions(); - }); - }; - - showConditionAddEditDialog = () => { - this.setState({ showConditionAddEditDialog: true }); - }; - - closeConditionAddEditDialog = () => { - this.setState({ showConditionAddEditDialog: false }); - }; - - showEquipmentTransferDialog = () => { - this.setState({ showEquipmentTransferDialog: true }); - }; - - closeEquipmentTransferDialog = () => { - this.setState({ showEquipmentTransferDialog: false }); - }; - - conditionSaved = () => { - Api.getRentalConditions(); - }; - - showDistrictEquipmentTypeAddEditDialog = () => { - this.setState({ showDistrictEquipmentTypeAddEditDialog: true }); - }; - - closeDistrictEquipmentTypeAddEditDialog = () => { - this.setState({ showDistrictEquipmentTypeAddEditDialog: false }); - }; - - closeDistrictEquipmentTypeErrorDialog = () => { - this.setState({ showDistrictEquipmentTypeErrorDialog: false }); - }; - - addDistrictEquipmentType = () => { - this.setState({ districtEquipmentType: { id: 0 } }, this.showDistrictEquipmentTypeAddEditDialog); - }; - - editDistrictEquipmentType = (equipment) => { - this.setState({ districtEquipmentType: equipment }, this.showDistrictEquipmentTypeAddEditDialog); - }; - - districtEquipmentTypeSaved = () => { - Api.getDistrictEquipmentTypes(); - }; - - deleteDistrictEquipmentType = (equipment) => { - Api.deleteDistrictEquipmentType(equipment).then(() => { - return Api.getDistrictEquipmentTypes(); - }).catch((error) => { - if (error.status === 400 && error.errorCode === 'HETS-37') { - this.setState({ showDistrictEquipmentTypeErrorDialog: true, districtEquipmentTypeError: error.errorDescription }); - } else { - throw error; - } - }); - }; - - render() { - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_DISTRICT_CODE_TABLE_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - return
- District Admin - - - - {(() => { - if (!this.props.districtEquipmentTypes.loaded) { return
; } - - var addDistrictEquipmentButton = ; - - var equipmentTypes = this.props.districtEquipmentTypes.data; - - if (Object.keys(equipmentTypes).length === 0) { return No equipment types { addDistrictEquipmentButton }; } - - var sortedEquipmentTypes = sort(equipmentTypes, this.state.uiEquipment.sortField, this.state.uiEquipment.sortDesc, caseInsensitiveSort); - - var headers = [ - { field: 'districtEquipmentName', title: 'Equipment Type/Description' }, - { field: 'equipmentType.blueBookSection', title: 'Blue Book Section Number' }, - { field: 'equipmentType.name', title: 'Blue Book Section Name' }, - { field: 'addDistrictEquipmentType', title: 'Add District Equipment Type', style: { textAlign: 'right' }, - node: addDistrictEquipmentButton, - }, - ]; - - return ( - - { - _.map(sortedEquipmentTypes, (equipment) => { - return - { equipment.districtEquipmentName } - { equipment.equipmentType.blueBookSection } - { equipment.equipmentType.name } - - - - }> - - - - - - - ; - }) - } - - ); - })()} -
- - - - {(() => { - if (this.props.rentalConditions.loading) { return
; } - - var addConditionButton = ; - - if (Object.keys(this.props.rentalConditions.data).length === 0) { return No users { addConditionButton }; } - - return ( - - { - _.map(this.props.rentalConditions.data, (condition) => { - return - { condition.conditionTypeCode } - { condition.description } - - - }> - - - - - - ; - }) - } - - ); - })()} -
- - - - - Bulk transfer will enable the user to transfer equipment associated with one owner code to another owner code. - - - - - { this.state.showEquipmentTransferDialog && - - } - { this.state.showConditionAddEditDialog && - - } - { this.state.showDistrictEquipmentTypeAddEditDialog && - - } - { this.state.showDistrictEquipmentTypeErrorDialog && - - - - } - > -
{ this.state.districtEquipmentTypeError }
-
- } -
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - rentalConditions: state.lookups.rentalConditions, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - equipmentTypes: state.lookups.equipmentTypes, - uiEquipment: state.ui.districtEquipment, - }; -} - -export default connect(mapStateToProps)(DistrictAdmin); diff --git a/client/src/js/views/Equipment.jsx b/client/src/js/views/Equipment.jsx deleted file mode 100644 index 8dbb78f2a..000000000 --- a/client/src/js/views/Equipment.jsx +++ /dev/null @@ -1,307 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, OverlayTrigger, Tooltip } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import CheckboxControl from '../components/CheckboxControl.jsx'; -import DateControl from '../components/DateControl.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import Spinner from '../components/Spinner.jsx'; -import Form from '../components/Form.jsx'; -import EquipmentTable from './EquipmentTable.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { toZuluTime } from '../utils/date'; - - -class Equipment extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - equipmentList: PropTypes.object, - localAreas: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - owners: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showAddDialog: false, - search: { - selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], - selectedEquipmentTypesIds: props.search.selectedEquipmentTypesIds || [], - equipmentAttachment: props.search.equipmentAttachment || '', - ownerName: props.search.ownerName || '', - lastVerifiedDate: props.search.lastVerifiedDate || '', - hired: props.search.hired || false, - twentyYears: props.search.twentyYears || false, - statusCode: props.search.statusCode || Constant.EQUIPMENT_STATUS_CODE_APPROVED, - equipmentId: props.search.equipmentId || '', - projectName: props.search.projectName || '', - }, - ui : { - sortField: props.ui.sortField || 'seniorityText', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.equipmentAttachment) { - searchParams.equipmentAttachment = this.state.search.equipmentAttachment; - } - - if (this.state.search.ownerName) { - searchParams.ownerName = this.state.search.ownerName; - } - - if (this.state.search.hired) { - searchParams.hired = this.state.search.hired; - } - - if (this.state.search.twentyYears) { - searchParams.twentyYears = this.state.search.twentyYears; - } - - if (this.state.search.statusCode) { - searchParams.status = this.state.search.statusCode; - } - - if (this.state.search.selectedLocalAreasIds.length > 0) { - searchParams.localareas = this.state.search.selectedLocalAreasIds; - } - - if (this.state.search.selectedEquipmentTypesIds.length > 0) { - searchParams.types = this.state.search.selectedEquipmentTypesIds; - } - - if (this.state.search.equipmentId) { - searchParams.equipmentId = this.state.search.equipmentId; - } - - if (this.state.search.projectName) { - searchParams.projectName = this.state.search.projectName; - } - - var notVerifiedSinceDate = Moment(this.state.search.lastVerifiedDate); - if (notVerifiedSinceDate && notVerifiedSinceDate.isValid()) { - searchParams.notverifiedsincedate = toZuluTime(notVerifiedSinceDate.startOf('day')); - } - - return searchParams; - }; - - componentDidMount() { - Api.getDistrictEquipmentTypes(); - - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchEquipmentList(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - selectedLocalAreasIds:[], - selectedEquipmentTypesIds: [], - equipmentAttachment: '', - ownerName: '', - lastVerifiedDate: '', - hired: false, - twentyYears: false, - statusCode: Constant.EQUIPMENT_STATUS_CODE_APPROVED, - equipmentId: '', - projectName: '', - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: this.state.search }); - store.dispatch({ type: Action.CLEAR_EQUIPMENT_LIST }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_UI, equipmentList: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - renderResults = () => { - if (Object.keys(this.props.equipmentList.data).length === 0) { - return No equipment; - } - - return ( - - ); - }; - - render() { - // Constrain the local area drop downs to those in the District of the current logged in user - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) - .filter(type => type.district.id == this.props.currentUser.district.id) - .sortBy('districtEquipmentName') - .value(); - - var resultCount = ''; - if (this.props.equipmentList.loaded) { - resultCount = '(' + Object.keys(this.props.equipmentList.data).length + ')'; - } - - return
- Equipment { resultCount } - - - - - -
- - - - - - - - - Hired - Equipment 20 years or older }> - 20+ Years - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - {(() => { - - if (this.props.equipmentList.loading) { - return
; - } - - if (this.props.equipmentList.loaded) { - return this.renderResults(); - } - - })()} - -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - equipmentList: state.models.equipmentList, - localAreas: state.lookups.localAreas, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - favourites: state.models.favourites.equipment, - search: state.search.equipmentList, - ui: state.ui.equipmentList, - }; -} - -export default connect(mapStateToProps)(Equipment); diff --git a/client/src/js/views/EquipmentDetail.jsx b/client/src/js/views/EquipmentDetail.jsx deleted file mode 100644 index d0c1186c3..000000000 --- a/client/src/js/views/EquipmentDetail.jsx +++ /dev/null @@ -1,543 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Well, Row, Col } from 'react-bootstrap'; -import { Alert, Button, ButtonGroup, Glyphicon, Label } from 'react-bootstrap'; -import _ from 'lodash'; -import Promise from 'bluebird'; - -import EquipmentEditDialog from './dialogs/EquipmentEditDialog.jsx'; -import SeniorityEditDialog from './dialogs/SeniorityEditDialog.jsx'; -import AttachmentAddDialog from './dialogs/AttachmentAddDialog.jsx'; -import AttachmentEditDialog from './dialogs/AttachmentEditDialog.jsx'; -import DocumentsListDialog from './dialogs/DocumentsListDialog.jsx'; -import NotesDialog from './dialogs/NotesDialog.jsx'; -import EquipmentChangeStatusDialog from './dialogs/EquipmentChangeStatusDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import * as Log from '../history'; -import store from '../store'; - -import BadgeLabel from '../components/BadgeLabel.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import Confirm from '../components/Confirm.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import History from '../components/History.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import StatusDropdown from '../components/StatusDropdown.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { activeEquipmentSelector, activeEquipmentIdSelector } from '../selectors/ui-selectors'; - -import { formatDateTime } from '../utils/date'; -import { formatHours } from '../utils/string'; - -/* - -TODO: -* Print / Notes / Docs / History / Actions on Equipment / Seniority Data History / Equipment Attachments - -*/ - -const EQUIPMENT_IN_ACTIVE_RENTAL_REQUEST_WARNING_MESSAGE = 'This equipment is part of an In Progress ' + - 'Rental Request. Release the list (finish hiring / delete) before making this change'; - - -class EquipmentDetail extends React.Component { - static propTypes = { - equipment: PropTypes.object, - equipmentId: PropTypes.number, - notes: PropTypes.array, - attachments: PropTypes.object, - documents: PropTypes.object, - history: PropTypes.object, - params: PropTypes.object, - ui: PropTypes.object, - location: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - loadingDocuments: true, - loadingNotes: true, - reloading: false, - - showEditDialog: false, - showDocumentsDialog: false, - showSeniorityDialog: false, - showPhysicalAttachmentDialog: false, - showPhysicalAttachmentEditDialog: false, - showNotesDialog: false, - showChangeStatusDialog: false, - equipmentPhysicalAttachment: {}, - ui : { - // Physical Attachments - sortField: props.ui.sortField || 'attachmentTypeName', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - componentDidMount() { - const { equipment, equipmentId } = this.props; - // Only show loading spinner if there is no existing equipment in the store - if (equipment) { - this.setState({ loading: false }); - } - - // Notes and documents need be fetched every time as they are not equipment-specific in the store ATM - Api.getEquipmentNotes(equipmentId).then(() => this.setState({ loadingNotes: false })); - Api.getEquipmentDocuments(equipmentId).then(() => this.setState({ loadingDocuments: false })); - - // Re-fetch equipment every time - Promise.all([ - this.fetch(), - ]).then(() => { - this.setState({ loading: false }); - }); - } - - componentDidUpdate(prevProps) { - if (prevProps.params.equipmentId !== this.props.params.equipmentId) { - this.fetch(); - } - } - - fetch = () => { - this.setState({ reloading: true }); - return Api.getEquipment(this.props.equipmentId).then(() => this.setState({ reloading: false })); - }; - - showNotes = () => { - this.setState({ showNotesDialog: true }); - }; - - closeNotesDialog = () => { - this.setState({ showNotesDialog: false }); - }; - - showDocuments = () => { - this.setState({ showDocumentsDialog: true }); - }; - - closeDocumentsDialog = () => { - this.setState({ showDocumentsDialog: false }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state } }, () => { - store.dispatch({ type: Action.UPDATE_PHYSICAL_ATTACHMENTS_UI, equipmentPhysicalAttachments: this.state.ui }); - if (callback) { callback(); } - }); - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - updateStatusState = (state) => { - if (state !== this.props.equipment.status) { - this.setState({ status: state }, () => this.openChangeStatusDialog()); - } - }; - - openChangeStatusDialog = () => { - this.setState({ showChangeStatusDialog: true }); - }; - - closeChangeStatusDialog = () => { - this.setState({ showChangeStatusDialog: false }); - }; - - onStatusChanged = () => { - this.closeChangeStatusDialog(); - Api.getEquipmentNotes(this.props.equipment.id); - }; - - openSeniorityDialog = () => { - this.setState({ showSeniorityDialog: true }); - }; - - closeSeniorityDialog = () => { - this.setState({ showSeniorityDialog: false }); - }; - - openPhysicalAttachmentDialog = () => { - this.setState({ - showPhysicalAttachmentDialog: true, - }); - }; - - closePhysicalAttachmentDialog = () => { - this.setState({ showPhysicalAttachmentDialog: false }); - }; - - physicalAttachmentsAdded = () => { - var equipId = this.props.params.equipmentId; - Api.getEquipment(equipId); - }; - - openPhysicalAttachmentEditDialog = (attachment) => { - this.setState({ - equipmentPhysicalAttachment: attachment, - showPhysicalAttachmentEditDialog: true, - }); - }; - - closePhysicalAttachmentEditDialog = () => { - this.setState({ showPhysicalAttachmentEditDialog: false }); - }; - - physicalAttachmentEdited = () => { - var equipId = this.props.params.equipmentId; - Api.getEquipment(equipId); - }; - - deletePhysicalAttachment = (attachmentId) => { - Api.deletePhysicalAttachment(attachmentId).then(() => { - let attachment = _.find(this.props.equipment.equipmentAttachments, ((attachment) => attachment.id === attachmentId )); - Log.equipmentAttachmentDeleted(this.props.equipment, attachment.typeName); - var equipId = this.props.params.equipmentId; - Api.getEquipment(equipId); - }); - }; - - getLastVerifiedStyle = (equipment) => { - var daysSinceVerified = equipment.daysSinceVerified; - if (daysSinceVerified >= Constant.EQUIPMENT_DAYS_SINCE_VERIFIED_CRITICAL) { return 'danger'; } - if (daysSinceVerified >= Constant.EQUIPMENT_DAYS_SINCE_VERIFIED_WARNING) { return 'warning'; } - return 'success'; - }; - - getStatuses = () => { - var dropdownItems = _.pull([ - Constant.EQUIPMENT_STATUS_CODE_APPROVED, - Constant.EQUIPMENT_STATUS_CODE_PENDING, - Constant.EQUIPMENT_STATUS_CODE_ARCHIVED, - ], this.props.equipment.status); - if (this.props.equipment.ownerStatus === Constant.OWNER_STATUS_CODE_PENDING) { - return _.pull(dropdownItems, Constant.EQUIPMENT_STATUS_CODE_APPROVED); - } else if (this.props.equipment.ownerStatus === Constant.OWNER_STATUS_CODE_ARCHIVED) { - return []; - } - return dropdownItems; - }; - - render() { - var equipment = this.props.equipment || {}; - const { loadingNotes, loadingDocuments } = this.state; - - var lastVerifiedStyle = this.getLastVerifiedStyle(equipment); - - return ( -
-
- {(() => { - if (this.state.loading) { return
; } - - return ( -
- - - - { this.props.equipment && - - } - - - - - -
- - -
- -
- - - - - -
- - { equipment.organizationName }}/> -
- District Office: { equipment.districtName } -
-
- Service/Local Area: { equipment.localArea && `${ equipment.localArea.serviceAreaId } - ${ equipment.localAreaName }` } -
-
-
- ); - })()} - - - - - - {(() => { - if (this.state.loading) { return
; } - - return - - { equipment.typeName } - - - { equipment.make } - - - { equipment.model } - - - { equipment.year } - - - { equipment.size } - - { equipment.isDumpTruck && - - { equipment.licencedGvw } - - } - { equipment.isDumpTruck && - - { equipment.legalCapacity } - - } - - { equipment.type } - - - { equipment.licencePlate } - - - - { equipment.serialNumber } - { equipment.hasDuplicates ? ! : null } - - - { equipment.isDumpTruck && - - { equipment.pupLegalCapacity } - - } - ; - })()} -
- - - - - {(() => { - if (this.state.loading ) { return
; } - if (!equipment.equipmentAttachments || Object.keys(equipment.equipmentAttachments).length === 0) { return No Attachments; } - - var physicalAttachments = _.sortBy(equipment.equipmentAttachments, this.state.ui.sortField); - if (this.state.ui.sortDesc) { - _.reverse(physicalAttachments); - } - - - var headers = [ - { field: 'attachmentTypeName', title: 'Type' }, - { field: 'blank' }, - ]; - - return - { - _.map(physicalAttachments, (attachment) => { - return - { attachment.typeName } - - - - - } - > - - - - - - ; - }) - } - ; - })()} -
- -
- - - - - {(() => { - if (this.state.loading) { return
; } - - return - - { equipment.seniorityString } - - - { formatHours(equipment.hoursYtd) } - - - Hours { equipment.yearMinus1 } }>{ formatHours(equipment.serviceHoursLastYear) } - - - Hours { equipment.yearMinus2 } }>{ formatHours(equipment.serviceHoursTwoYearsAgo) } - - - Hours { equipment.yearMinus3 } }>{ formatHours(equipment.serviceHoursThreeYearsAgo) } - - - { equipment.yearsOfService } - - - - { formatDateTime(equipment.receivedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - - - { formatDateTime(equipment.approvedDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - - - { equipment.isSeniorityOverridden ? 'Manually Updated' : 'Not Overriden'} - - - - { equipment.seniorityOverrideReason } - - ; - })()} -
- - - - - { equipment.historyEntity && } - - -
-
- { this.state.showChangeStatusDialog && ( - - )} - { this.state.showNotesDialog && ( - - )} - { this.state.showDocumentsDialog && ( - - )} - { this.state.showEditDialog && ( - - )} - { this.state.showSeniorityDialog && ( - - )} - { this.state.showPhysicalAttachmentDialog && ( - - )} - { this.state.showPhysicalAttachmentEditDialog && ( - - )} -
- ); - } -} - - -function mapStateToProps(state) { - return { - equipment: activeEquipmentSelector(state), - equipmentId: activeEquipmentIdSelector(state), - notes: state.models.equipmentNotes, - attachments: state.models.equipmentAttachments, - documents: state.models.documents, - history: state.models.equipmentHistory, - ui: state.ui.equipmentPhysicalAttachments, - }; -} - -export default connect(mapStateToProps)(EquipmentDetail); diff --git a/client/src/js/views/EquipmentTable.jsx b/client/src/js/views/EquipmentTable.jsx deleted file mode 100644 index 40e58fd1f..000000000 --- a/client/src/js/views/EquipmentTable.jsx +++ /dev/null @@ -1,82 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Link } from 'react-router'; -import _ from 'lodash'; -import { Button, Glyphicon } from 'react-bootstrap'; -import { LinkContainer } from 'react-router-bootstrap'; - -import * as Constant from '../constants'; - -import SortTable from '../components/SortTable.jsx'; - -import { formatDateTime } from '../utils/date'; - - -class EquipmentTable extends React.Component { - static propTypes = { - ui: PropTypes.object, - updateUIState: PropTypes.func, - equipmentList: PropTypes.object, - }; - - shouldComponentUpdate(nextProps) { - if (this.props.ui !== nextProps.ui || this.props.equipmentList !== nextProps.equipmentList) { - return true; - } - return false; - } - - render() { - var equipmentList = _.sortBy(this.props.equipmentList, equipment => { - var sortValue = equipment[this.props.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.props.ui.sortDesc) { - _.reverse(equipmentList); - } - - return ( - - { - _.map(equipmentList, (equip) => { - return ( - - { equip.equipmentCode } - { equip.localArea } - { equip.ownerName } - { equip.equipmentType } - { equip.details } - { equip.attachmentCount } - { equip.projectName } - { equip.status } - { formatDateTime(equip.lastVerifiedDate, 'YYYY-MMM-DD') } - - - - - - - ); - }) - } - - ); - } -} - -export default EquipmentTable; diff --git a/client/src/js/views/Footer.jsx b/client/src/js/views/Footer.jsx deleted file mode 100644 index b57eaac5c..000000000 --- a/client/src/js/views/Footer.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Row } from 'react-bootstrap'; - - -class Footer extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - }; - - render() { - return ; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - }; -} - -export default connect(mapStateToProps, null, null, { pure:false })(Footer); diff --git a/client/src/js/views/HiringReport.jsx b/client/src/js/views/HiringReport.jsx deleted file mode 100644 index f79a556e9..000000000 --- a/client/src/js/views/HiringReport.jsx +++ /dev/null @@ -1,339 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Form } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import Favourites from '../components/Favourites.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { formatDateTime } from '../utils/date'; - - -class HiringReport extends React.Component { - static propTypes = { - projects: PropTypes.object, - localAreas: PropTypes.object, - owners: PropTypes.object, - equipment: PropTypes.object, - hiringResponses: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - search: { - projectIds: props.search.projectIds || [], - localAreaIds: props.search.localAreaIds || [], - ownerIds: props.search.ownerIds || [], - equipmentIds: props.search.equipmentIds || [], - }, - ui : { - sortField: props.ui.sortField || 'name', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - componentDidMount() { - Api.getProjectsCurrentFiscal(); - Api.getEquipmentHires(); - Api.getOwnersLiteHires(); - - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.projectIds.length > 0) { - searchParams.projects = this.state.search.projectIds; - } - - if (this.state.search.localAreaIds.length > 0) { - searchParams.localAreas = this.state.search.localAreaIds; - } - - if (this.state.search.ownerIds.length > 0) { - searchParams.owners = this.state.search.ownerIds; - } - - if (this.state.search.equipmentIds.length > 0) { - searchParams.equipment = this.state.search.equipmentIds; - } - - return searchParams; - }; - - fetch = () => { - Api.searchHiringReport(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - projectIds: [], - localAreaIds: [], - ownerIds: [], - equipmentIds: [], - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_HIRING_RESPONSES_SEARCH, hiringResponses: this.state.search }); - store.dispatch({ type: Action.CLEAR_HIRING_RESPONSES }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_HIRING_RESPONSES_SEARCH, hiringResponses: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_HIRING_RESPONSES_UI, hiringResponses: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - renderResults = () => { - if (Object.keys(this.props.hiringResponses.data).length === 0) { - return No results; - } - - var hiringResponses = _.sortBy(this.props.hiringResponses.data, response => { - var sortValue = response[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(hiringResponses); - } - - return - { - _.map(hiringResponses, (entry) => { - var reason = entry.reason == Constant.HIRING_REFUSAL_OTHER ? entry.offerResponseNote : entry.reason; - - return - { entry.localAreaLabel } - { entry.ownerCode } - { entry.companyName } - { entry.equipmentCode } - { entry.equipmentDetails } - { entry.projectNumber ? entry.projectNumber : 'N/A' } - { formatDateTime(entry.noteDate, 'YYYY-MMM-DD') } - { entry.noteType } - { reason } - { entry.userName } ({ entry.userId }) - ; - }) - } - ; - }; - - matchesProjectFilter = (projectIds) => { - if (this.state.search.projectIds.length == 0) { - return true; - } - - return _.intersection(this.state.search.projectIds, projectIds).length > 0; - }; - - matchesLocalAreaFilter = (localAreaId) => { - if (this.state.search.localAreaIds.length == 0) { - return true; - } - - return _.includes(this.state.search.localAreaIds, localAreaId); - }; - - matchesOwnerFilter = (ownerId) => { - if (this.state.search.ownerIds.length == 0) { - return true; - } - - return _.includes(this.state.search.ownerIds, ownerId); - }; - - updateProjectSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedOwners); - }; - - updateLocalAreaSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedOwners); - }; - - updateOwnerSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedEquipment); - }; - - filterSelectedOwners = () => { - var acceptableOwnerIds = _.map(this.getFilteredOwners(), 'id'); - var ownerIds = _.intersection(this.state.search.ownerIds, acceptableOwnerIds); - this.updateSearchState({ ownerIds: ownerIds }, this.filterSelectedEquipment); - }; - - filterSelectedEquipment = () => { - var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), 'id'); - var equipmentIds = _.intersection(this.state.search.equipmentIds, acceptableEquipmentIds); - this.updateSearchState({ equipmentIds: equipmentIds }); - }; - - getFilteredOwners = () => { - return _.chain(this.props.owners.data) - .filter(x => this.matchesProjectFilter(x.projectIds) && this.matchesLocalAreaFilter(x.localAreaId)) - .sortBy('organizationName') - .value(); - }; - - getFilteredEquipment = () => { - return _.chain(this.props.equipment.data) - .filter(x => this.matchesProjectFilter(x.projectIds) && this.matchesOwnerFilter(x.ownerId)) - .sortBy('equipmentCode') - .value(); - }; - - render() { - var resultCount = ''; - if (this.props.hiringResponses.loaded) { - resultCount = '(' + Object.keys(this.props.hiringResponses.data).length + ')'; - } - - var projects = _.sortBy(this.props.projects.data, 'name'); - var localAreas = _.sortBy(this.props.localAreas, 'name'); - var owners = this.getFilteredOwners(); - var equipment = this.getFilteredEquipment(); - - return
- Hiring Report - Not Hired / Force Hire { resultCount } - - - - - -
- - - - - - - - - - - - - - - - - -
-
- - {(() => { - if (this.props.hiringResponses.loading) { - return
; - } - - if (this.props.hiringResponses.loaded) { - return this.renderResults(); - } - })()} -
; - } -} - - -function mapStateToProps(state) { - return { - projects: state.lookups.projectsCurrentFiscal, - localAreas: state.lookups.localAreas, - owners: state.lookups.owners.hires, - equipment: state.lookups.equipment.hires, - hiringResponses: state.models.hiringResponses, - favourites: state.models.favourites.hiringReport, - search: state.search.hiringResponses, - ui: state.ui.hiringResponses, - }; -} - -export default connect(mapStateToProps)(HiringReport); diff --git a/client/src/js/views/Home.jsx b/client/src/js/views/Home.jsx deleted file mode 100644 index 951838ae4..000000000 --- a/client/src/js/views/Home.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Row, Col, Button } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; - - -class Home extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - searchSummaryCounts: PropTypes.object, - router: PropTypes.object, - }; - - componentDidMount() { - this.fetch(); - } - - fetch = () => { - Api.getSearchSummaryCounts(); - }; - - goToUnapprovedOwners = () => { - var unapprovedStatus = Constant.OWNER_STATUS_CODE_PENDING; - - // update search parameters - store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: { statusCode: unapprovedStatus } }); - - // perform search - Api.searchOwners({ status: unapprovedStatus }); - - // navigate to search page - this.props.router.push({ pathname: Constant.OWNERS_PATHNAME }); - }; - - goToUnapprovedEquipment = () => { - var unapprovedStatus = Constant.EQUIPMENT_STATUS_CODE_PENDING; - - // update search parameters - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: { statusCode: Constant.EQUIPMENT_STATUS_CODE_PENDING } }); - - // perform search - Api.searchEquipmentList({ status: unapprovedStatus }); - - // navigate to search page - this.props.router.push({ pathname: Constant.EQUIPMENT_PATHNAME }); - }; - - goToHiredEquipment = () => { - // update search parameters - store.dispatch({ type: Action.UPDATE_EQUIPMENT_LIST_SEARCH, equipmentList: { statusCode: Constant.EQUIPMENT_STATUS_CODE_APPROVED, hired: true } }); - - // perform search - Api.searchEquipmentList({ status: Constant.EQUIPMENT_STATUS_CODE_APPROVED, hired: true }); - - // navigate to search page - this.props.router.push({ pathname: Constant.EQUIPMENT_PATHNAME }); - }; - - goToBlockedRotationLists = () => { - // update search parameters - store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: { statusCode: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS } }); - - // perform search - Api.searchRentalRequests({ status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS }); - - // navigate to search page - this.props.router.push({ pathname: Constant.RENTAL_REQUESTS_PATHNAME }); - }; - - render() { - var counts = this.props.searchSummaryCounts; - - return
- {this.props.currentUser.fullName}
{this.props.currentUser.districtName} District
- - - - - - - - - - - -
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - searchSummaryCounts: state.lookups.searchSummaryCounts, - }; -} - -export default connect(mapStateToProps)(Home); diff --git a/client/src/js/views/Main.jsx b/client/src/js/views/Main.jsx deleted file mode 100644 index 1d5144f4f..000000000 --- a/client/src/js/views/Main.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import {connect} from 'react-redux'; -import * as Api from '../api'; -import { unhandledApiError, closeSessionTimeoutDialog } from '../actions'; - -import TopNav from './TopNav.jsx'; -import Footer from './Footer.jsx'; -import ConfirmDialog from './dialogs/ConfirmDialog.jsx'; -import ErrorDialog from './dialogs/ErrorDialog.jsx'; -import Countdown from '../components/Countdown.jsx'; - -import { resetSessionTimeoutTimer } from '../App.jsx'; -import { ApiError } from '../utils/http'; -import { bindActionCreators } from 'redux'; - - -class Main extends React.Component { - static propTypes = { - children: PropTypes.object, - showNav: PropTypes.bool, - showSessionTimeoutDialog: PropTypes.bool, - showErrorDialog: PropTypes.bool, - - unhandledApiError: PropTypes.func, - closeSessionTimeoutDialog: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - headerHeight: 0, - }; - } - - componentDidMount() { - const height = document.getElementById('header-main').clientHeight; - this.setState({ headerHeight: height + 10 }); - - window.addEventListener('unhandledrejection', this.unhandledRejection); - } - - unhandledRejection = (e) => { - var err = e.detail.reason; - - if (err instanceof ApiError) { - this.props.unhandledApiError(err); - } - }; - - onCloseSessionTimeoutDialog = () => { - Api.keepAlive(); - resetSessionTimeoutTimer(); - this.props.closeSessionTimeoutDialog(); - }; - - onEndSession = () => { - Api.logoffUser().then(logoffUrl => { - if (logoffUrl) { - window.location.href = logoffUrl; - } - }); - this.props.closeSessionTimeoutDialog(); - }; - - componentWillUnmount() { - window.removeEventListener('unhandledrejection', this.unhandledRejection); - } - - render() { - return ( -
- -
- {this.props.children} -
-
- - Your session will time out in . Would you - like to keep the session active or end the session? - - -
- ); - } -} - -function mapStateToProps(state) { - return { - showSessionTimeoutDialog: state.ui.showSessionTimeoutDialog, - showErrorDialog: state.ui.showErrorDialog, - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators({ unhandledApiError, closeSessionTimeoutDialog }, dispatch); -} - -export default connect(mapStateToProps, mapDispatchToProps)(Main); diff --git a/client/src/js/views/OvertimeRates.jsx b/client/src/js/views/OvertimeRates.jsx deleted file mode 100644 index 07c9465cc..000000000 --- a/client/src/js/views/OvertimeRates.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Button, ButtonGroup, Glyphicon, Well } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import TableControl from '../components/TableControl.jsx'; -import Spinner from '../components/Spinner.jsx'; -import OvertimeRateEditDialog from './dialogs/OvertimeRateEditDialog.jsx'; - - -class OvertimeRates extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - overtimeRateTypes: PropTypes.array, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showOvertimeRateEditDialog: false, - overtimeRateType: {}, - }; - } - - componentDidMount() { - this.fetch(); - } - - fetch = () => { - Api.getOvertimeRateTypes(); - }; - - editRate = (overtimeRateType) => { - this.setState({ overtimeRateType: overtimeRateType }, this.showOvertimeRateEditDialog); - }; - - showOvertimeRateEditDialog = () => { - this.setState({ showOvertimeRateEditDialog: true }); - }; - - closeOvertimeRateEditDialog = () => { - this.setState({ showOvertimeRateEditDialog: false }); - }; - - overtimeRateSaved = () => { - this.fetch(); - }; - - render() { - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - return
- Manage Rental Agreement Overtime Rates - - - {(() => { - if (this.props.overtimeRateTypes.length == 0) { return
; } - - return ( - - { - _.map(this.props.overtimeRateTypes, (overtimeRateType) => { - return - { overtimeRateType.rateType } - { overtimeRateType.description } - { `$${ overtimeRateType.rate.toFixed(2) }/Hr` } - - - - - - ; - }) - } - - ); - })()} -
- - { this.state.showOvertimeRateEditDialog && - - } -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - overtimeRateTypes: state.lookups.overtimeRateTypes, - }; -} - -export default connect(mapStateToProps)(OvertimeRates); diff --git a/client/src/js/views/Owners.jsx b/client/src/js/views/Owners.jsx deleted file mode 100644 index 9464eb039..000000000 --- a/client/src/js/views/Owners.jsx +++ /dev/null @@ -1,260 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; -import OwnersAddDialog from './dialogs/OwnersAddDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; -import EditButton from '../components/EditButton.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import Form from '../components/Form.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { sort, caseInsensitiveSort } from '../utils/array.js'; - - -class Owners extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - ownerList: PropTypes.object, - localAreas: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showAddDialog: false, - - search: { - selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], - ownerCode: props.search.ownerCode || '', - ownerName: props.search.ownerName || '', - statusCode: props.search.statusCode || Constant.OWNER_STATUS_CODE_APPROVED, - }, - - ui : { - sortField: props.ui.sortField || 'organizationName', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.ownerCode) { - searchParams.ownerCode = this.state.search.ownerCode; - } - - if (this.state.search.ownerName) { - searchParams.ownerName = this.state.search.ownerName; - } - - if (this.state.search.statusCode) { - searchParams.status = this.state.search.statusCode; - } - - if (this.state.search.selectedLocalAreasIds.length > 0) { - searchParams.localareas = this.state.search.selectedLocalAreasIds; - } - - return searchParams; - }; - - componentDidMount() { - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchOwners(this.buildSearchParams()); - }; - - search = () => { - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - selectedLocalAreasIds: [], - ownerCode: '', - ownerName: '', - statusCode: Constant.OWNER_STATUS_CODE_APPROVED, - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: this.state.search }); - store.dispatch({ type: Action.CLEAR_OWNERS }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () => { - store.dispatch({ type: Action.UPDATE_OWNERS_SEARCH, owners: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_OWNERS_UI, owners: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - openAddDialog = () => { - this.setState({ showAddDialog: true }); - }; - - closeAddDialog = () => { - this.setState({ showAddDialog: false }); - }; - - ownerSaved = (owner) => { - this.fetch(); - this.props.router.push({ - pathname: `${ Constant.OWNERS_PATHNAME }/${ owner.id }`, - }); - }; - - renderResults = (ownerList, addOwnerButton) => { - if (Object.keys(this.props.ownerList.data).length === 0) { return No owners { addOwnerButton }; } - - return - { - _.map(ownerList, (owner) => { - return - { owner.ownerCode } - { owner.localAreaName } - { owner.organizationName } - { owner.primaryContactName } - { owner.workPhoneNumber } - { owner.mobilePhoneNumber } - { owner.equipmentCount } - { owner.status } - - - - - - ; - }) - } - ; - }; - - render() { - // Constrain the local area drop downs to those in the District of the current logged in user - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - var resultCount = ''; - if (this.props.ownerList.loaded) { - resultCount = '(' + Object.keys(this.props.ownerList.data).length + ')'; - } - - var ownerList = sort(this.props.ownerList.data, this.state.ui.sortField, this.state.ui.sortDesc, caseInsensitiveSort); - - return
- Owners { resultCount } - - - - - -
- - - - - - - - - - - - - - - - - -
-
- - {(() => { - if (this.props.ownerList.loading) { return
; } - - var addOwnerButton = ; - - if (this.props.ownerList.loaded) { - return this.renderResults(ownerList, addOwnerButton); - } - - return { addOwnerButton }; - })()} - { this.state.showAddDialog && - - } -
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - ownerList: state.models.owners, - localAreas: state.lookups.localAreas, - favourites: state.models.favourites.owner, - search: state.search.owners, - ui: state.ui.owners, - }; -} - -export default connect(mapStateToProps)(Owners); diff --git a/client/src/js/views/OwnersDetail.jsx b/client/src/js/views/OwnersDetail.jsx deleted file mode 100644 index 1ac321855..000000000 --- a/client/src/js/views/OwnersDetail.jsx +++ /dev/null @@ -1,988 +0,0 @@ -import PropTypes from "prop-types"; -import React from "react"; -import { connect } from "react-redux"; -import { - Well, - Row, - Col, - Alert, - Button, - ButtonGroup, - Glyphicon, - Label, -} from "react-bootstrap"; -import { Link } from "react-router"; -import _ from "lodash"; -import Promise from "bluebird"; - -import ContactsEditDialog from "./dialogs/ContactsEditDialog.jsx"; -import DocumentsListDialog from "./dialogs/DocumentsListDialog.jsx"; -import EquipmentAddDialog from "./dialogs/EquipmentAddDialog.jsx"; -import OwnersEditDialog from "./dialogs/OwnersEditDialog.jsx"; -import OwnersPolicyEditDialog from "./dialogs/OwnersPolicyEditDialog.jsx"; -import NotesDialog from "./dialogs/NotesDialog.jsx"; -import OwnerChangeStatusDialog from "./dialogs/OwnerChangeStatusDialog.jsx"; -import StatusDropdown from "../components/StatusDropdown.jsx"; - -import * as Action from "../actionTypes"; -import * as Api from "../api"; -import * as Constant from "../constants"; -import * as Log from "../history"; -import store from "../store"; - -import CheckboxControl from "../components/CheckboxControl.jsx"; -import ColDisplay from "../components/ColDisplay.jsx"; -import DeleteButton from "../components/DeleteButton.jsx"; -import EditButton from "../components/EditButton.jsx"; -import History from "../components/History.jsx"; -import SortTable from "../components/SortTable.jsx"; -import Spinner from "../components/Spinner.jsx"; -import TooltipButton from "../components/TooltipButton.jsx"; -import Confirm from "../components/Confirm.jsx"; -import OverlayTrigger from "../components/OverlayTrigger.jsx"; -import ReturnButton from "../components/ReturnButton.jsx"; -import PageHeader from "../components/ui/PageHeader.jsx"; -import SubHeader from "../components/ui/SubHeader.jsx"; -import PrintButton from "../components/PrintButton.jsx"; -import Authorize from "../components/Authorize.jsx"; - -import { - activeOwnerSelector, - activeOwnerIdSelector, -} from "../selectors/ui-selectors.js"; - -import { - formatDateTime, - formatDateTimeUTCToLocal, - today, - toZuluTime, -} from "../utils/date"; -import { sortDir, sort } from "../utils/array.js"; -import { firstLastName } from "../utils/string.js"; - -/* - -TODO: -* Print / Notes / Policy Proof Documents (attachments) - -*/ - -const CONTACT_NAME_SORT_FIELDS = ["givenName", "surname"]; - -const OWNER_WITH_EQUIPMENT_IN_ACTIVE_RENTAL_REQUEST_WARNING_MESSAGE = - "This owner has equipment that " + - "is part of an In Progress Rental Request. Release the list (finish hiring / delete) before making this change"; - -class OwnersDetail extends React.Component { - static propTypes = { - ownerId: PropTypes.number.isRequired, - owner: PropTypes.object, - documents: PropTypes.object, - uiContacts: PropTypes.object, - uiEquipment: PropTypes.object, - router: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - reloading: false, - - showEditDialog: false, - showContactDialog: false, - showPolicyDialog: false, - showPolicyDocumentsDialog: false, - showEquipmentDialog: false, - showDocumentsDialog: false, - showNotesDialog: false, - showChangeStatusDialog: false, - - showAttachments: false, - - contact: {}, - - status: "", - - // Contacts - uiContacts: { - sortField: props.uiContacts.sortField || CONTACT_NAME_SORT_FIELDS, - sortDesc: props.uiContacts.sortDesc === true, - }, - - // Equipment - uiEquipment: { - sortField: props.uiEquipment.sortField || "equipmentNumber", - sortDesc: props.uiEquipment.sortDesc === true, - }, - }; - } - - componentDidMount() { - const { ownerId, owner } = this.props; - - /* Documents need be fetched every time as they are not project specific in the store ATM */ - Api.getOwnerDocuments(ownerId).then(() => - this.setState({ loadingDocuments: false }) - ); - - // Only show loading spinner if there is no existing project in the store - if (owner) { - this.setState({ loading: false }); - } - - // Re-fetch project and notes every time - Promise.all([this.fetch(), Api.getOwnerNotes(ownerId)]).then(() => { - this.setState({ loading: false }); - }); - } - - fetch = () => { - this.setState({ reloading: true }); - return Api.getOwner(this.props.ownerId).then(() => - this.setState({ reloading: false }) - ); - }; - - updateContactsUIState = (state, callback) => { - this.setState( - { uiContacts: { ...this.state.uiContacts, ...state } }, - () => { - store.dispatch({ - type: Action.UPDATE_OWNER_CONTACTS_UI, - ownerContacts: this.state.uiContacts, - }); - if (callback) { - callback(); - } - } - ); - }; - - updateEquipmentUIState = (state, callback) => { - this.setState( - { uiEquipment: { ...this.state.uiEquipment, ...state } }, - () => { - store.dispatch({ - type: Action.UPDATE_OWNER_EQUIPMENT_UI, - ownerEquipment: this.state.uiEquipment, - }); - if (callback) { - callback(); - } - } - ); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateStatusState = (state) => { - if (state !== this.props.owner.status) { - this.setState({ status: state }, this.openChangeStatusDialog); - } - }; - - openChangeStatusDialog = () => { - this.setState({ showChangeStatusDialog: true }); - }; - - closeChangeStatusDialog = () => { - this.setState({ showChangeStatusDialog: false }); - }; - - onStatusChanged = () => { - this.closeChangeStatusDialog(); - Api.getOwnerNotes(this.props.owner.id); - }; - - showDocuments = () => { - this.setState({ showDocumentsDialog: true }); - }; - - closeDocumentsDialog = () => { - this.setState({ showDocumentsDialog: false }); - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - ownerSaved = () => { - Log.ownerModified(this.props.owner); - }; - - openContactDialog = (contactId) => { - var contact; - if (contactId === 0) { - // New - contact = { - id: 0, - owner: this.props.owner, - }; - } else if (contactId) { - // Open the contact for viewing if possible - contact = this.props.owner.contacts.find( - (contact) => contact.id === contactId - ); - } - this.setState({ - contact: contact, - showContactDialog: true, - }); - }; - - closeContactDialog = () => { - this.setState({ showContactDialog: false }); - }; - - deleteContact = (contact) => { - Api.deleteContact(contact).then(() => { - Log.ownerContactDeleted(this.props.owner, contact).then(() => { - // In addition to refreshing the contacts, we need to update the owner - // to get primary contact info and history. - this.fetch(); - }); - }); - }; - - contactSaved = (contact) => { - var isNew = !contact.id; - var log = isNew ? Log.ownerContactAdded : Log.ownerContactUpdated; - - log(this.props.owner, contact).then(() => { - // In addition to refreshing the contacts, we need to update the owner - // to get primary contact info and history. - this.fetch(); - }); - - this.closeContactDialog(); - }; - - openEquipmentDialog = () => { - this.setState({ showEquipmentDialog: true }); - }; - - closeEquipmentDialog = () => { - this.setState({ showEquipmentDialog: false }); - }; - - equipmentSaved = (equipment) => { - this.closeEquipmentDialog(); - Log.ownerEquipmentAdded(this.props.owner, equipment); - Log.equipmentAdded(equipment); - // Open it up - this.props.router.push({ - pathname: `${Constant.EQUIPMENT_PATHNAME}/${equipment.id}`, - state: { - returnUrl: `${Constant.OWNERS_PATHNAME}/${this.props.owner.id}`, - }, - }); - }; - - equipmentVerifyAll = () => { - var now = today(); - var owner = this.props.owner; - - // Update the last verified date on all pieces of equipment - var equipmentList = _.map(owner.equipmentList, (equipment) => { - return { - ...equipment, - lastVerifiedDate: toZuluTime(now), - owner: { id: owner.id }, - }; - }); - - Api.updateOwnerEquipment(owner, equipmentList).then(() => { - this.fetch(); - }); - }; - - equipmentVerify = (equipment) => { - const updatedEquipment = { - ...equipment, - lastVerifiedDate: toZuluTime(today()), - owner: { id: this.props.owner.id }, - }; - - Log.ownerEquipmentVerified(this.props.owner, updatedEquipment); - - Api.updateEquipment(updatedEquipment).then(() => { - this.fetch(); - }); - }; - - openPolicyDialog = () => { - this.setState({ showPolicyDialog: true }); - }; - - closePolicyDialog = () => { - this.setState({ showPolicyDialog: false }); - }; - - policySaved = () => { - Log.ownerModifiedPolicy(this.props.owner); - }; - - openPolicyDocumentsDialog = () => { - // TODO Show popup with links to policy documents - this.setState({ showPolicyDocumentsDialog: true }); - }; - - closePolicyDocumentsDialog = () => { - this.setState({ showPolicyDocumentsDialog: false }); - }; - - addPolicyDocument = () => { - // TODO Upload policy document (proof of policy coverage) - }; - - openNotesDialog = () => { - this.setState({ showNotesDialog: true }); - }; - - closeNotesDialog = () => { - this.setState({ showNotesDialog: false }); - }; - - render() { - const { loading, loadingDocuments } = this.state; - var owner = this.props.owner || {}; - - var isApproved = owner.status === Constant.OWNER_STATUS_CODE_APPROVED; - var restrictEquipmentAddTooltip = - "Equipment can only be added to an approved owner."; - var restrictEquipmentVerifyTooltip = - "Equipment can only be verified for an approved owner."; - - const statuses = _.pull( - [ - Constant.OWNER_STATUS_CODE_APPROVED, - Constant.OWNER_STATUS_CODE_PENDING, - Constant.OWNER_STATUS_CODE_ARCHIVED, - ], - owner.status - ); - - return ( -
-
- - - - - - - - -
- - -
- -
- - - - - - - - {(() => { - if (loading) { - return ( -
- -
- ); - } - - return ( -
- - - - {owner.doingBusinessAs} - - - - - {owner.primaryContactName} - - - - - {owner.ownerName} - - - - - {owner.ownerCode} - - - - - {owner.districtName} - - - - - {owner.meetsResidency ? "Yes" : "No"} - - - - - {owner.registeredCompanyNumber} - - - - - {owner.localAreaName} - - - - - {owner.isMaintenanceContractor ? "Yes" : "No"} - - - - - {owner.address1} {owner.address2}
{" "} - {owner.city} {owner.province} {owner.postalCode} -
- -
-
- ); - })()} -
- - - - - {(() => { - if (loading) { - return ( -
- -
- ); - } - - return ( - - - - {owner.workSafeBCPolicyNumber} - - - - - {formatDateTime( - owner.workSafeBCExpiryDate, - Constant.DATE_YEAR_SHORT_MONTH_DAY - )} - - - - - {owner.cglCompanyName} - - - - - {owner.cglPolicyNumber} - - - - - {formatDateTime( - owner.cglEndDate, - Constant.DATE_YEAR_SHORT_MONTH_DAY - )} - - - - ); - })()} -
- - - - - {(() => { - if (loading) { - return ( -
- -
- ); - } - - var addContactButton = ( - - - - ); - - if (!owner.contacts || owner.contacts.length === 0) { - return ( - - No contacts {addContactButton} - - ); - } - - var contacts = sort( - owner.contacts, - this.state.uiContacts.sortField, - this.state.uiContacts.sortDesc - ); - - var headers = [ - { field: CONTACT_NAME_SORT_FIELDS, title: "Name" }, - { field: "phone", title: "Phone" }, - { field: "mobilePhoneNumber", title: "Cell Phone" }, - { field: "faxPhoneNumber", title: "Fax" }, - { field: "emailAddress", title: "Email" }, - { field: "role", title: "Role" }, - { field: "notes", title: "Notes" }, - { - field: "addContact", - title: "Add Contact", - style: { textAlign: "right" }, - node: addContactButton, - }, - ]; - - return ( - - {contacts.map((contact) => { - return ( - - - {contact.isPrimary && } - {firstLastName( - contact.givenName, - contact.surname - )} - - {contact.phone} - {contact.mobilePhoneNumber} - {contact.faxPhoneNumber} - - - {contact.emailAddress} - - - {contact.role} - {contact.notes ? "Y" : ""} - - - {contact.canDelete && !contact.isPrimary && ( - - - - )} - {contact.canEdit && ( - - )} - - - - ); - })} - - ); - })()} -
- - - - Show Attachments - - - - } - > - - Verify All - - - - - - - - {(() => { - if (loading) { - return ( -
- -
- ); - } - - if ( - !owner.equipmentList || - owner.equipmentList.length === 0 - ) { - return No equipment; - } - - var equipmentList = _.orderBy( - owner.equipmentList, - [this.state.uiEquipment.sortField], - sortDir(this.state.uiEquipment.sortDesc) - ); - - var headers = [ - { field: "equipmentNumber", title: "ID" }, - { field: "localArea.name", title: "Local Area" }, - { field: "typeName", title: "Equipment Type" }, - { field: "details", title: "Make/Model/Size/Year" }, - { field: "lastVerifiedDate", title: "Last Verified" }, - { field: "blank" }, - ]; - - return ( - - {_.map(equipmentList, (equipment) => { - const location = { - pathname: `${Constant.EQUIPMENT_PATHNAME}/${equipment.id}`, - state: { - returnUrl: `${Constant.OWNERS_PATHNAME}/${owner.id}`, - }, - }; - return ( - - - - {equipment.equipmentCode} - - - {equipment.localArea.name} - {equipment.typeName} - - {equipment.details} - {this.state.showAttachments && ( -
- Attachments: - {equipment.equipmentAttachments && - equipment.equipmentAttachments.map( - (item, i) => ( - - - - {item.typeName} - {i + 1 < - equipment.equipmentAttachments - .length && ,} - - - ) - )} - {(!equipment.equipmentAttachments || - equipment.equipmentAttachments.length === - 0) && none} -
- )} - - - {equipment.isApproved - ? formatDateTimeUTCToLocal( - equipment.lastVerifiedDate, - Constant.DATE_YEAR_SHORT_MONTH_DAY - ) - : "Not Approved"} - - - - - OK - - - - - ); - })} -
- ); - })()} -
- - - {owner.historyEntity && ( - - )} - - -
-
- {this.state.showChangeStatusDialog && ( - - )} - {this.state.showNotesDialog && ( - - )} - {this.state.showDocumentsDialog && ( - - )} - {this.state.showEditDialog && ( - - )} - {this.state.showEquipmentDialog && ( - - )} - {this.state.showPolicyDialog && ( - - )} - {this.state.showContactDialog && ( - - )} -
- ); - } -} - -function mapStateToProps(state) { - return { - owner: activeOwnerSelector(state), - ownerId: activeOwnerIdSelector(state), - documents: state.models.documents, - uiContacts: state.ui.ownerContacts, - uiEquipment: state.ui.ownerEquipment, - }; -} - -export default connect(mapStateToProps)(OwnersDetail); diff --git a/client/src/js/views/Projects.jsx b/client/src/js/views/Projects.jsx deleted file mode 100644 index 90aa4b2aa..000000000 --- a/client/src/js/views/Projects.jsx +++ /dev/null @@ -1,267 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, Form } from 'react-bootstrap'; -import _ from 'lodash'; - -import ProjectsAddDialog from './dialogs/ProjectsAddDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; -import EditButton from '../components/EditButton.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - - -class Projects extends React.Component { - static propTypes = { - fiscalYears: PropTypes.array, - projects: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showAddDialog: false, - search: { - statusCode: props.search.statusCode || Constant.PROJECT_STATUS_CODE_ACTIVE, - projectName: props.search.projectName || '', - projectNumber: props.search.projectNumber || '', - fiscalYear: props.search.fiscalYear || '', - }, - ui : { - sortField: props.ui.sortField || 'name', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.projectName) { - searchParams.project = this.state.search.projectName; - } - - if (this.state.search.statusCode) { - searchParams.status = this.state.search.statusCode; - } - - if (this.state.search.projectNumber) { - searchParams.projectNumber = this.state.search.projectNumber; - } - - if (this.state.search.fiscalYear) { - searchParams.fiscalYear = this.state.search.fiscalYear; - } - - return searchParams; - }; - - componentDidMount() { - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchProjects(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - statusCode: Constant.PROJECT_STATUS_CODE_ACTIVE, - projectName: '', - projectNumber: '', - fiscalYear: '', - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_PROJECTS_SEARCH, projects: this.state.search }); - store.dispatch({ type: Action.CLEAR_PROJECTS }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_PROJECTS_SEARCH, projects: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_PROJECTS_UI, projects: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - openAddDialog = () => { - this.setState({ showAddDialog: true }); - }; - - closeAddDialog = () => { - this.setState({ showAddDialog: false }); - }; - - projectAdded = (project) => { - this.fetch(); - this.props.router.push({ - pathname: `${ Constant.PROJECTS_PATHNAME }/${ project.id }`, - }); - }; - - renderResults = (addProjectButton) => { - if (Object.keys(this.props.projects.data).length === 0) { - return No Projects { addProjectButton }; - } - - var projects = _.sortBy(this.props.projects.data, project => { - var sortValue = project[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(projects); - } - - return - { - _.map(projects, (project) => { - return - { project.name } - { project.fiscalYear } - { project.provincialProjectNumber } - { project.primaryContactName } - { project.primaryContactPhone } - { project.hires } - { project.requests } - { project.status } - - - - - - ; - }) - } - ; - }; - - render() { - var resultCount = ''; - if (this.props.projects.loaded) { - resultCount = '(' + Object.keys(this.props.projects.data).length + ')'; - } - - return
- Projects { resultCount } - - - - - -
- - - - - - - - - - - - - - - - - -
-
- - {(() => { - if (this.props.projects.loading) { - return
; - } - - var addProjectButton = ( - - ); - - if (this.props.projects.loaded) { - return this.renderResults(addProjectButton); - } - - return { addProjectButton }; - })()} - { this.state.showAddDialog && ( - - )} -
; - } -} - - -function mapStateToProps(state) { - return { - fiscalYears: state.lookups.fiscalYears, - projects: state.models.projects, - favourites: state.models.favourites.project, - search: state.search.projects, - ui: state.ui.projects, - }; -} - -export default connect(mapStateToProps)(Projects); diff --git a/client/src/js/views/ProjectsDetail.jsx b/client/src/js/views/ProjectsDetail.jsx deleted file mode 100644 index 24ef5d3cc..000000000 --- a/client/src/js/views/ProjectsDetail.jsx +++ /dev/null @@ -1,584 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Row, Col } from 'react-bootstrap'; -import { Alert, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; -import { Link } from 'react-router'; -import _ from 'lodash'; -import Promise from 'bluebird'; - -import ProjectsEditDialog from './dialogs/ProjectsEditDialog.jsx'; -import ContactsEditDialog from './dialogs/ContactsEditDialog.jsx'; -import DocumentsListDialog from './dialogs/DocumentsListDialog.jsx'; -import RentalRequestsAddDialog from './dialogs/RentalRequestsAddDialog.jsx'; -import TimeEntryDialog from './dialogs/TimeEntryDialog.jsx'; -import NotesDialog from './dialogs/NotesDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import * as Log from '../history'; -import store from '../store'; - -import CheckboxControl from '../components/CheckboxControl.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import Confirm from '../components/Confirm.jsx'; -import DeleteButton from '../components/DeleteButton.jsx'; -import EditButton from '../components/EditButton.jsx'; -import History from '../components/History.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import StatusDropdown from '../components/StatusDropdown.jsx'; -import TableControl from '../components/TableControl.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { activeProjectSelector, activeProjectIdSelector } from '../selectors/ui-selectors.js'; - -import { formatDateTime } from '../utils/date'; -import { sort, caseInsensitiveSort } from '../utils/array.js'; -import { firstLastName } from '../utils/string.js'; -import ReturnButton from '../components/ReturnButton.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - - -const CONTACT_NAME_SORT_FIELDS = ['givenName', 'surname']; - -const STATUS_NOT_EDITABLE_MESSAGE = 'The project can only be marked as completed when it has no active requests or actively hired equipment.'; - -class ProjectsDetail extends React.Component { - static propTypes = { - projectId: PropTypes.number, - project: PropTypes.object, - documents: PropTypes.object, - uiContacts: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - loadingDocuments: true, - reloading: false, - - showNotesDialog: false, - showDocumentsDialog: false, - showEditDialog: false, - showAddRequestDialog: false, - showTimeEntryDialog: false, - showContactDialog: false, - - includeCompletedRequests: false, - - contact: {}, - - rentalAgreement: {}, - - // Contacts - uiContacts : { - sortField: props.uiContacts.sortField || CONTACT_NAME_SORT_FIELDS, - sortDesc: props.uiContacts.sortDesc === true, - }, - }; - } - - componentDidMount() { - const { projectId, project } = this.props; - - /* Documents need be fetched every time as they are not project specific in the store ATM */ - Api.getProjectDocuments(projectId).then(() => this.setState({ loadingDocuments: false })); - - // Only show loading spinner if there is no existing project in the store - if (project) { - this.setState({ loading: false }); - } - - // Re-fetch project and notes every time - Promise.all([ - this.fetch(), - Api.getProjectNotes(projectId), - ]).then(() => { - this.setState({ loading: false }); - }); - } - - fetch = () => { - this.setState({ reloading: true }); - return Api.getProject(this.props.projectId).then(() => this.setState({ reloading: false })); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateContactsUIState = (state, callback) => { - this.setState({ uiContacts: { ...this.state.uiContacts, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_PROJECT_CONTACTS_UI, projectContacts: this.state.uiContacts }); - if (callback) { callback(); } - }); - }; - - showNotes = () => { - this.setState({ showNotesDialog: true }); - }; - - closeNotesDialog = () => { - this.setState({ showNotesDialog: false }); - }; - - showDocuments = () => { - this.setState({ showDocumentsDialog: true }); - }; - - closeDocumentsDialog = () => { - this.setState({ showDocumentsDialog: false }); - }; - - addDocument = () => { - - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - openContactDialog = (contactId) => { - var contact; - if (contactId === 0) { - // New - contact = { - id: 0, - owner: this.props.project, - }; - } else if (contactId) { - // Open the contact for viewing if possible - contact = _.find(this.props.project.contacts, (contact) => contact.id === contactId); - } - this.setState({ - contact: contact, - showContactDialog: true, - }); - }; - - closeContactDialog = () => { - this.setState({ contact:null, showContactDialog: false }); - }; - - deleteContact = (contact) => { - Api.deleteContact(contact).then(() => { - Log.projectContactDeleted(this.props.project, contact).then(() => { - this.fetch(); - }); - }); - }; - - contactSaved = (contact) => { - var isNew = !contact.id; - var log = isNew ? Log.projectContactAdded : Log.projectContactUpdated; - - log(this.props.project, contact).then(() => { - // In addition to refreshing the contacts, we need to update the owner - // to get primary contact info and history. - this.fetch(); - }); - - this.closeContactDialog(); - }; - - openAddRequestDialog = () => { - this.setState({ showAddRequestDialog: true }); - }; - - closeAddRequestDialog = () => { - this.setState({ showAddRequestDialog: false }); - }; - - newRentalAdded = (rentalRequest) => { - this.fetch(); - - Log.projectRentalRequestAdded(this.props.project, rentalRequest); - - this.props.router.push({ - pathname: `${ Constant.RENTAL_REQUESTS_PATHNAME }/${ rentalRequest.id }`, - }); - }; - - confirmEndHire = (item) => { - Api.releaseRentalAgreement(item.id).then(() => { - Api.getProject(this.props.projectId); - Log.projectEquipmentReleased(this.props.project, item.equipment); - }); - }; - - openTimeEntryDialog = (rentalAgreement) => { - this.setState({ rentalAgreement }, () => { - this.setState({ - showTimeEntryDialog: true, - fiscalYearStartDate: this.props.project.fiscalYearStartDate, - }); - }); - }; - - closeTimeEntryDialog = () => { - this.setState({ showTimeEntryDialog: false }); - }; - - cancelRequest = (request) => { - store.dispatch({ type: Action.DELETE_PROJECT_RENTAL_REQUEST, projectId: this.props.projectId, requestId: request.id }); - Api.cancelRentalRequest(request.id).then(() => { - this.fetch(); - }); - }; - - renderRentalRequestListItem = (item) => { - return - - - Request - - - { item.localAreaName } - { item.equipmentTypeName } - { item.equipmentCount } - TBD - N/A - N/A - N/A - N/A - - 0 } onConfirm={ this.cancelRequest.bind(this, item) }/> - - ; - }; - - renderRentalAgreementListItem = (item) => { - return - - - { item.equipmentCode } - - - { item.localAreaName } - { item.equipmentTypeName } -   - { item.equipment.equipmentDetails } - { item.isCompleted ? - 'Completed' - : - - } - - - { item.status === Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED ? -
Released
- : - - }> - - - - } - - Agreement - { formatDateTime(item.datedOn, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - ; - }; - - getStatuses = () => { - var project = this.props.project || {}; - - return _.pull([ - Constant.PROJECT_STATUS_CODE_ACTIVE, - Constant.PROJECT_STATUS_CODE_COMPLETED, - ], project.status); - }; - - updateStatusState = (state) => { - if (state !== this.props.project.status) { - const project = { - ...this.props.project, - status: state, - }; - - store.dispatch({ type: Action.UPDATE_PROJECT, project }); - Log.projectModifiedStatus(project); - Api.updateProject(project); - } - }; - - render() { - const { loading, loadingDocuments } = this.state; - var project = this.props.project || {}; - - // As per business requirements: - // "Lists the records - requests then rental agreements, within the groups, list in largest-to-smallest ID order (aka reverse chronological create)." - var rentalRequests = _.orderBy(project.rentalRequests, ['id'], ['desc']); - var rentalAgreements = _.orderBy(project.rentalAgreements, ['id'], ['desc']); - - var combinedList =_.concat(rentalRequests, rentalAgreements); - // Exclude completed items - if (!this.state.includeCompletedRequests) { - _.remove(combinedList, (x) => !x.isActive); - } - - return ( -
-
-
- - - - - - - -
- - -
- -
- - -
- - - - - - {(() => { - if (loading) { return
; } - - var mailto = - { project.primaryContactName } - ; - - return - - { project.fiscalYear } - - - { project.provincialProjectNumber } - - - { project.responsibilityCentre } - - - { project.serviceLine } - - - { project.stob } - - - { project.product } - - - { project.businessFunction } - - - { project.workActivity } - - - { project.costType } - - - { project.information } - - - - { project.primaryContactEmail ? mailto : `${project.primaryContactName}` }{ project.primaryContactPhone ? `, ${project.primaryContactPhone}` : '' } - - - ; - })()} -
- - - Show Completed - - - {(() => { - if (loading) { return
; } - - if (Object.keys(combinedList).length === 0) { return No equipment; } - - var headers = [ - { field: 'equipmentCode', title: 'ID' }, - { field: 'localAreaName', title: 'Local Area' }, - { field: 'equipmentTypeName', title: 'Type' }, - { field: 'equipmentCount', title: 'Quantity' }, - { field: 'equipmentMake', title: 'Year Make/Model/Size' }, - { field: 'lastTimeRecord', title: 'Time Entry' }, - { field: 'release', title: 'Release' }, - { field: 'agreement', title: 'Agreement' }, - { field: 'hiredDate', title: 'Hired Date' }, - { field: 'blank' }, - ]; - - return - { - _.map(combinedList, (listItem) => { - if (listItem.isRentalRequest) { - return this.renderRentalRequestListItem(listItem); - } else { - return this.renderRentalAgreementListItem(listItem); - } - }) - } - ; - })()} -
- - - - - {(() => { - if (loading) { return
; } - - var addContactButton = ; - - if (!project.contacts || project.contacts.length === 0) { return No contacts { addContactButton }; } - - var contacts = sort(project.contacts, this.state.uiContacts.sortField, this.state.uiContacts.sortDesc, caseInsensitiveSort); - - var headers = [ - { field: 'name', title: 'Name' }, - { field: 'phone', title: 'Phone' }, - { field: 'mobilePhoneNumber', title: 'Cell Phone' }, - { field: 'faxPhoneNumber', title: 'Fax' }, - { field: 'emailAddress', title: 'Email' }, - { field: 'role', title: 'Role' }, - { field: 'notes', title: 'Notes' }, - { field: 'addContact', title: 'Add Contact', style: { textAlign: 'right' }, - node: addContactButton, - }, - ]; - - return - { - contacts.map((contact) => { - return - - { contact.isPrimary && } - { firstLastName(contact.givenName, contact.surname) } - - { contact.phone } - { contact.mobilePhoneNumber } - { contact.faxPhoneNumber } - { contact.emailAddress } - { contact.role } - { contact.notes ? 'Y' : '' } - - - {contact.canDelete && ( - - )} - {contact.canEdit && ( - - )} - - - ; - }) - } - ; - })()} -
- - - { project.historyEntity && } - - -
-
- {this.state.showEditDialog && ( - - )} - {this.state.showNotesDialog && ( - - )} - {this.state.showDocumentsDialog && ( - - )} - {this.state.showAddRequestDialog && ( - - )} - {this.state.showTimeEntryDialog && ( - - )} - {this.state.showContactDialog && ( - - )} -
- ); - } -} - - -function mapStateToProps(state) { - return { - project: activeProjectSelector(state), - projectId: activeProjectIdSelector(state), - documents: state.models.documents, - uiContacts: state.ui.projectContacts, - }; -} - -export default connect(mapStateToProps)(ProjectsDetail); diff --git a/client/src/js/views/RentalAgreementsDetail.jsx b/client/src/js/views/RentalAgreementsDetail.jsx deleted file mode 100644 index 2bd4cfbe3..000000000 --- a/client/src/js/views/RentalAgreementsDetail.jsx +++ /dev/null @@ -1,522 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Well, Row, Col, Table, Alert, Button, Glyphicon, Label, ButtonGroup } from 'react-bootstrap'; -import _ from 'lodash'; - -import EquipmentRentalRatesEditDialog from './dialogs/EquipmentRentalRatesEditDialog.jsx'; -import RentalAgreementsEditDialog from './dialogs/RentalAgreementsEditDialog.jsx'; -import RentalConditionsEditDialog from './dialogs/RentalConditionsEditDialog.jsx'; -import RentalAgreementOvertimeNotesDialog from './dialogs/RentalAgreementOvertimeNotesDialog.jsx'; -import RentalRatesEditDialog from './dialogs/RentalRatesEditDialog.jsx'; -import CloneDialog from './dialogs/CloneDialog.jsx'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import ColDisplay from '../components/ColDisplay.jsx'; -import DeleteButton from '../components/DeleteButton.jsx'; -import EditButton from '../components/EditButton.jsx'; -import Spinner from '../components/Spinner.jsx'; -import TooltipButton from '../components/TooltipButton.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { activeRentalAgreementSelector, activeRentalAgreementIdSelector } from '../selectors/ui-selectors'; - -import { buildApiPath } from '../utils/http.js'; -import { formatDateTime } from '../utils/date'; -import { formatCurrency } from '../utils/string'; - - -class RentalAgreementsDetail extends React.Component { - static propTypes = { - rentalAgreement: PropTypes.object, - rentalAgreementId: PropTypes.number, - rentalConditions: PropTypes.array, - ui: PropTypes.object, - location: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - rentalAgreementDocumentLoading: false, - - showEditDialog: false, - showEquipmentRateDialog: false, - showRentalRateDialog: false, - showConditionDialog: false, - showCloneDialog: false, - - rentalRate: {}, - rentalCondition: {}, - }; - } - - componentDidMount() { - const { rentalAgreement } = this.props; - - // Only show loading spinner if there is no existing rental agreement in the store - if (rentalAgreement) { - this.setState({ loading: false }); - } - - // Re-fetch rental agreement every time - Promise.all([ - this.fetch(rentalAgreement), - ]).then(() => { - this.setState({ loading: false }); - }); - } - - fetch = () => { - return Api.getRentalAgreement(this.props.rentalAgreementId); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - openEquipmentRateDialog = () => { - this.setState({ showEquipmentRateDialog: true }); - }; - - closeEquipmentRateDialog = () => { - this.setState({ showEquipmentRateDialog: false }); - }; - - openRentalRateDialog = (rentalRate) => { - this.setState({ - rentalRate, - showRentalRateDialog: true, - }); - }; - - addRentalRate = (isIncluded) => { - // New - this.openRentalRateDialog({ - id: 0, - isIncludedInTotal: isIncluded, - rentalAgreement: this.props.rentalAgreement, - }); - }; - - closeRentalRateDialog = () => { - this.setState({ showRentalRateDialog: false }); - }; - - deleteRentalRate = (rentalRate) => { - Api.deleteRentalRate(rentalRate).then(() => { - // In addition to refreshing the rental rates, we need to update the rental agreement to get - // possibly new info. - this.fetch(); - }); - }; - - openConditionDialog = (rentalCondition) => { - this.setState({ - rentalCondition, - showConditionDialog: true, - }); - }; - - closeConditionDialog = () => { - this.setState({ showConditionDialog: false }); - }; - - addCondition = () => { - this.openConditionDialog({ - id: 0, - rentalAgreement: this.props.rentalAgreement, - }); - }; - - deleteCondition = (rentalCondition) => { - Api.deleteRentalCondition(rentalCondition).then(() => { - // In addition to refreshing the rental condition, we need to update the rental agreement to - // get possibly new info. - this.fetch(); - }); - }; - - openOvertimeNotesDialog = () => { - this.setState({ showOvertimeNotesDialog: true }); - }; - - closeOvertimeNotesDialog = () => { - this.setState({ showOvertimeNotesDialog: false }); - }; - - generateRentalAgreementDocument = () => { - Api.generateRentalAgreementDocument(this.props.rentalAgreementId).then(() => { - window.open(buildApiPath(`/rentalagreements/${ this.props.rentalAgreementId }/doc`)); - }); - }; - - openCloneDialog = () => { - this.setState({ showCloneDialog: true }); - }; - - closeCloneDialog = () => { - this.setState({ showCloneDialog: false }); - }; - - render() { - const { loading } = this.state; - const rentalAgreement = this.props.rentalAgreement || { }; - - var buttons = -
- - - -
; - - return ( -
- - -
- {!loading && } -
- - - { buttons } - -
- - - {(() => { - if (loading) { return
; } - - var equipmentDetails = rentalAgreement.equipment && rentalAgreement.equipment.id != 0 ? `${rentalAgreement.equipment.year} ${rentalAgreement.equipment.make}/${rentalAgreement.equipment.model}/${rentalAgreement.equipment.size}` : ''; - - return ( -
- - - - { rentalAgreement.number } - - - - View - - - - { rentalAgreement.project.name } - - - { rentalAgreement.district.name } - - - { rentalAgreement.ownerName } - - - { rentalAgreement.equipment.owner.workSafeBcpolicyNumber } - - - - { rentalAgreement.equipment.equipmentCode } - - - - { rentalAgreement.equipment.serialNumber } - - - { equipmentDetails } - - - { rentalAgreement.pointOfHire } - - -
- ); - })()} -
- - - - {(() => { - if (loading) { return
; } - - return ( - - - { formatDateTime(rentalAgreement.estimateStartWork, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - { rentalAgreement.estimateHours } - - - { formatDateTime(rentalAgreement.datedOn, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - { rentalAgreement.agreementCity } - - - ); - })()} -
- - - - {(() => { - if (loading) { return
; } - - return - - Pay Rate: { formatCurrency(rentalAgreement.equipmentRate) } - - - Period: { rentalAgreement.ratePeriod } - - - Comment: { rentalAgreement.rateComment } - - - ; - })()} - - {(() => { - if (loading) { return; } - - // filter to included rates only - // as-needed rates are shown in the next section - var includedRates = _.filter(rentalAgreement.rentalAgreementRates, { isIncludedInTotal: true }); - - var button = - - Add Included Rates and Attachments - ; - - if (Object.keys(includedRates || []).length === 0) { return
No included rates or attachments{ button }
; } - - // newly-added rates (with an id of 0) need to appear at the end of the list - includedRates = _.orderBy(includedRates, [r => r.id === 0, r => r.id], ['asc', 'asc']); - - return
- - - - - - - - - - - { - _.map(includedRates, (obj, i) => { - return - - - - - ; - }) - } - -
RatePeriodComment
{ formatCurrency(obj.rate) }{ obj.ratePeriod }{ obj.comment } - - - - -
- { button } -
; - })()} -
- - - - {(() => { - if (loading) { return
; } - - // filter to as-needed rates only - // included rates are shown in the previous section - var asNeededRates = _.filter(rentalAgreement.rentalAgreementRates, { isIncludedInTotal: false }); - - var button = - - Add Other Rates and Attachments - ; - - if (Object.keys(asNeededRates || []).length === 0) { return
No as-needed rates or attachments{ button }
; } - - // newly-added rates (with an id of 0) need to appear at the end of the list - asNeededRates = _.orderBy(asNeededRates, [r => r.id === 0, r => r.id], ['asc', 'asc']); - - return
- - - - - - - - - - - { - _.map(asNeededRates, (obj, i) => { - return - - - - - ; - }) - } - -
RatePeriodComment
{ formatCurrency(obj.rate) }{ obj.set ? Constant.RENTAL_RATE_PERIOD_SET : obj.ratePeriod }{ obj.comment } - - - - -
- { button } -
; - })()} -
- - - - {(() => { - if (loading) { return
; } - - // newly-added conditions (with an id of 0) need to appear at the end of the list - var rentalConditions = _.orderBy(rentalAgreement.rentalAgreementConditions, [c => c.id === 0, c => c.id], ['asc', 'asc']); - - var button = ; - - if (Object.keys(rentalConditions || []).length === 0) { return
No rental conditions{ button }
; } - - return
- - - - - - - - - - { - _.map(rentalConditions, (obj, i) => { - return - - - - ; - }) - } - -
ConditionComment
{ obj.conditionName }{ obj.comment } - - - - -
- { button } -
; - })()} -
- - - - {(() => { - if (loading) { return
; } - - var rates = _.orderBy(rentalAgreement.overtimeRates, ['comment'], ['desc']); - - return - { - rates.map((rate) => { - if (rate.active) { - return { rate.comment }; - } - }) - } - ; - })()} - { rentalAgreement && rentalAgreement.note } -
- - - {buttons} - - {this.state.showEditDialog && ( - - )} - {this.state.showEquipmentRateDialog && ( - - )} - {this.state.showRentalRateDialog && ( - - )} - {this.state.showConditionDialog && ( - - )} - {this.state.showOvertimeNotesDialog && ( - - )} - {this.state.showCloneDialog && ( - - )} -
- ); - } -} - - -function mapStateToProps(state) { - return { - rentalAgreement: activeRentalAgreementSelector(state), - rentalAgreementId: activeRentalAgreementIdSelector(state), - }; -} - -export default connect(mapStateToProps)(RentalAgreementsDetail); diff --git a/client/src/js/views/RentalRequests.jsx b/client/src/js/views/RentalRequests.jsx deleted file mode 100644 index 4d6f17c2e..000000000 --- a/client/src/js/views/RentalRequests.jsx +++ /dev/null @@ -1,384 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, Form } from 'react-bootstrap'; -import { Link } from 'react-router'; -import _ from 'lodash'; -import Moment from 'moment'; - -import RentalRequestsAddDialog from './dialogs/RentalRequestsAddDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import * as Log from '../history'; -import store from '../store'; - -import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import DateControl from '../components/DateControl.jsx'; -import DeleteButton from '../components/DeleteButton.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; -import EditButton from '../components/EditButton.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import Mailto from '../components/Mailto.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { formatDateTime, startOfCurrentFiscal, endOfCurrentFiscal, startOfPreviousFiscal, endOfPreviousFiscal, toZuluTime } from '../utils/date'; - -const WITHIN_30_DAYS = 'Within 30 Days'; -const THIS_MONTH = 'This Month'; -const THIS_QUARTER = 'This Quarter'; -const THIS_FISCAL = 'This Fiscal'; -const LAST_MONTH = 'Last Month'; -const LAST_QUARTER = 'Last Quarter'; -const LAST_FISCAL = 'Last Fiscal'; -const CUSTOM = 'Custom'; - - -class RentalRequests extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - rentalRequests: PropTypes.object, - rentalRequest: PropTypes.object, - localAreas: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showAddDialog: false, - addViewOnly: false, - search: { - selectedLocalAreasIds: props.search.selectedLocalAreasIds || [], - projectName: props.search.projectName || '', - status: props.search.status || Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, - dateRange: props.search.dateRange || '', - }, - ui : { - sortField: props.ui.sortField || 'projectName', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = { - status: this.state.search.status || '', - project: this.state.search.projectName || '', - }; - - if (this.state.search.selectedLocalAreasIds.length > 0) { - searchParams.localAreas = this.state.search.selectedLocalAreasIds; - } - - // Time period drop-down; e.g. "This Month" - var startDate; - var endDate; - var today = Moment(); - - switch (this.state.search.dateRange) { - case WITHIN_30_DAYS: - endDate = today.add(30, 'day'); - break; - case THIS_MONTH: - startDate = today.startOf('month'); - endDate = Moment(startDate).endOf('month'); - break; - case THIS_QUARTER: - startDate = today.startOf('quarter'); - endDate = Moment(startDate).endOf('quarter'); - break; - case THIS_FISCAL: - // Fiscal Year: Apr 1 - March 31 - startDate = startOfCurrentFiscal(today); - endDate = endOfCurrentFiscal(today); - break; - case LAST_MONTH: - startDate = today.subtract(1, 'month').startOf('month'); - endDate = Moment(startDate).endOf('month'); - break; - case LAST_QUARTER: - startDate = today.subtract(1, 'quarter').startOf('quarter'); - endDate = Moment(startDate).endOf('quarter'); - break; - case LAST_FISCAL: - // Fiscal Year: Apr 1 - March 31 - startDate = startOfPreviousFiscal(today); - endDate = endOfPreviousFiscal(today); - break; - case CUSTOM: - startDate = Moment(this.state.search.startDate); - endDate = Moment(this.state.search.endDate); - break; - default: - break; - } - - if (startDate && startDate.isValid()) { - searchParams.startDate = toZuluTime(startDate.startOf('day')); - } - if (endDate && endDate.isValid()) { - searchParams.endDate = toZuluTime(endDate.startOf('day')); - } - - return searchParams; - }; - - componentDidMount() { - var defaultFavourite = null; - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - } - - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); // also fetches - } else if (this.props.rentalRequests.loaded) { - // if a search was performed previously, refresh the search results - this.fetch(); - } - } - - fetch = () => { - Api.searchRentalRequests(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - selectedLocalAreasIds: [], - projectName: '', - status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, - dateRange: '', - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: this.state.search }); - store.dispatch({ type: Action.CLEAR_RENTAL_REQUESTS }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_SEARCH, rentalRequests: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_RENTAL_REQUESTS_UI, rentalRequests: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - deleteRequest = (request) => { - Api.cancelRentalRequest(request.id).then(() => { - this.fetch(); - }); - }; - - openAddDialog = (viewOnly) => { - this.setState({ showAddDialog: true, addViewOnly: viewOnly }); - }; - - closeAddDialog = () => { - this.setState({ showAddDialog: false }); - }; - - newRentalAdded = (rentalRequest) => { - Log.rentalRequestAdded(rentalRequest); - - this.props.router.push({ - pathname: `${ Constant.RENTAL_REQUESTS_PATHNAME }/${ rentalRequest.id }`, - }); - }; - - renderResults = (addRequestButtons) => { - if (Object.keys(this.props.rentalRequests.data).length === 0) { return No Rental Requests { addRequestButtons }; } - - var rentalRequests = _.sortBy(this.props.rentalRequests.data, rentalRequest => { - var sortValue = rentalRequest[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(rentalRequests); - } - - return - { - _.map(rentalRequests, (request) => { - var projectLink = request.projectId ? { request.projectName } : request.projectName; - - return - { request.localAreaName } - { request.equipmentCount } - { request.districtEquipmentName } - { formatDateTime(request.expectedStartDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - { formatDateTime(request.expectedEndDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - { projectLink } - - { - request.primaryContactName ? - { request.primaryContactName } : - 'None' - } - - { request.status } - - - {request.canDelete && ( - - )} - {request.canView && ( - - )} - - - ; - }) - } - ; - }; - - render() { - // Constrain the local area drop downs to those in the District of the current logged in user - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - var resultCount = ''; - if (this.props.rentalRequests.loaded) { - resultCount = '(' + Object.keys(this.props.rentalRequests.data).length + ')'; - } - - return
- Rental Requests { resultCount } - - - - - -
- - - - - - - - - - - - - {(() => { - if (this.state.search.dateRange === CUSTOM) { - return - - - - - ; - } - })()} - - - - - - - -
-
- - {(() => { - if (this.props.rentalRequests.loading) { return
; } - - var addViewOnlyRequestButton = ( - - ); - - var addRentalRequestButton = ( - - ); - - var addRequestButtons =
- { addRentalRequestButton } - { addViewOnlyRequestButton } -
; - - if (this.props.rentalRequests.loaded) { - return this.renderResults(addRequestButtons); - } - - return { addRequestButtons }; - })()} - { this.state.showAddDialog && ( - - )} -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - rentalRequests: state.models.rentalRequests, - localAreas: state.lookups.localAreas, - favourites: state.models.favourites.rentalRequests, - search: state.search.rentalRequests, - ui: state.ui.rentalRequests, - }; -} - -export default connect(mapStateToProps)(RentalRequests); diff --git a/client/src/js/views/RentalRequestsDetail.jsx b/client/src/js/views/RentalRequestsDetail.jsx deleted file mode 100644 index 0c6e5fc6d..000000000 --- a/client/src/js/views/RentalRequestsDetail.jsx +++ /dev/null @@ -1,483 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Row, Col, Alert, Button, ButtonGroup, Glyphicon, Label } from 'react-bootstrap'; -import { Link } from 'react-router'; -import _ from 'lodash'; -import Promise from 'bluebird'; -import Moment from 'moment'; - -import HireOfferEditDialog from './dialogs/HireOfferEditDialog.jsx'; -import RentalRequestsEditDialog from './dialogs/RentalRequestsEditDialog.jsx'; -import DocumentsListDialog from './dialogs/DocumentsListDialog.jsx'; -import NotesDialog from './dialogs/NotesDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import * as Log from '../history'; -import store from '../store'; - -import CheckboxControl from '../components/CheckboxControl.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import PageOrientation from '../components/PageOrientation.jsx'; -import Spinner from '../components/Spinner.jsx'; -import TableControl from '../components/TableControl.jsx'; -import Confirm from '../components/Confirm.jsx'; -import History from '../components/History.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import TooltipButton from '../components/TooltipButton.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import Watermark from '../components/Watermark.jsx'; - -import { formatDateTime, formatDateTimeUTCToLocal } from '../utils/date'; -import { concat } from '../utils/string'; -import PrintButton from '../components/PrintButton.jsx'; -import { activeRentalRequestSelector, activeRentalRequestIdSelector } from '../selectors/ui-selectors.js'; - -/* - -TODO: -* Print / Notes / Docs / Contacts (TBD) / History / Request Status List / Clone / Request Attachments - -*/ -const STATUS_YES = 'Yes'; -const STATUS_NO = 'No'; -const STATUS_FORCE_HIRE = 'Force Hire'; -const STATUS_ASKED = 'Asked'; -const STATUS_IN_PROGRESS = 'In Progress'; - -class RentalRequestsDetail extends React.Component { - static propTypes = { - rentalRequestId: PropTypes.number, - rentalRequest: PropTypes.object, - documents: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - loadingDocuments: false, - reloading: false, - - showEditDialog: false, - showHireOfferDialog: false, - showNotesDialog: false, - showAttachments: false, - - rotationListHireOffer: {}, - showAllResponseFields: false, - - isNew: props.rentalRequestId == 0, - }; - } - - componentDidMount() { - const { rentalRequestId, rentalRequest } = this.props; - - /* Documents need be fetched every time as they are not rentalRequest specific in the store ATM */ - Api.getRentalRequestDocuments(rentalRequestId).then(() => this.setState({ loadingDocuments: false })); - - // Only show loading spinner if there is no existing rental request in the store - if (rentalRequest) { - this.setState({ loading: false }); - } - - // Re-fetch rental request, rotationlist, and notes every time - Promise.all([ - this.fetch(), - Api.getRentalRequestNotes(rentalRequestId), - Api.getRentalRequestRotationList(rentalRequestId), - ]).then(() => { - this.setState({ loading: false }); - }); - } - - fetch = () => { - this.setState({ reloading: true }); - return Api.getRentalRequest(this.props.rentalRequestId).then(() => this.setState({ reloading: false })); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateContactsUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () => { - store.dispatch({ type: Action.UPDATE_PROJECT_CONTACTS_UI, projectContacts: this.state.ui }); - if (callback) { callback(); } - }); - }; - - showNotes = () => { - this.setState({ showNotesDialog: true }); - }; - - closeNotesDialog = () => { - this.setState({ showNotesDialog: false }); - }; - - showDocuments = () => { - this.setState({ showDocumentsDialog: true }); - }; - - closeDocumentsDialog = () => { - this.setState({ showDocumentsDialog: false }); - }; - - addDocument = () => { - - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - rentalRequestSaved = () => { - Promise.all([ - this.fetch(), - Api.getRentalRequestRotationList(this.props.rentalRequestId), - ]); - }; - - openHireOfferDialog = (hireOffer, showAllResponseFields) => { - this.setState({ - rotationListHireOffer: hireOffer, - showAllResponseFields, - showHireOfferDialog: true, - }); - }; - - closeHireOfferDialog = () => { - this.setState({ showHireOfferDialog: false }); - }; - - hireOfferSaved = (hireOffer) => { - Log.rentalRequestEquipmentHired(this.props.rentalRequest, hireOffer.equipment, hireOffer.offerResponse); - - this.closeHireOfferDialog(); - - var rotationListItem = _.find(this.props.rentalRequest.rotationList, i => i.id === hireOffer.id); - if (rotationListItem && rotationListItem.rentalAgreementId && !hireOffer.rentalAgreementId) { - // navigate to rental agreement if it was newly generated - this.props.router.push({ pathname: `${ Constant.RENTAL_AGREEMENTS_PATHNAME }/${ rotationListItem.rentalAgreementId }` }); - } else { - // close popup dialog and refresh page data - this.fetch(); - } - }; - - downloadDoc = (promise, filename) => { - promise.then((response) => { - var blob; - if (window.navigator.msSaveBlob) { - blob = window.navigator.msSaveBlob(response, filename); - } else { - blob = new Blob([response], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'}); - } - //Create a link element, hide it, direct - //it towards the blob, and then 'click' it programatically - let a = document.createElement('a'); - a.style.cssText = 'display: none'; - document.body.appendChild(a); - //Create a DOMString representing the blob - //and point the link element towards it - let url = window.URL.createObjectURL(blob); - a.href = url; - a.download = filename; - //programatically click the link to trigger the download - a.click(); - //release the reference to the file by revoking the Object URL - window.URL.revokeObjectURL(url); - }); - }; - - printSeniorityList = () => { - var localAreaIds = [ this.props.rentalRequest.localAreaId ]; - var districtEquipmentTypeIds = [ this.props.rentalRequest.districtEquipmentTypeId ]; - var promise = Api.equipmentSeniorityListDoc(localAreaIds, districtEquipmentTypeIds); - var filename = 'SeniorityList-' + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + '.docx'; - this.downloadDoc(promise, filename); - }; - - addRequest = () => { - - }; - - renderStatusText = (listItem) => { - let text = 'Hire'; - if (listItem.offerResponse === STATUS_NO && listItem.offerRefusalReason == Constant.HIRING_REFUSAL_OTHER) { - text = listItem.offerResponseNote; - } else if (listItem.offerResponse == STATUS_NO) { - text = listItem.offerRefusalReason; - } else if (listItem.offerResponse === STATUS_ASKED) { - text = `${listItem.offerResponse} (${Moment(listItem.askedDateTime).format('YYYY-MM-DD hh:mm A')})`; - } else if (listItem.offerResponse === STATUS_FORCE_HIRE || listItem.offerResponse === STATUS_YES) { - text = listItem.offerResponse; - } - return text; - }; - - render() { - const { loading, loadingDocuments } = this.state; - var rentalRequest = this.props.rentalRequest || {}; - - var viewOnly = !rentalRequest.projectId; - var canEditRequest = !viewOnly && rentalRequest.status !== Constant.RENTAL_REQUEST_STATUS_CODE_COMPLETED; - - return
- - - - -
- -
- - - - -
- -
- -
- - - - - {(() => { - if (loading) { return
; } - - var requestAttachments = rentalRequest.rentalRequestAttachments && rentalRequest.rentalRequestAttachments[0] ? rentalRequest.rentalRequestAttachments[0].attachment : 'None'; - - return - - { rentalRequest.localAreaName } - - - - { concat(rentalRequest.projectPrimaryContactName, rentalRequest.projectPrimaryContactPhone, ', ') } - - - - { rentalRequest.equipmentTypeName } - - - { rentalRequest.equipmentCount } - - - { requestAttachments } - - - { rentalRequest.expectedHours } - - - { rentalRequest.project && rentalRequest.project.name } - - - { formatDateTime(rentalRequest.expectedStartDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - - { rentalRequest.project && rentalRequest.project.provincialProjectNumber } - - - { formatDateTime(rentalRequest.expectedEndDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - - ; - })()} -
- - - - - Hire Rotation List - - - - Seniority List - - Show Attachments - - {(() => { - if (loading) { return
; } - - var rotationList = this.props.rentalRequest.rotationList; - - if (Object.keys(rotationList || []).length === 0) { return No equipment; } - - // Sort in rotation list order - rotationList = _.sortBy(rotationList, 'rotationListSortOrder'); - - // use spans for table headers so we can force them to wrap when printing - var headers = [ - { field: 'seniorityString', title: 'Seniority' }, - { field: 'block', title: 'Blk' }, - { field: 'serviceHoursThisYear', node:
YTD Hours
}, - { field: 'equipmentCode', node:
Equip. ID
}, - { field: 'equipmentDetails', node:
Equip. Details
}, - { field: 'equipmentOwner', title: 'Owner' }, - { field: 'primaryContactName', title: 'Contact' }, - { field: 'primaryContactWorkPhone', node:
Phone
}, - { field: 'primaryContactCellPhone', node:
Cell Phone
}, - { field: 'status', title: 'Status' }, - { field: '', title: 'Comments' }, - ]; - - var numberEquipmentAvailableForNormalHire = rentalRequest.equipmentCount - rentalRequest.yesCount; - - return - { - _.map(rotationList, (listItem, i) => { - const owner = listItem.equipment.owner; - var showAllResponseFields = false; - if ((numberEquipmentAvailableForNormalHire > 0) && (listItem.offerResponse === STATUS_ASKED || !listItem.offerResponse) && (rentalRequest.yesCount < rentalRequest.equipmentCount)) { - showAllResponseFields = true; - numberEquipmentAvailableForNormalHire -= 1; - } - - const showBlankLine = i > 0 && rotationList[i - 1].equipment.blockNumber !== listItem.equipment.blockNumber; - - return [ - showBlankLine &&  , - - { listItem.equipment.seniorityString } - { listItem.equipment.blockNumber } - { listItem.equipment.hoursYtd } - { listItem.equipment.equipmentCode } - { listItem.equipment.equipmentDetails } - { this.state.showAttachments && -
- Attachments: - { listItem.equipment.equipmentAttachments && listItem.equipment.equipmentAttachments.map((item, i) => ( - - - { item.typeName } - { ((i + 1) < listItem.equipment.equipmentAttachments.length) && - , - } - - - ))} - { (!listItem.equipment.equipmentAttachments || listItem.equipment.equipmentAttachments.length === 0) && - none - } -
- } - - { owner && owner.organizationName } - { listItem.displayFields.primaryContactName } - { owner && owner.primaryContact && owner.primaryContact.workPhoneNumber } - { owner && owner.primaryContact && owner.primaryContact.mobilePhoneNumber } - - - {(() => { - const changeOfferWarningMessage = 'This piece of equipment is has met or ' + - 'exceeded its Maximum Allowed Hours for this year. Are you sure you want ' + - 'to edit the Offer on this equipment?'; - - const confirm = ( - this.openHireOfferDialog(listItem, showAllResponseFields) } - /> - ); - - if (listItem.maximumHours) { - return ( - - - - ); - } - if (!viewOnly && rentalRequest.status === STATUS_IN_PROGRESS && (listItem.offerResponse === STATUS_ASKED || !listItem.offerResponse)) { - return ( - - ); - } - return this.renderStatusText(listItem); - })()} - - - - , - ]; - }) - } -
; - })()} -
- - - - { rentalRequest.historyEntity && } - - { this.state.showEditDialog && ( - - )} - { this.state.showHireOfferDialog && ( - - )} - { this.state.showDocumentsDialog && ( - - )} - { this.state.showNotesDialog && - - } -
; - } -} - - -function mapStateToProps(state) { - return { - rentalRequest: activeRentalRequestSelector(state), - rentalRequestId: activeRentalRequestIdSelector(state), - documents: state.models.documents, - }; -} - -export default connect(mapStateToProps)(RentalRequestsDetail); diff --git a/client/src/js/views/Roles.jsx b/client/src/js/views/Roles.jsx deleted file mode 100644 index d6e05c8ba..000000000 --- a/client/src/js/views/Roles.jsx +++ /dev/null @@ -1,171 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon } from 'react-bootstrap'; -import { LinkContainer } from 'react-router-bootstrap'; -import _ from 'lodash'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import Confirm from '../components/Confirm.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import SearchControl from '../components/SearchControl.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -class Roles extends React.Component { - static propTypes = { - roles: PropTypes.object, - currentUser: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - - search: { - key: props.search.key || 'name', - text: props.search.text || '', - params: props.search.params || null, - }, - - ui : { - sortField: props.ui.sortField || 'name', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - componentDidMount() { - this.fetch(); - } - - fetch = () => { - this.setState({ loading: true }); - Api.searchRoles().finally(() => { - this.setState({ loading: false }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_ROLES_SEARCH, roles: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_ROLES_UI, roles: this.state.ui }); - if (callback) { callback(); } - }); - }; - - delete = (role) => { - Api.deleteRole(role).then(() => { - this.fetch(); - }); - }; - - render() { - var numRoles = this.state.loading ? '...' : Object.keys(this.props.roles).length; - - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ROLES_AND_PERMISSIONS) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - return
- Roles ({ numRoles }) - - - - - - - - - - - - - - - {(() => { - if (this.state.loading) { return
; } - - var addRoleButton = - - ; - if (Object.keys(this.props.roles).length === 0) { return No roles { addRoleButton }; } - - var roles = _.sortBy(_.filter(this.props.roles, role => { - if (!this.state.search.params) { - return true; - } - return role[this.state.search.key] && role[this.state.search.key].toLowerCase().indexOf(this.state.search.text.toLowerCase()) !== -1; - }), this.state.ui.sortField); - - if (this.state.ui.sortDesc) { - _.reverse(roles); - } - - return - { - _.map(roles, (role) => { - return - { role.name } - { role.description } - - - }> - - - - - - - - ; - }) - } - ; - })()} -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - roles: state.models.roles, - search: state.search.roles, - ui: state.ui.roles, - }; -} - -export default connect(mapStateToProps)(Roles); diff --git a/client/src/js/views/RolesDetail.jsx b/client/src/js/views/RolesDetail.jsx deleted file mode 100644 index 50fc5cd4c..000000000 --- a/client/src/js/views/RolesDetail.jsx +++ /dev/null @@ -1,266 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Grid, Row, Col } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import { Table, Button } from 'react-bootstrap'; -import _ from 'lodash'; -import Promise from 'bluebird'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import FormInputControl from '../components/FormInputControl.jsx'; -import Spinner from '../components/Spinner.jsx'; -import Form from '../components/Form.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { isBlank } from '../utils/string'; - - -class RolesDetail extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - role: PropTypes.object, - rolePermissions: PropTypes.object, - permissions: PropTypes.object, - params: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - - name: '', - description: '', - - nameError: '', - descriptionError: '', - - selectedPermissionIds: [], - - isNew: props.params.roleId === '0', - }; - } - - componentDidMount() { - if (this.state.isNew) { - // Clear the role and permissions store - store.dispatch({ type: Action.UPDATE_ROLE, role: {} }); - store.dispatch({ type: Action.UPDATE_ROLE_PERMISSIONS, rolePermissions: {} }); - } else { - this.fetch(); - } - } - - fetch = () => { - var rolePromise = Api.getRole(this.props.params.roleId); - var permissionsPromise = Api.getRolePermissions(this.props.params.roleId); - - this.setState({ loading: true }); - Promise.all([rolePromise, permissionsPromise]).then(() => { - var selectedPermissionIds = _.map(this.props.rolePermissions, rolePermission => { - return rolePermission.permission.id; - }); - this.setState({ - loading: false, - name: this.props.role.name, - description: this.props.role.description, - selectedPermissionIds: selectedPermissionIds, - }); - }); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - permissionClicked = (permission) => { - var selectedPermissionIds = _.clone(this.state.selectedPermissionIds); - if (selectedPermissionIds.indexOf(permission.id) === -1) { - selectedPermissionIds.push(permission.id); - } else { - _.pull(selectedPermissionIds, permission.id); - } - this.setState({ selectedPermissionIds: selectedPermissionIds }); - }; - - isValid = () => { - this.setState({ - nameError: false, - descriptionError: false, - }); - - var valid = true; - - if (isBlank(this.state.name)) { - this.setState({ nameError: 'Name is required' }); - valid = false; - } - - if (isBlank(this.state.description)) { - this.setState({ descriptionError: 'Description is required' }); - valid = false; - } - - return valid; - }; - - didChangeRole = () => { - if (this.state.name !== this.props.role.name) { return true; } - if (this.state.description !== this.props.role.description) { return true; } - - return false; - }; - - didChangePermissions = () => { - var originalPermissionIds = _.map(this.props.rolePermissions, rolePermission => { - return rolePermission.permission.id; - }); - if (_.xor(originalPermissionIds, this.state.selectedPermissionIds).length > 0) { return true; } - - return false; - }; - - savePermissions = () => { - if (this.didChangePermissions()) { - Api.updateRolePermissions(this.props.role.id, _.map(this.state.selectedPermissionIds, id => { - return { id: id }; - })).then(() => { - this.returnToList(); - }); - } else { - this.returnToList(); - } - }; - - returnToList = () => { - this.props.router.push({ - pathname: Constant.ROLES_PATHNAME, - }); - }; - - onSave = () => { - if (this.isValid()) { - if (this.didChangeRole()) { - if (this.state.isNew) { - Api.addRole({ - name: this.state.name, - description: this.state.description, - }).then(() => { - this.savePermissions(); - }); - } else { - Api.updateRole({ ...this.props.role, ...{ - name: this.state.name, - description: this.state.description, - }}).then(() => { - this.savePermissions(); - }); - } - } else { - this.savePermissions(); - } - } - }; - - render() { - var role = this.props.role; - - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_ROLES_AND_PERMISSIONS) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - return
-
- - -
- - {(() => { - if (this.state.loading) { return
; } - - return
- -
; - })()} - - {(() => { - if (this.state.loading) { return
; } - - return
- - - - - Name * - - { this.state.nameError } - - - - - Description * - - { this.state.descriptionError } - - - - -
; - })()} -
- - - {(() => { - if (this.state.loading ) { return
; } - - var permissions = _.sortBy(this.props.permissions, 'name'); - - return - - - - - - - - { - _.map(permissions, permission => { - var selected = this.state.selectedPermissionIds.indexOf(permission.id) !== -1; - return - - - ; - }) - } - -
NameDescription
{ permission.name }{ permission.description }
; - })()} -
- -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - role: state.models.role, - rolePermissions: state.models.rolePermissions, - permissions: state.lookups.permissions, - }; -} - -export default connect(mapStateToProps)(RolesDetail); diff --git a/client/src/js/views/Rollover.jsx b/client/src/js/views/Rollover.jsx deleted file mode 100644 index 17a2f7d1d..000000000 --- a/client/src/js/views/Rollover.jsx +++ /dev/null @@ -1,188 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Button, Well } from 'react-bootstrap'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import CheckboxControl from '../components/CheckboxControl.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import Confirm from '../components/Confirm.jsx'; -import Spinner from '../components/Spinner.jsx'; - -import { formatDateTimeUTCToLocal } from '../utils/date'; - - -class Rollover extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - rolloverStatus: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - checkListStep1: false, - checkListStep2: false, - checkListStep3: false, - refreshStatusTimerId: null, - }; - } - - componentDidMount() { - var user = this.props.currentUser; - var status = this.props.rolloverStatus; - - Api.getRolloverStatus(this.props.currentUser.district.id).then(() => { - this.setState({ loading: false }); - - if (!user.hasPermission(Constant.PERMISSION_DISTRICT_ROLLOVER) && !status.rolloverActive) { - // redirect to home page - this.props.router.push({ pathname: '/' }); - } - - if (status.rolloverActive && this.state.refreshStatusTimerId === null) { - this.startRefreshStatusTimer(); - } - }); - } - - componentDidUpdate() { - if (this.props.rolloverStatus.rolloverActive && this.state.refreshStatusTimerId === null) { - this.startRefreshStatusTimer(); - } - } - - startRefreshStatusTimer = () => { - var refreshStatusTimerId = setInterval(this.refreshStatus, 2000); // 2 seconds - this.setState({ refreshStatusTimerId: refreshStatusTimerId }); - }; - - refreshStatus = () => { - const districtId = this.props.currentUser.district.id; - - Api.getRolloverStatus(districtId).then(() => { - const status = this.props.rolloverStatus; - - if (!status.rolloverActive && this.state.refreshStatusTimerId !== null) { - clearInterval(this.state.refreshStatusTimerId); - this.setState({ refreshStatusTimerId: null }); - } - - if (status.rolloverComplete) { - // refresh fiscal years - Api.getFiscalYears(districtId); - } - }); - }; - - initiateRollover = () => { - Api.initiateRollover(this.props.currentUser.district.id); - }; - - dismissRolloverNotice = () => { - Api.dismissRolloverMessage(this.props.currentUser.district.id); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - renderContentRolloverActive = () => { - var status = this.props.rolloverStatus; - - return ( -
-
A roll over is currently in progress.
-
-
- { status.progressPercentage }% Complete -
-
-
- ); - }; - - renderContentRolloverComplete = () => { - return ( -
-

The hired equipment roll over has been completed on { formatDateTimeUTCToLocal(this.props.rolloverStatus.rolloverEndDate, Constant.DATE_TIME_READABLE) }.

-

Note: Please save/print out the new seniority lists for all equipments corresponding to each local area.

- -
- ); - }; - - renderContent = () => { - var rolloverButtonDisabled = !this.state.checkListStep1 || !this.state.checkListStep2 || !this.state.checkListStep3 || !this.state.checkListStep4; - - return ( - - -
- - Verify all equipment hours have been entered in the system - - - Save the seniority list (pre-roll over) - - - Take note of any equipment currently hired - - - Release all blocked rotation lists, as the hiring order may change after the roll over - -
- -
- Note: - The roll over is an important annual process that recalculates the seniority for each piece of equipment across the district at the start of a fiscal year. Once triggered, this process is not reversible. In case you have any questions, please contact the primary coordinator for the process before proceeding with the hired equipment roll over. -
- -
-

Please ensure all processes corresponding to the checklist are complete before rolling over.

If you are certain all tasks have been completed, click Yes to proceed with roll over. Otherwise, click No.

}> - -
-
-
- ); - }; - - render() { - var status = this.props.rolloverStatus; - var user = this.props.currentUser; - - return
- { user.districtName } Roll Over - -
- {(() => { - if (this.state.loading) { - return
; - } else if (status.rolloverActive) { - return this.renderContentRolloverActive(); - } else if (status.rolloverComplete) { - return this.renderContentRolloverComplete(); - } else { - return this.renderContent(); - } - })()} -
-
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - rolloverStatus: state.lookups.rolloverStatus, - }; -} - -export default connect(mapStateToProps)(Rollover); diff --git a/client/src/js/views/SeniorityList.jsx b/client/src/js/views/SeniorityList.jsx deleted file mode 100644 index dffb8b049..000000000 --- a/client/src/js/views/SeniorityList.jsx +++ /dev/null @@ -1,133 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Row, Col, ButtonToolbar, Button } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; - -import { formatDateTimeUTCToLocal } from '../utils/date'; - - -class SeniorityList extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - localAreas: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - selectedEquipmentTypeIds: [], - selectedLocalAreaIds: [], - }; - } - - componentDidMount() { - this.fetch(); - } - - fetch = () => { - Api.getDistrictEquipmentTypes(); - }; - - updateState = (state) => { - this.setState(state); - }; - - onLocalAreasChanged = () => { - this.setState({ selectedEquipmentTypeIds: [] }); - }; - - getFilteredEquipmentTypes = (localAreaIds) => { - return _.chain(this.props.districtEquipmentTypes.data) - .filter(type => type.equipmentCount > 0 && localAreaIds.length === 0 || _.filter(type.localAreas, localArea => _.includes(localAreaIds, localArea.id) && localArea.equipmentCount > 0).length > 0) - .sortBy('districtEquipmentName') - .value(); - }; - - downloadFile = (promise, filename, mimeType) => { - promise.then((response) => { - var blob; - if (window.navigator.msSaveBlob) { - blob = window.navigator.msSaveBlob(response, filename); - } else { - blob = new Blob([response], {type: mimeType}); - } - //Create a link element, hide it, direct - //it towards the blob, and then 'click' it programatically - let a = document.createElement('a'); - a.style.cssText = 'display: none'; - document.body.appendChild(a); - //Create a DOMString representing the blob - //and point the link element towards it - let url = window.URL.createObjectURL(blob); - a.href = url; - a.download = filename; - //programatically click the link to trigger the download - a.click(); - //release the reference to the file by revoking the Object URL - window.URL.revokeObjectURL(url); - }); - }; - - getRotationList = () => { - const promise = Api.equipmentSeniorityListDoc(this.state.selectedLocalAreaIds, this.state.selectedEquipmentTypeIds, false); - const filename = 'SeniorityList-' + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + '.docx'; - const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; - - this.downloadFile(promise, filename, mimeType); - }; - - render() { - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - var districtEquipmentTypes = this.getFilteredEquipmentTypes(this.state.selectedLocalAreaIds); - - return
- Seniority List - - - - - - - - - - - - -
; - } -} - - -function mapStateToProps(state) { - return { - currentUser: state.user, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - localAreas: state.lookups.localAreas, - }; -} - -export default connect(mapStateToProps)(SeniorityList); diff --git a/client/src/js/views/StatusLetters.jsx b/client/src/js/views/StatusLetters.jsx deleted file mode 100644 index aedd8aa42..000000000 --- a/client/src/js/views/StatusLetters.jsx +++ /dev/null @@ -1,153 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Row, Col, ButtonToolbar, Button } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; - -import { formatDateTimeUTCToLocal } from '../utils/date'; - - -class StatusLetters extends React.Component { - static propTypes = { - localAreas: PropTypes.object, - owners: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - localAreaIds: [], - ownerIds: [], - }; - } - - componentDidMount() { - Api.getOwnersLite(); - } - - updateState = (state, callback) => { - this.setState(state, () => { - if (callback) { callback(); } - }); - }; - - downloadFile = (promise, filename, mimeType) => { - promise.then((response) => { - var blob; - if (window.navigator.msSaveBlob) { - blob = window.navigator.msSaveBlob(response, filename); - } else { - blob = new Blob([response], {type: mimeType}); - } - //Create a link element, hide it, direct - //it towards the blob, and then 'click' it programatically - let a = document.createElement('a'); - a.style.cssText = 'display: none'; - document.body.appendChild(a); - //Create a DOMString representing the blob - //and point the link element towards it - let url = window.URL.createObjectURL(blob); - a.href = url; - a.download = filename; - //programatically click the link to trigger the download - a.click(); - //release the reference to the file by revoking the Object URL - window.URL.revokeObjectURL(url); - }); - }; - - getStatusLetters = () => { - const promise = Api.getStatusLettersDoc({ localAreas: this.state.localAreaIds, owners: this.state.ownerIds }); - const filename = 'StatusLetters-' + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + '.docx'; - const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; - - this.downloadFile(promise, filename, mimeType); - }; - - getMailingLabel = () => { - const promise = Api.getMailingLabelsDoc({ localAreas: this.state.localAreaIds, owners: this.state.ownerIds }); - const filename = 'MailingLabels-' + formatDateTimeUTCToLocal(new Date(), Constant.DATE_TIME_FILENAME) + '.docx'; - const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; - - this.downloadFile(promise, filename, mimeType); - }; - - matchesLocalAreaFilter = (localAreaId) => { - if (this.state.localAreaIds.length == 0) { - return true; - } - - return _.includes(this.state.localAreaIds, localAreaId); - }; - - updateLocalAreaState = (state) => { - this.updateState(state, this.filterSelectedOwners); - }; - - filterSelectedOwners = () => { - var acceptableOwnerIds = _.map(this.getFilteredOwners(), 'id'); - var ownerIds = _.intersection(this.state.ownerIds, acceptableOwnerIds); - this.updateState({ ownerIds: ownerIds }); - }; - - getFilteredOwners = () => { - return _.chain(this.props.owners.data) - .filter(x => this.matchesLocalAreaFilter(x.localAreaId)) - .sortBy('organizationName') - .value(); - }; - - render() { - var localAreas = _.sortBy(this.props.localAreas, 'name'); - var owners = this.getFilteredOwners(); - - return ( -
- Status Letters - - - - - - - - - - - - -
- ); - } -} - -function mapStateToProps(state) { - return { - localAreas: state.lookups.localAreas, - owners: state.lookups.owners.lite, - }; -} - -export default connect(mapStateToProps)(StatusLetters); diff --git a/client/src/js/views/TimeEntry.jsx b/client/src/js/views/TimeEntry.jsx deleted file mode 100644 index e75bebc46..000000000 --- a/client/src/js/views/TimeEntry.jsx +++ /dev/null @@ -1,381 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, Form } from 'react-bootstrap'; -import _ from 'lodash'; - -import TimeEntryDialog from './dialogs/TimeEntryDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import Favourites from '../components/Favourites.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { formatDateTime } from '../utils/date'; - - -class TimeEntry extends React.Component { - static propTypes = { - projects: PropTypes.object, - localAreas: PropTypes.object, - owners: PropTypes.object, - equipment: PropTypes.object, - timeEntries: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showTimeEntryDialog: false, - allowMultipleTimeEntries: false, - rentalAgreementId: null, - timeEntryDialogProjectId: null, - search: { - projectIds: props.search.projectIds || [], - localAreaIds: props.search.localAreaIds || [], - ownerIds: props.search.ownerIds || [], - equipmentIds: props.search.equipmentIds || [], - }, - ui : { - sortField: props.ui.sortField || 'localAreaLabel', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - componentDidMount() { - Api.getProjectsCurrentFiscal(); - Api.getEquipmentTs(); - Api.getOwnersLiteTs(); - - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.projectIds.length > 0) { - searchParams.projects = this.state.search.projectIds; - } - - if (this.state.search.localAreaIds.length > 0) { - searchParams.localAreas = this.state.search.localAreaIds; - } - - if (this.state.search.ownerIds.length > 0) { - searchParams.owners = this.state.search.ownerIds; - } - - if (this.state.search.equipmentIds.length > 0) { - searchParams.equipment = this.state.search.equipmentIds; - } - - return searchParams; - }; - - fetch = () => { - Api.searchTimeEntries(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - projectIds: [], - localAreaIds: [], - ownerIds: [], - equipmentIds: [], - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_TIME_ENTRIES_SEARCH, timeEntries: this.state.search }); - store.dispatch({ type: Action.CLEAR_TIME_ENTRIES }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_TIME_ENTRIES_SEARCH, timeEntries: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_TIME_ENTRIES_UI, timeEntries: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - openTimeEntryDialog = (timeEntry) => { - this.setState({ - timeEntryDialogProjectId: timeEntry ? timeEntry.projectId : null, - rentalAgreementId: timeEntry ? timeEntry.rentalAgreementId : null, - allowMultipleTimeEntries: !timeEntry, - showTimeEntryDialog: true, - }); - }; - - closeTimeEntryDialog = () => { - this.setState({ showTimeEntryDialog: false }); - if (this.props.timeEntries.loaded) { - this.fetch(); - } - }; - - renderResults = (addTimeEntryButton) => { - if (Object.keys(this.props.timeEntries.data).length === 0) { - return No time entries { addTimeEntryButton }; - } - - var timeEntries = _.sortBy(this.props.timeEntries.data, timeEntry => { - var sortValue = timeEntry[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(timeEntries); - } - - return - { - _.map(timeEntries, (entry) => { - return - { entry.localAreaLabel } - { entry.ownerCode } - { entry.ownerName } - { entry.equipmentCode } - { entry.equipmentDetails } - { entry.provincialProjectNumber ? entry.provincialProjectNumber : 'N/A' } - { entry.hours } - { formatDateTime(entry.workedDate, 'YYYY-MMM-DD') } - { formatDateTime(entry.enteredDate, 'YYYY-MMM-DD') } - - - - - - ; - }) - } - ; - }; - - matchesProjectFilter = (projectIds) => { - if (this.state.search.projectIds.length == 0) { - return true; - } - - return _.intersection(this.state.search.projectIds, projectIds).length > 0; - }; - - matchesLocalAreaFilter = (localAreaId) => { - if (this.state.search.localAreaIds.length == 0) { - return true; - } - - return _.includes(this.state.search.localAreaIds, localAreaId); - }; - - matchesOwnerFilter = (ownerId) => { - if (this.state.search.ownerIds.length == 0) { - return true; - } - - return _.includes(this.state.search.ownerIds, ownerId); - }; - - updateProjectSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedOwners); - }; - - updateLocalAreaSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedOwners); - }; - - updateOwnerSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedEquipment); - }; - - filterSelectedOwners = () => { - var acceptableOwnerIds = _.map(this.getFilteredOwners(), 'id'); - var ownerIds = _.intersection(this.state.search.ownerIds, acceptableOwnerIds); - this.updateSearchState({ ownerIds: ownerIds }, this.filterSelectedEquipment); - }; - - filterSelectedEquipment = () => { - var acceptableEquipmentIds = _.map(this.getFilteredEquipment(), 'id'); - var equipmentIds = _.intersection(this.state.search.equipmentIds, acceptableEquipmentIds); - this.updateSearchState({ equipmentIds: equipmentIds }); - }; - - getFilteredOwners = () => { - return _.chain(this.props.owners.data) - .filter(x => this.matchesProjectFilter(x.projectIds) && this.matchesLocalAreaFilter(x.localAreaId)) - .sortBy('organizationName') - .value(); - }; - - getFilteredEquipment = () => { - return _.chain(this.props.equipment.data) - .filter(x => this.matchesProjectFilter(x.projectIds) && this.matchesOwnerFilter(x.ownerId) && this.matchesLocalAreaFilter(x.localAreaId)) - .sortBy('equipmentCode') - .value(); - }; - - render() { - var resultCount = ''; - if (this.props.timeEntries.loaded) { - resultCount = '(' + Object.keys(this.props.timeEntries.data).length + ')'; - } - - var projects = _.sortBy(this.props.projects.data, 'name'); - var localAreas = _.sortBy(this.props.localAreas, 'name'); - var owners = this.getFilteredOwners(); - var equipment = this.getFilteredEquipment(); - - return
- Time Entry { resultCount } - - - - - -
- - - - - - - - - - - - - - - - - -
-
- - {(() => { - if (this.props.timeEntries.loading) { - return
; - } - - var addTimeEntryButton = ; - - if (this.props.timeEntries.loaded) { - return this.renderResults(addTimeEntryButton); - } - - return { addTimeEntryButton }; - })()} - { this.state.showTimeEntryDialog && ( - - )} -
; - } -} - - -function mapStateToProps(state) { - return { - projects: state.lookups.projectsCurrentFiscal, - localAreas: state.lookups.localAreas, - owners: state.lookups.owners.ts, - equipment: state.lookups.equipment.ts, - timeEntries: state.models.timeEntries, - favourites: state.models.favourites.timeEntry, - search: state.search.timeEntries, - ui: state.ui.timeEntries, - }; -} - -export default connect(mapStateToProps)(TimeEntry); diff --git a/client/src/js/views/TopNav.jsx b/client/src/js/views/TopNav.jsx deleted file mode 100644 index aaa50cb05..000000000 --- a/client/src/js/views/TopNav.jsx +++ /dev/null @@ -1,211 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import _ from 'lodash'; -import { Navbar, Nav, NavItem, NavDropdown, MenuItem, OverlayTrigger, Dropdown, Popover, Button, Glyphicon, ControlLabel, FormGroup } from 'react-bootstrap'; -import { LinkContainer } from 'react-router-bootstrap'; - -import * as Constant from '../constants'; -import * as Api from '../api'; - -import Spinner from '../components/Spinner.jsx'; -import DropdownControl from '../components/DropdownControl.jsx'; - -import { formatDateTimeUTCToLocal } from '../utils/date'; -import { currentPathStartsWith } from '../utils/routes'; - - -class TopNav extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - showWorkingIndicator: PropTypes.bool, - showNav: PropTypes.bool, - currentUserDistricts: PropTypes.object, - rolloverStatus: PropTypes.object, - }; - - static defaultProps = { - showNav: true, - }; - - updateUserDistrict = (state) => { - var district = _.find(this.props.currentUserDistricts.data, district => { return district.district.id === state.districtId; }); - Api.switchUserDistrict(district.id).then(() => { - location.reload(); - this.context.router.push({ pathname: Constant.HOME_PATHNAME }); - }); - }; - - logout = () => { - Api.logoffUser().then(logoffUrl => { - if (logoffUrl) { - window.location.href = logoffUrl; - } - }); - }; - - dismissRolloverNotice = () => { - Api.dismissRolloverMessage(this.props.currentUser.district.id); - }; - - render() { - var userDistricts = _.map(this.props.currentUserDistricts.data, district => { - return { ...district, districtName: district.district.name, id: district.district.id }; - }); - - var navigationDisabled = this.props.rolloverStatus.rolloverActive; - - var environmentClass = ''; - if (this.props.currentUser.environment === 'Development') { - environmentClass = 'env-dev'; - } else if (this.props.currentUser.environment === 'Test') { - environmentClass = 'env-test'; - }else if (this.props.currentUser.environment === 'Training') { - environmentClass = 'env-trn'; - }else if (this.props.currentUser.environment === 'UAT') { - environmentClass = 'env-uat'; - } - - return ; - } -} - -TopNav.contextTypes = { - router: PropTypes.object.isRequired, -}; - - -function mapStateToProps(state) { - return { - currentUser: state.user, - showWorkingIndicator: state.ui.requests.waiting, - currentUserDistricts: state.models.currentUserDistricts, - rolloverStatus: state.lookups.rolloverStatus, - }; -} - -export default connect(mapStateToProps, null, null, { pure: false })(TopNav); diff --git a/client/src/js/views/Users.jsx b/client/src/js/views/Users.jsx deleted file mode 100644 index df7c9a231..000000000 --- a/client/src/js/views/Users.jsx +++ /dev/null @@ -1,273 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup, Glyphicon, InputGroup, Form } from 'react-bootstrap'; -import { LinkContainer } from 'react-router-bootstrap'; -import _ from 'lodash'; - -import UsersEditDialog from './dialogs/UsersEditDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import AddButtonContainer from '../components/ui/AddButtonContainer.jsx'; -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import CheckboxControl from '../components/CheckboxControl.jsx'; -import Confirm from '../components/Confirm.jsx'; -import Favourites from '../components/Favourites.jsx'; -import FormInputControl from '../components/FormInputControl.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import Authorize from '../components/Authorize.jsx'; - -class Users extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - users: PropTypes.object, - user: PropTypes.object, - districts: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - showUsersEditDialog: false, - - search: { - selectedDistrictsIds: props.search.selectedDistrictsIds || [], - surname: props.search.surname || '', - hideInactive: props.search.hideInactive || true, - }, - - ui : { - sortField: props.ui.sortField || 'surname', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = { - includeInactive: !this.state.search.hideInactive, - surname: this.state.search.surname, - }; - - if (this.state.search.selectedDistrictsIds.length > 0) { - searchParams.districts = this.state.search.selectedDistrictsIds; - } - - return searchParams; - }; - - componentDidMount() { - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchUsers(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - selectedDistrictsIds: [], - surname: '', - hideInactive: true, - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_USERS_SEARCH, users: this.state.search }); - store.dispatch({ type: Action.CLEAR_USERS }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_USERS_SEARCH, users: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_USERS_UI, users: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - delete = (user) => { - Api.deleteUser(user).then(() => { - this.fetch(); - }); - }; - - openUsersEditDialog = () => { - this.setState({ showUsersEditDialog: true }); - }; - - closeUsersEditDialog = () => { - this.setState({ showUsersEditDialog: false }); - }; - - onUserSaved = (user) => { - this.closeUsersEditDialog(); - this.props.router.push({ - pathname: `${ Constant.USERS_PATHNAME }/${ user.id }`, - }); - }; - - renderResults = (addUserButton) => { - if (Object.keys(this.props.users.data).length === 0) { - return No users { addUserButton }; - } - - var users = _.sortBy(this.props.users.data, this.state.ui.sortField); - if (this.state.ui.sortDesc) { - _.reverse(users); - } - - return - { - _.map(users, (user) => { - return - { user.surname } - { user.givenName } - { user.smUserId } - { user.districtName } - - - - }> - - - - - - - - - ; - }) - } - ; - }; - - render() { - var districts = _.sortBy(this.props.districts, 'name'); - - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_USER_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - var resultCount = ''; - if (this.props.users.loaded) { - resultCount = '(' + Object.keys(this.props.users.data).length + ')'; - } - - return
- Users { resultCount } - - - - - -
- - - - - - Surname - - - Hide Inactive - - - - - - - - - - -
-
- - {(() => { - if (this.props.users.loading) { - return
; - } - - var addUserButton = ; - - if (this.props.users.loaded) { - return this.renderResults(addUserButton); - } - - return { addUserButton }; - })()} - - { this.state.showUsersEditDialog && - - } -
; - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - users: state.models.users, - user: state.models.user, - districts: state.lookups.districts, - favourites: state.models.favourites.user, - search: state.search.users, - ui: state.ui.users, - }; -} - -export default connect(mapStateToProps)(Users); diff --git a/client/src/js/views/UsersDetail.jsx b/client/src/js/views/UsersDetail.jsx deleted file mode 100644 index 007ce6696..000000000 --- a/client/src/js/views/UsersDetail.jsx +++ /dev/null @@ -1,450 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Row, Col, Alert, Label, Button, Glyphicon, Popover, FormGroup, HelpBlock, ButtonGroup } from 'react-bootstrap'; -import _ from 'lodash'; -import Promise from 'bluebird'; - -import UserRoleAddDialog from './dialogs/UserRoleAddDialog.jsx'; -import UsersEditDialog from './dialogs/UsersEditDialog.jsx'; -import DistrictEditDialog from './dialogs/DistrictEditDialog.jsx'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import CheckboxControl from '../components/CheckboxControl.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import DateControl from '../components/DateControl.jsx'; -import OverlayTrigger from '../components/OverlayTrigger.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import Confirm from '../components/Confirm.jsx'; -import TableControl from '../components/TableControl.jsx'; -import Form from '../components/Form.jsx'; -import PrintButton from '../components/PrintButton.jsx'; -import ReturnButton from '../components/ReturnButton.jsx'; -import SubHeader from '../components/ui/SubHeader.jsx'; -import Authorize from '../components/Authorize.jsx'; - -import { daysFromToday, formatDateTime, today, isValidDate, toZuluTime } from '../utils/date'; -import { isBlank, notBlank } from '../utils/string'; -import { sort, caseInsensitiveSort } from '../utils/array.js'; - - -class UsersDetail extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - user: PropTypes.object, - ui: PropTypes.object, - userDistricts: PropTypes.object, - districts: PropTypes.object, - params: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - - district: {}, - - showEditDialog: false, - showUserRoleDialog: false, - showDistrictEditDialog: false, - - ui: { - // User roles - sortField: props.ui.sortField || 'roleName', - sortDesc: props.ui.sortDesc === true, - showExpiredOnly: false, - }, - }; - } - - componentDidMount() { - // if new user - if (this.props.params.userId === '0') { - // Clear the user store - store.dispatch({ type: Action.UPDATE_USER, user: { - id: 0, - active: true, - district: { id: 0, name: '' }, - groupIds: [], - - }}); - // Open editor to add new user - this.openEditDialog(); - } else { - this.fetch(); - } - } - - componentWillReceiveProps(nextProps) { - if (this.props.params.userId !== nextProps.params.userId) { - this.fetch(); - } - } - - fetch = () => { - this.setState({ loading: true }); - Promise.all([ - Api.getUser(this.props.params.userId), - Api.getUserDistricts(this.props.params.userId), - ]).then(() => { - this.setState({ loading: false }); - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_USER_ROLES_UI, userRoles: this.state.ui }); - if (callback) { callback(); } - }); - }; - - openEditDialog = () => { - this.setState({ showEditDialog: true }); - }; - - closeEditDialog = () => { - this.setState({ showEditDialog: false }); - }; - - onUserSaved = () => { - this.closeEditDialog(); - }; - - onCloseEdit = () => { - this.closeEditDialog(); - if (this.props.params.userId === '0') { - // Go back to user list if cancelling new user - this.props.router.push({ - pathname: Constant.USERS_PATHNAME, - }); - } - }; - - openUserRoleDialog = () => { - this.setState({ showUserRoleDialog: true }); - }; - - closeUserRoleDialog = () => { - this.setState({ showUserRoleDialog: false }); - }; - - updateUserRole = (userRole) => { - // The API call updates all of the user's user roles so we have to - // include them all in this call, modifying the one that has just - // been expired. - var userRoles = this.props.user.userRoles.map(ur => { - return { - roleId: ur.roleId, - effectiveDate: ur.effectiveDate, - expiryDate: userRole.id === ur.id ? userRole.expiryDate : ur.expiryDate, - }; - }); - - Api.updateUserRoles(this.props.user.id, userRoles); - this.closeUserRoleDialog(); - }; - - openDistrictEditDialog = () => { - this.setState({ showDistrictEditDialog: true }); - }; - - closeDistrictEditDialog = () => { - this.setState({ showDistrictEditDialog: false }); - }; - - addUserDistrict = () => { - this.setState({ district: { id: 0 }, showDistrictEditDialog: true }); - }; - - editUserDistrict = (district) => { - this.setState({ district, showDistrictEditDialog: true }); - }; - - districtSaved = (district, districts) => { - this.updateCurrentUserDistricts(districts); - this.closeDistrictEditDialog(); - }; - - deleteDistrict = (district) => { - Api.deleteUserDistrict(district).then((response) => { - this.updateCurrentUserDistricts(response.data); - }); - }; - - updateCurrentUserDistricts = (districts) => { - if (this.props.user.id === this.props.currentUser.id) { - store.dispatch({ type: Action.CURRENT_USER_DISTRICTS, currentUserDistricts: districts }); - } - }; - - render() { - const { loading } = this.state; - const { user } = this.props; - - if (!this.props.currentUser.hasPermission(Constant.PERMISSION_USER_MANAGEMENT) && !this.props.currentUser.hasPermission(Constant.PERMISSION_ADMIN)) { - return ( -
You do not have permission to view this page.
- ); - } - - return
-
- - - {!loading && ( - - )} - - -
- - -
- -
- -
-

User: { loading ? '...' : user.fullName }

-
- - - - - - {(() => { - if (loading) { return
; } - - return - - { user.givenName } - - - { user.surname } - - - { user.smUserId } - - - { user.email } - - - { user.districtName } - - - { user.agreementCity } - - ; - })()} -
- -
- - - - - {(() => { - var addDistrictButton = ; - - if (loading) { return
; } - - if (this.props.userDistricts.data.length === 0) { return No Districts { addDistrictButton }; } - - const userDistricts = sort(this.props.userDistricts.data, ['isPrimary', 'district.name'], ['asc', 'asc'], caseInsensitiveSort); - - return ( - - { - _.map(userDistricts, (district) => { - return - { district.isPrimary && }{ district.district.name } - - { !district.isPrimary && - - - }> - - - - - - } - - ; - }) - } - - ); - })()} -
- -
- - - -

Access - Show Expired Only -

- {(() => { - if (loading ) { return
; } - - var addUserRoleButton = ; - - var userRoles = _.filter(user.userRoles, userRole => { - var include = notBlank(userRole.roleName); - if (this.state.ui.showExpiredOnly) { - include = include && userRole.expiryDate && daysFromToday(userRole.expiryDate) < 0; - } - return include; - }); - if (userRoles.length === 0) { return No roles { addUserRoleButton }; } - - userRoles = _.sortBy(userRoles, this.state.ui.sortField); - if (this.state.ui.sortDesc) { - _.reverse(userRoles); - } - - var headers = [ - { field: 'roleName', title: 'Role' }, - { field: 'effectiveDateSort', title: 'Effective Date' }, - { field: 'expiryDateSort', title: 'Expiry Date' }, - { field: 'addUserRole', title: 'Add User Role', style: { textAlign: 'right' }, - node: addUserRoleButton, - }, - ]; - - return - { - _.map(userRoles, (userRole) => { - return - { userRole.roleName } - { formatDateTime(userRole.effectiveDate, Constant.DATE_FULL_MONTH_DAY_YEAR) } - { formatDateTime(userRole.expiryDate, Constant.DATE_FULL_MONTH_DAY_YEAR) } -  { daysFromToday(userRole.expiryDate) < 0 ? : '' } - - - { - userRole.expiryDate ? null : - - } - > - - - - } - - ; - }) - } - ; - })()} -
- -
-
- { this.state.showEditDialog && ( - - )} - { this.state.showUserRoleDialog && ( - - )} - { this.state.showDistrictEditDialog && ( - - )} -
; - } -} - -class ExpireOverlay extends React.Component { - static propTypes = { - userRole: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - hide: PropTypes.func, - }; - - constructor(props) { - super(props); - - this.state = { - expiryDate: today(), - expiryDateError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - saveUserRole = () => { - this.setState({ expiryDateError: false }); - - if (isBlank(this.state.expiryDate)) { - this.setState({ expiryDateError: 'Expiry date is required' }); - } else if (!isValidDate(this.state.expiryDate)) { - this.setState({ expiryDateError: 'Expiry date not valid' }); - } else { - this.props.onSave({ ...this.props.userRole, ...{ - expiryDate: toZuluTime(this.state.expiryDate), - roleId: this.props.userRole.role.id, - }}); - this.props.hide(); - } - }; - - render() { - var props = _.omit(this.props, 'onSave', 'hide', 'userRole'); - return -
- - - { this.state.expiryDateError } - - -
-
; - } -} - - - -function mapStateToProps(state) { - return { - currentUser: state.user, - user: state.models.user, - ui: state.ui.userRoles, - userDistricts: state.models.userDistricts, - districts: state.lookups.districts, - }; -} - -export default connect(mapStateToProps)(UsersDetail); diff --git a/client/src/js/views/Version.jsx b/client/src/js/views/Version.jsx deleted file mode 100644 index 82f4e757f..000000000 --- a/client/src/js/views/Version.jsx +++ /dev/null @@ -1,146 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Well, Button, Glyphicon } from 'react-bootstrap'; - -import * as Api from '../api'; -import * as Constant from '../constants'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import ColDisplay from '../components/ColDisplay.jsx'; -import Spinner from '../components/Spinner.jsx'; -import Unimplemented from '../components/Unimplemented.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { formatDateTime } from '../utils/date'; -import { request } from '../utils/http'; - - -class Version extends React.Component { - static propTypes = { - version: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - showRawSection: false, - buildtime : '', - version : '', - commit : '', - }; - } - - componentDidMount() { - this.setState({ loading: true }); - Api.getVersion().finally(() => { - this.fetchLocal().finally(() => { - this.setState({ loading: false }); - }); - }); - } - - fetchLocal = () => { - return request('buildinfo.html', { silent: true }).then(xhr => { - if (xhr.status === 200) { - const parser = new DOMParser(); - const doc = parser.parseFromString(xhr.responseText, 'text/html'); - - this.setState({ - buildTime : doc.getElementById('buildtime').dataset.buildtime, - version : doc.getElementById('version').textContent, - commit : doc.getElementById('commit').textContent, - }); - } - }).catch(err => { - console.err('Failed to find buildinfo: ', err); - }); - }; - - showRaw = (e) => { - if (this.state.showRawSection) { - this.setState({ showRawSection: false }); - e.target.textContent = 'Show Raw Versions'; - } else { - this.setState({ showRawSection: true }); - e.target.textContent = 'Hide Raw Versions'; - } - }; - - email = () => { - - }; - - render() { - return
- Version -
- - - - -
-
- - {(() => { - if (this.state.loading) { return
; } - - var applicationVersion = {}; - if (this.props.version.applicationVersions && this.props.version.applicationVersions.length > 0) { - applicationVersion = this.props.version.applicationVersions[0]; - } - var databaseVersion = {}; - if (this.props.version.databaseVersions && this.props.version.databaseVersions.length > 0) { - databaseVersion = this.props.version.databaseVersions[0]; - } - - return
- -

Client

-
- MOTI Hired Equipment Tracking System - { formatDateTime(this.state.buildTime, Constant.DATE_TIME_READABLE) } - { navigator.userAgent } -
-
- -

Application

-
- { applicationVersion.title } - { formatDateTime(applicationVersion.fileCreationTime, Constant.DATE_TIME_READABLE) } - { applicationVersion.informationalVersion } - { applicationVersion.targetFramework } - { applicationVersion.buildVersion } - { applicationVersion.environment } -
-
- -

Database

-
- { databaseVersion.database } - { databaseVersion.server } - { databaseVersion.version } - { databaseVersion.buildVersion } - { databaseVersion.environment } -
-
- - -
{ JSON.stringify(this.props.version) }
-
-
; - })()} -
; - } -} - - -function mapStateToProps(state) { - return { - version: state.version, - }; -} - -export default connect(mapStateToProps)(Version); diff --git a/client/src/js/views/WcbCglCoverage.jsx b/client/src/js/views/WcbCglCoverage.jsx deleted file mode 100644 index a88dd7e64..000000000 --- a/client/src/js/views/WcbCglCoverage.jsx +++ /dev/null @@ -1,288 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Link } from 'react-router'; -import { Alert, Row, Col, ButtonToolbar, Button, ButtonGroup } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; - -import * as Action from '../actionTypes'; -import * as Api from '../api'; -import * as Constant from '../constants'; -import store from '../store'; - -import PageHeader from '../components/ui/PageHeader.jsx'; -import SearchBar from '../components/ui/SearchBar.jsx'; -import DateControl from '../components/DateControl.jsx'; -import Favourites from '../components/Favourites.jsx'; -import Form from '../components/Form.jsx'; -import MultiDropdown from '../components/MultiDropdown.jsx'; -import SortTable from '../components/SortTable.jsx'; -import Spinner from '../components/Spinner.jsx'; -import PrintButton from '../components/PrintButton.jsx'; - -import { formatDateTime, toZuluTime } from '../utils/date'; - - -class WcbCglCoverage extends React.Component { - static propTypes = { - localAreas: PropTypes.object, - owners: PropTypes.object, - ownersCoverage: PropTypes.object, - favourites: PropTypes.object, - search: PropTypes.object, - ui: PropTypes.object, - router: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: true, - search: { - localAreaIds: props.search.localAreaIds || [], - ownerIds: props.search.ownerIds || [], - wcbExpiry: props.search.wcbExpiry || '', - cglExpiry: props.search.cglExpiry || '', - }, - ui : { - sortField: props.ui.sortField || 'localAreaLabel', - sortDesc: props.ui.sortDesc === true, - }, - }; - } - - buildSearchParams = () => { - var searchParams = {}; - - if (this.state.search.localAreaIds.length > 0) { - searchParams.localAreas = this.state.search.localAreaIds; - } - - if (this.state.search.ownerIds.length > 0) { - searchParams.owners = this.state.search.ownerIds; - } - - var wcbExpiryDate = Moment(this.state.search.wcbExpiry); - if (wcbExpiryDate && wcbExpiryDate.isValid()) { - searchParams.wcbExpiry = toZuluTime(wcbExpiryDate.startOf('day')); - } - - var cglExpiryDate = Moment(this.state.search.cglExpiry); - if (cglExpiryDate && cglExpiryDate.isValid()) { - searchParams.cglExpiry = toZuluTime(cglExpiryDate.startOf('day')); - } - - return searchParams; - }; - - componentDidMount() { - Api.getOwnersLite(); - - // If this is the first load, then look for a default favourite - if (_.isEmpty(this.props.search)) { - var defaultFavourite = _.find(this.props.favourites, f => f.isDefault); - if (defaultFavourite) { - this.loadFavourite(defaultFavourite); - } - } - } - - fetch = () => { - Api.searchOwnersCoverage(this.buildSearchParams()); - }; - - search = (e) => { - e.preventDefault(); - this.fetch(); - }; - - clearSearch = () => { - var defaultSearchParameters = { - localAreaIds: [], - ownerIds: [], - wcbExpiry: '', - cglExpiry: '', - }; - - this.setState({ search: defaultSearchParameters }, () => { - store.dispatch({ type: Action.UPDATE_OWNERS_COVERAGE_SEARCH, ownersCoverage: this.state.search }); - store.dispatch({ type: Action.CLEAR_OWNERS_COVERAGE }); - }); - }; - - updateSearchState = (state, callback) => { - this.setState({ search: { ...this.state.search, ...state, ...{ loaded: true } }}, () =>{ - store.dispatch({ type: Action.UPDATE_OWNERS_COVERAGE_SEARCH, ownersCoverage: this.state.search }); - if (callback) { callback(); } - }); - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_OWNERS_COVERAGE_UI, ownersCoverage: this.state.ui }); - if (callback) { callback(); } - }); - }; - - loadFavourite = (favourite) => { - this.updateSearchState(JSON.parse(favourite.value), this.fetch); - }; - - renderResults = () => { - if (Object.keys(this.props.ownersCoverage.data).length === 0) { - return No results; - } - - var ownersCoverage = _.sortBy(this.props.ownersCoverage.data, entry => { - var sortValue = entry[this.state.ui.sortField]; - if (typeof sortValue === 'string') { - return sortValue.toLowerCase(); - } - return sortValue; - }); - - if (this.state.ui.sortDesc) { - _.reverse(ownersCoverage); - } - - return - { - _.map(ownersCoverage, (entry) => { - return - { entry.localAreaLabel } - { entry.ownerCode } - { entry.organizationName } - { entry.primaryContactNumber } - { entry.primaryContactCell } - { entry.wcbNumber } - { formatDateTime(entry.wcbExpiryDate, 'YYYY-MMM-DD') } - { entry.cglNumber } - { formatDateTime(entry.cglExpiryDate, 'YYYY-MMM-DD') } - ; - }) - } - ; - }; - - matchesLocalAreaFilter = (localAreaId) => { - if (this.state.search.localAreaIds.length == 0) { - return true; - } - - return _.includes(this.state.search.localAreaIds, localAreaId); - }; - - updateLocalAreaSearchState = (state) => { - this.updateSearchState(state, this.filterSelectedOwners); - }; - - filterSelectedOwners = () => { - var acceptableOwnerIds = _.map(this.getFilteredOwners(), 'id'); - var ownerIds = _.intersection(this.state.search.ownerIds, acceptableOwnerIds); - this.updateSearchState({ ownerIds: ownerIds }, this.filterSelectedEquipment); - }; - - getFilteredOwners = () => { - return _.chain(this.props.owners.data) - .filter(x => this.matchesLocalAreaFilter(x.localAreaId)) - .sortBy('organizationName') - .value(); - }; - - render() { - var resultCount = ''; - if (this.props.ownersCoverage.loaded) { - resultCount = '(' + Object.keys(this.props.ownersCoverage.data).length + ')'; - } - - var localAreas = _.sortBy(this.props.localAreas, 'name'); - var owners = this.getFilteredOwners(); - - return
- WCB / CGL Coverage { resultCount } - - - - - -
- - - - - - - - - - - - - - - - - -
-
- - {(() => { - if (this.props.ownersCoverage.loading) { - return
; - } - if (this.props.ownersCoverage.loaded) { - return this.renderResults(); - } - })()} -
; - } -} - -function mapStateToProps(state) { - return { - localAreas: state.lookups.localAreas, - owners: state.lookups.owners.lite, - ownersCoverage: state.models.ownersCoverage, - favourites: state.models.favourites.ownersCoverage, - search: state.search.ownersCoverage, - ui: state.ui.ownersCoverage, - }; -} - -export default connect(mapStateToProps)(WcbCglCoverage); diff --git a/client/src/js/views/dialogs/AttachmentAddDialog.jsx b/client/src/js/views/dialogs/AttachmentAddDialog.jsx deleted file mode 100644 index c3dbd89b3..000000000 --- a/client/src/js/views/dialogs/AttachmentAddDialog.jsx +++ /dev/null @@ -1,153 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - -class AttachmentAddDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - equipment: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - forms: [{ - typeName: '', - attachmentError: '', - }], - }; - } - - updateState = (state, index) => { - const forms = this.state.forms.slice(); - - forms[index].typeName = state.typeName; - - this.setState({forms}); - }; - - didChange = () => { - if (this.state.typeName !== '') { return true; } - - return false; - }; - - isValid = () => { - const forms = this.state.forms.slice(); - - var valid = false; - - forms.forEach((form) => { - const formIsValid = !isBlank(form.typeName); - - form.attachmentError = formIsValid ? '' : 'Attachment is required'; - - valid = formIsValid; - }); - - this.setState({forms}); - - return valid; - }; - - addInput = () => { - if (this.state.forms.length < 10) { - const forms = this.state.forms.slice(); // shallow clone - - forms.push({ - typeName: '', - attachmentError: '', - }); - - this.setState({forms}); - } - }; - - removeInput = () => { - if (this.state.forms.length > 1) { - let forms = this.state.forms.slice(); - forms.splice(forms.length - 1, 1); - this.setState({forms}); - } - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const attachmentTypeNames = this.state.forms.map((form) => form.typeName); - - const promise = Api.addPhysicalAttachments(this.props.equipment.id, attachmentTypeNames); - - promise.then(() => { - attachmentTypeNames.forEach((typeName) => { - Log.equipmentAttachmentAdded(this.props.equipment, typeName); - }); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - const { forms } = this.state; - - return ( - -
- { forms.map((form, i) => ( - - Attachment - this.updateState(state, i) }/> - { form.attachmentError } - - ))} -
-
- { forms.length > 1 && ( - - )} - { forms.length < 10 && ( - - )} -
-
- ); - } -} - -export default AttachmentAddDialog; diff --git a/client/src/js/views/dialogs/AttachmentEditDialog.jsx b/client/src/js/views/dialogs/AttachmentEditDialog.jsx deleted file mode 100644 index b2c25c146..000000000 --- a/client/src/js/views/dialogs/AttachmentEditDialog.jsx +++ /dev/null @@ -1,102 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -class AttachmentEditDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - equipment: PropTypes.object.isRequired, - attachment: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - typeName: props.attachment.typeName, - concurrencyControlNumber: props.attachment.concurrencyControlNumber || 0, - attachmentError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.typeName !== '') { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - attachmentError: '', - }); - - var valid = true; - - if (this.state.typeName === '') { - this.setState({ attachmentError: 'Attachment is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const attachment = { - id: this.props.attachment.id, - typeName: this.state.typeName, - concurrencyControlNumber: this.state.concurrencyControlNumber, - equipment: { id: this.props.equipment.id }, - }; - - const promise = Api.updatePhysicalAttachment(attachment); - - promise.then(() => { - Log.equipmentAttachmentUpdated(this.props.equipment, attachment.typeName); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - return ( - - - Attachment - - { this.state.attachmentError } - - - ); - } -} - -export default AttachmentEditDialog; diff --git a/client/src/js/views/dialogs/CloneDialog.jsx b/client/src/js/views/dialogs/CloneDialog.jsx deleted file mode 100644 index 5051e6367..000000000 --- a/client/src/js/views/dialogs/CloneDialog.jsx +++ /dev/null @@ -1,184 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; - -import _ from 'lodash'; -import Promise from 'bluebird'; - -import { Row, Col, Radio, Alert, FormGroup, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import FormDialog from '../../components/FormDialog.jsx'; -import TableControl from '../../components/TableControl.jsx'; -import DropdownControl from '../../components/DropdownControl.jsx'; -import Spinner from '../../components/Spinner.jsx'; - -import { formatDateTime } from '../../utils/date'; - -class CloneDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - rentalAgreement: PropTypes.object, - projectRentalAgreements: PropTypes.object, - equipmentRentalAgreements: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - cloneRentalAgreementError: '', - loading: false, - rentalAgreementId: '', - type: Constant.BY_PROJECT, - }; - } - - componentDidMount() { - var getProjectRentalAgreementsPromise = Api.getProjectRentalAgreements(this.props.rentalAgreement.project.id); - var getEquipmentRentalAgreementsPromise = Api.getEquipmentRentalAgreements(this.props.rentalAgreement.equipment.id); - this.setState({ loading: true }); - return Promise.all([getProjectRentalAgreementsPromise, getEquipmentRentalAgreementsPromise]).finally(() => { - this.setState({ loading: false }); - }); - } - - updateState = (e) => { - this.setState({ [e.target.name]: e.target.value }); - }; - - updateDropdownState = (state) => { - this.setState(state); - }; - - didChange = () => { - if (this.state.rentalAgreementId !== '') { return true; } - - return false; - }; - - isValid = () => { - return true; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var data = { - projectId: this.props.rentalAgreement.project.id, - agreementToCloneId: parseInt(this.state.rentalAgreementId, 10), - rentalAgreementId: this.props.rentalAgreement.id, - equipmentId: this.props.rentalAgreement.equipmentId, - }; - - const promise = this.state.type === Constant.BY_EQUIPMENT ? Api.cloneEquipmentRentalAgreement(data) : Api.cloneProjectRentalAgreement(data); - - promise.then(() => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.onClose(); - }).catch((error) => { - if (error.status === 400 && (error.errorCode === 'HETS-11' || error.errorCode === 'HETS-12' || error.errorCode === 'HETS-13')) { - this.setState({ isSaving: false, cloneRentalAgreementError: 'There was an error cloning the rental agreement.' }); - } else { - throw error; - } - }); - } else { - this.onClose(); - } - } - }; - - onClose = () => { - this.setState({ cloneRentalAgreementError: '' }); - this.props.onClose(); - }; - - render() { - var headers = [ - { field: 'blank' }, - { field: 'equipmentId', title: 'Equipment ID' }, - { field: 'equipmentType', title: 'Equipment Type' }, - { field: 'equipmentMakeModelSize', title: 'Year Make/Model/Size' }, - { field: 'projectName', title: 'Project Name' }, - { field: 'rentalAgreementNumber', title: 'Rental Agreement #' }, - { field: 'datedOn', title: 'Dated On' }, - ]; - - var rentalAgreements = _.filter(this.state.type === Constant.BY_PROJECT ? - this.props.projectRentalAgreements.data : this.props.equipmentRentalAgreements.data, item => { - return item.id !== this.props.rentalAgreement.id; - }); - - rentalAgreements = _.reverse(_.sortBy(rentalAgreements, function(rentalAgreement) { - return rentalAgreement.datedOn; - })); - - return ( - - - - - Rental Agreements - - -

Select a rental agreement to clone...

- {(() => { - if (this.state.loading) { return
; } - - if (!rentalAgreements || Object.keys(rentalAgreements).length === 0) { return No rental agreements.; } - - return ( - - { - _.map(rentalAgreements, (rentalAgreement) => { - return - - { rentalAgreement.equipment.equipmentCode } - { rentalAgreement.equipment.districtEquipmentType.districtEquipmentName } - {`${rentalAgreement.equipment.year} ${rentalAgreement.equipment.make}/${rentalAgreement.equipment.model}/${rentalAgreement.equipment.size}`} - { rentalAgreement.project && rentalAgreement.project.name } - { rentalAgreement.number } - { formatDateTime(rentalAgreement.datedOn, 'YYYY-MMM-DD') } - ; - }) - } - - ); - })()} - { this.state.cloneRentalAgreementError && - { this.state.cloneRentalAgreementError } - } - -
-
- ); - } -} - -function mapStateToProps(state) { - return { - projectRentalAgreements: state.models.projectRentalAgreements, - equipmentRentalAgreements: state.models.equipmentRentalAgreements, - }; -} - -export default connect(mapStateToProps)(CloneDialog); diff --git a/client/src/js/views/dialogs/ConditionAddEditDialog.jsx b/client/src/js/views/dialogs/ConditionAddEditDialog.jsx deleted file mode 100644 index 3a38a3267..000000000 --- a/client/src/js/views/dialogs/ConditionAddEditDialog.jsx +++ /dev/null @@ -1,139 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; - -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - - -class ConditionAddEditDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - condition: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - isNew: props.condition.id === 0, - - conditionId: props.condition.id, - typeCode: props.condition.conditionTypeCode || '', - description: props.condition.description || '', - concurrencyControlNumber: props.condition.concurrencyControlNumber || 0, - typeCodeError: '', - descriptionError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.isNew && this.state.typeCode !== '') { return true; } - if (this.state.isNew && this.state.description !== '') { return true; } - if (!this.state.isNew && this.state.typeCode !== this.props.condition.conditionTypeCode) { return true; } - if (!this.state.isNew && this.state.description !== this.props.condition.description) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - typeCodeError: '', - descriptionError: '', - }); - - var valid = true; - - if (this.state.typeCode === '') { - this.setState({ typeCodeError: 'Condition type code is required' }); - valid = false; - } - - if (this.state.description === '') { - this.setState({ descriptionError: 'Description is required' }); - valid = false; - } - - return valid; - }; - - onSave = () => { - this.props.onSave({ - id: this.state.conditionId, - conditionTypeCode: this.state.typeCode, - description: this.state.description, - concurrencyControlNumber: this.state.concurrencyControlNumber, - active: true, - }); - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const condition = { - id: this.state.conditionId, - conditionTypeCode: this.state.typeCode, - description: this.state.description, - concurrencyControlNumber: this.state.concurrencyControlNumber, - active: true, - district: { id: this.props.currentUser.district.id }, - }; - - const promise = this.state.isNew ? Api.addCondition(condition) : Api.updateCondition(condition); - - promise.then(() => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - return ( - - - Type Code * - - { this.state.typeCodeError } - - - Description * - - { this.state.descriptionError } - - - ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - }; -} - -export default connect(mapStateToProps)(ConditionAddEditDialog); diff --git a/client/src/js/views/dialogs/ConfirmDialog.jsx b/client/src/js/views/dialogs/ConfirmDialog.jsx deleted file mode 100644 index 271508893..000000000 --- a/client/src/js/views/dialogs/ConfirmDialog.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import FormDialog from '../../components/FormDialog.jsx'; - -class ConfirmDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - title: PropTypes.string, - saveText: PropTypes.string, - closeText: PropTypes.string, - children: PropTypes.node, - }; - - render() { - return ( - - { this.props.children } - - ); - } -} - -export default ConfirmDialog; diff --git a/client/src/js/views/dialogs/ConfirmForceHireDialog.jsx b/client/src/js/views/dialogs/ConfirmForceHireDialog.jsx deleted file mode 100644 index c848c4589..000000000 --- a/client/src/js/views/dialogs/ConfirmForceHireDialog.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Grid, Row, Col, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - - -class ConfirmForceHireDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - reasonForForceHire: '', - }; - } - - componentDidMount() { - this.input && this.input.focus(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - return true; - }; - - isValid = () => { - this.setState({ - noteError: '', - }); - - var valid = true; - - if (isBlank(this.state.reasonForForceHire) ) { - this.setState({ reasonForForceHireError: 'Reason is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - this.props.onSave(this.state.reasonForForceHire); - }; - - render() { - return ( - - - -

Are you sure you want to do a Force Hire?

- - - - - Reason for Force Hire - - { this.state.reasonForForceHireError } - - - -
-
- ); - } -} - -export default connect()(ConfirmForceHireDialog); diff --git a/client/src/js/views/dialogs/ContactsEditDialog.jsx b/client/src/js/views/dialogs/ContactsEditDialog.jsx deleted file mode 100644 index c115ffe70..000000000 --- a/client/src/js/views/dialogs/ContactsEditDialog.jsx +++ /dev/null @@ -1,273 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { connect } from 'react-redux'; - -import { Grid, Row, Col, Button, Label } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Constant from '../../constants'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank, formatPhoneNumber } from '../../utils/string'; - - -class ContactsEditDialog extends React.Component { - static propTypes = { - contact: PropTypes.object.isRequired, - parent: PropTypes.object.isRequired, - saveContact: PropTypes.func.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - defaultPrimary: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isNew: props.contact.id === 0, - - isSaving: false, - - givenName: props.contact.givenName || '', - surname: props.contact.surname || '', - role: props.contact.role || '', - notes: props.contact.notes || '', - emailAddress: props.contact.emailAddress || '', - workPhoneNumber: props.contact.workPhoneNumber || '', - mobilePhoneNumber: props.contact.mobilePhoneNumber || '', - faxPhoneNumber: props.contact.faxPhoneNumber || '', - isPrimary: props.contact.isPrimary || props.defaultPrimary || false, - - givenNameError: false, - emailAddressError: false, - workPhoneNumberError: false, - mobilePhoneNumberError: false, - faxPhoneNumberError: false, - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - makePrimary = () => { - this.setState({ isPrimary: true }); - }; - - didChange = () => { - if (this.state.givenName !== this.props.contact.givenName) { return true; } - if (this.state.surname !== this.props.contact.surname) { return true; } - if (this.state.organizationName !== this.props.contact.organizationName) { return true; } - if (this.state.role !== this.props.contact.role) { return true; } - if (this.state.notes !== this.props.contact.notes) { return true; } - if (this.state.emailAddress !== this.props.contact.emailAddress) { return true; } - if (this.state.workPhoneNumber !== this.props.contact.workPhoneNumber) { return true; } - if (this.state.mobilePhoneNumber !== this.props.contact.mobilePhoneNumber) { return true; } - if (this.state.faxPhoneNumber !== this.props.contact.faxPhoneNumber) { return true; } - if (this.state.isPrimary !== this.props.contact.isPrimary) { return true; } - - return false; - }; - - isValidPhoneNumber = (number) => { - if (isBlank(number)) { - return true; - } - return Constant.NANP_REGEX.test(number) && formatPhoneNumber(number).length <= Constant.MAX_LENGTH_PHONE_NUMBER; - }; - - isValid = () => { - this.setState({ - givenNameError: false, - emailAddressError: false, - workPhoneNumberError: false, - mobilePhoneNumberError: false, - faxPhoneNumberError: false, - }); - - var valid = true; - - if (isBlank(this.state.givenName)) { - this.setState({ givenNameError: 'Given name is required' }); - valid = false; - } - - // Check the phone numbers against the North American Numbering Plan format. We basically want to - // make sure that there's the right number of digits to make an actual phone number. Note for testers: - // an area code and an exchange code cannot start with 0 or 1. - if (!this.isValidPhoneNumber(this.state.workPhoneNumber)) { - this.setState({ workPhoneNumberError: 'Invalid phone number' }); - valid = false; - } - - if (!this.isValidPhoneNumber(this.state.mobilePhoneNumber)) { - this.setState({ mobilePhoneNumberError: 'Invalid phone number' }); - valid = false; - } - - if (!this.isValidPhoneNumber(this.state.faxPhoneNumber)) { - this.setState({ faxPhoneNumberError: 'Invalid phone number' }); - valid = false; - } - - if (!isBlank(this.state.emailAddress) && !Constant.EMAIL_REGEX.test(this.state.emailAddress)) { - // Just a simple RegEx test for X@Y.Z - this.setState({ emailAddressError: 'Invalid email' }); - valid = false; - } - - // A Primary Contact requires at least one of the phone/email fields to be filled out. - if (this.state.isPrimary && isBlank(this.state.workPhoneNumber) && isBlank(this.state.mobilePhoneNumber) && isBlank(this.state.emailAddress)) { - this.setState({ - workPhoneNumberError: 'A primary contact requires a phone number or email address', - mobilePhoneNumberError: ' ', - emailAddressError: ' ', - }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - const { isNew } = this.state; - - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const contact = { - ...this.props.contact, - givenName: this.state.givenName, - surname: this.state.surname, - role: this.state.role, - notes: this.state.notes, - emailAddress: this.state.emailAddress, - workPhoneNumber: formatPhoneNumber(this.state.workPhoneNumber), - mobilePhoneNumber: formatPhoneNumber(this.state.mobilePhoneNumber), - faxPhoneNumber: formatPhoneNumber(this.state.faxPhoneNumber), - isPrimary: this.state.isPrimary, - }; - - this.props.saveContact(this.props.parent, contact).then((savedContact) => { - this.setState({ isSaving: false }); - this.props.onSave(savedContact); - }); - - if (!isNew) { // can be closed right away if it isn't new - this.props.onClose(); - } - } - } - }; - - render() { - // Read-only if the user cannot edit the contact - var isReadOnly = !this.props.contact.canEdit && this.props.contact.id !== 0; - - const dialogTitle = ( - - Contact - { this.state.isPrimary ? - : - - } - - ); - - return ( - - - - - - Given Name * - - { this.state.givenNameError } - - - - - - - Surname - - - - - - - - Role - - - - - - - - Phone {this.state.isPrimary && *} - - { this.state.workPhoneNumberError } - - - - - - - Cell Phone {this.state.isPrimary && *} - - { this.state.mobilePhoneNumberError } - - - - - - - Fax - - { this.state.faxPhoneNumberError } - - - - - - - Email {this.state.isPrimary && *} - - { this.state.emailAddressError } - - - - - - - Notes - - - - - - - ); - } -} - -function mapStateToProps(state) { - return { - contactz: state.models.contact, - }; -} - -export default connect(mapStateToProps)(ContactsEditDialog); diff --git a/client/src/js/views/dialogs/DistrictEditDialog.jsx b/client/src/js/views/dialogs/DistrictEditDialog.jsx deleted file mode 100644 index 42c000796..000000000 --- a/client/src/js/views/dialogs/DistrictEditDialog.jsx +++ /dev/null @@ -1,128 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import _ from 'lodash'; -import { FormGroup, HelpBlock } from 'react-bootstrap'; - -import * as Api from '../../api'; - -import FormDialog from '../../components/FormDialog.jsx'; -import CheckboxControl from '../../components/CheckboxControl.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; - - -class DistrictEditDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - districts: PropTypes.object, - user: PropTypes.object, - district: PropTypes.object, - userDistricts: PropTypes.array, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - var isNew = props.district.id === 0; - - this.state = { - isNew: isNew, - isSaving: false, - - districtId: isNew ? 0 : props.district.district.id, - isPrimary: props.district.isPrimary || false, - - districtIdError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.isNew && this.state.districtId !== '') { return true; } - if (this.state.isNew && this.state.isPrimary !== '') { return true; } - if (!this.state.isNew && this.state.districtId !== this.props.district.district.id) { return true; } - if (!this.state.isNew && this.state.isPrimary !== this.props.district.isPrimary) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - districtIdError: '', - }); - - var valid = true; - - if (this.state.districtId === 0) { - this.setState({ districtIdError: 'District is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const district = { - id: this.props.district.id, - user: { id: this.props.user.id }, - district: { id: this.state.districtId }, - isPrimary: this.state.isPrimary, - }; - - const promise = this.state.isNew ? Api.addUserDistrict(district) : Api.editUserDistrict(district); - - promise.then((response) => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(response.data); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - var userDistrictsFiltered = _.map(this.props.userDistricts, district => { - if (this.state.isNew || district.district.id !== this.props.district.district.id) { - return district.district.id; - } - return; - }); - - var districts = _.chain(this.props.districts) - .sortBy('name') - .reject(district => { - return _.includes(userDistrictsFiltered, district.id); - } ) - .value(); - - return ( - - - - { this.state.districtIdError } - - Primary District - - ); - } -} - -export default DistrictEditDialog; diff --git a/client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx b/client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx deleted file mode 100644 index 0e9e224d4..000000000 --- a/client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx +++ /dev/null @@ -1,154 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - - -const PROHIBITED_SECTIONS = [ 1.2, 1.8, 2.3, 2.6, 3.3, 6.3, 7.4, 8.2, 9.3, 11.2, 12.2, 13.5, 13.6, 16.3 ]; - - -class DistrictEquipmentTypeAddEditDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - show: PropTypes.bool, - districtEquipmentType: PropTypes.object, - equipmentTypes: PropTypes.object, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - isNew: props.districtEquipmentType.id === 0, - - id: props.districtEquipmentType.id || 0, - equipmentTypeId: props.districtEquipmentType.equipmentType ? props.districtEquipmentType.equipmentType.id : undefined, - districtEquipmentName: props.districtEquipmentType.districtEquipmentName || '', - concurrencyControlNumber: props.districtEquipmentType.concurrencyControlNumber || 0, - equipmentTypeIdError: '', - districtEquipmentNameError: '', - }; - } - - componentDidMount() { - Api.getEquipmentTypes(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.isNew && this.state.equipmentTypeId !== undefined) { return true; } - if (this.state.isNew && this.state.districtEquipmentName !== '') { return true; } - if (!this.state.isNew && this.state.equipmentTypeId !== this.props.districtEquipmentType.equipmentType.id) { return true; } - if (!this.state.isNew && this.state.districtEquipmentName !== this.props.districtEquipmentType.districtEquipmentName) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - equipmentTypeIdError: '', - districtEquipmentNameError: '', - }); - - var valid = true; - - if (this.state.equipmentTypeId === undefined) { - this.setState({ equipmentTypeIdError: 'Blue book section is required' }); - valid = false; - } else { - var equipmentType = _.find(this.props.equipmentTypes, { id: this.state.equipmentTypeId }); - if (equipmentType && _.includes(PROHIBITED_SECTIONS, equipmentType.blueBookSection)) { - this.setState({ equipmentTypeIdError: 'Equipment types cannot be created for this blue book section' }); - valid = false; - } - } - - if (this.state.districtEquipmentName === '') { - this.setState({ districtEquipmentNameError: 'Equipment type/description is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const equipmentType = { - id: this.state.id, - equipmentType: { id: this.state.equipmentTypeId }, - districtEquipmentName: this.state.districtEquipmentName, - concurrencyControlNumber: this.state.concurrencyControlNumber, - district: { id: this.props.currentUser.district.id }, - }; - - const promise = equipmentType.id !== 0 ? Api.updateDistrictEquipmentType(equipmentType) : Api.addDistrictEquipmentType(equipmentType); - - promise.then(() => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - var equipmentTypes = _.sortBy(this.props.equipmentTypes.data, 'blueBookSection'); - - return ( - - - Blue Book Section * - - { this.state.equipmentTypeIdError } - - - Equipment Type/Description * - - { this.state.districtEquipmentNameError } - - - ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - equipmentTypes: state.lookups.equipmentTypes, - }; -} - -export default connect(mapStateToProps)(DistrictEquipmentTypeAddEditDialog); diff --git a/client/src/js/views/dialogs/DocumentsListDialog.jsx b/client/src/js/views/dialogs/DocumentsListDialog.jsx deleted file mode 100644 index 921ec5827..000000000 --- a/client/src/js/views/dialogs/DocumentsListDialog.jsx +++ /dev/null @@ -1,217 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { connect } from 'react-redux'; - -import { Alert, Button, ButtonGroup, Glyphicon, ProgressBar, HelpBlock } from 'react-bootstrap'; - -import _ from 'lodash'; - -import { request, buildApiPath } from '../../utils/http'; - -import * as Action from '../../actionTypes'; -import * as Api from '../../api'; -import * as Constant from '../../constants'; -import store from '../../store'; - -import DeleteButton from '../../components/DeleteButton.jsx'; -import ModalDialog from '../../components/ModalDialog.jsx'; -import SortTable from '../../components/SortTable.jsx'; -import Spinner from '../../components/Spinner.jsx'; -import FilePicker from '../../components/FilePicker.jsx'; -import Authorize from '../../components/Authorize.jsx'; - -import { formatDateTime } from '../../utils/date'; - - -class DocumentsListDialog extends React.Component { - static propTypes = { - parent: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - - documents: PropTypes.object, - users: PropTypes.object, - ui: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - documents: [], - uploadInProgress: false, - percentUploaded: 0, - showAttachmentDialog: false, - ui : { - sortField: props.ui.sortField || 'timestampSort', - sortDesc: props.ui.sortDesc !== false, - }, - uploadError: '', - }; - } - - componentDidMount() { - this.setState({ loading: true }); - Api.getUsers().then(() => { - return this.formatDocuments(); - }).finally(() => { - this.setState({ loading: false }); - }); - } - - getUserName = (smUserId) => { - var user = _.find(this.props.users, user => { return user.smUserId === smUserId; }); - return user ? user.name : smUserId; - }; - - updateUIState = (state, callback) => { - this.setState({ ui: { ...this.state.ui, ...state }}, () =>{ - store.dispatch({ type: Action.UPDATE_DOCUMENTS_UI, documents: this.state.ui }); - if (callback) { callback(); } - }); - }; - - fetch = () => { - this.setState({ loading: true }); - return this.props.parent.getDocumentsPromise(this.props.parent.id).then(() => { - this.formatDocuments(); - }).finally(() => { - this.setState({ loading: false }); - }); - }; - - formatDocuments = () => { - var documents = _.map(this.props.documents, document => { - return { - ...document, - userName: this.getUserName(document.lastUpdateUserid), - formattedTimestamp: formatDateTime(document.lastUpdateTimestamp, Constant.DATE_TIME_LOG), - }; - }); - this.setState({ - documents: documents, - }); - }; - - deleteDocument = (document) => { - Api.deleteDocument(document).then(() => { - this.props.parent.documentDeleted(this.props.parent, document); - return this.fetch(); - }); - }; - - downloadDocument = (document) => { - // Get path to the document and open it in a new browser window to initiate download. - window.open(Api.getDownloadDocumentURL(document)); - }; - - uploadFiles = (files) => { - this.setState({ uploadError: '' }); - - var invalidFiles = _.filter(files, file => file.size > Constant.MAX_ATTACHMENT_FILE_SIZE); - if (invalidFiles.length > 0) { - this.setState({ uploadError: 'One of the selected files is too large.' }); - return; - } - - this.setState({ uploadInProgress: true, percentUploaded: 0 }); - - var options = { - method: 'POST', - files: [...files], - onUploadProgress: (percentComplete) => { - var percent = Math.round(percentComplete); - this.setState({ percentUploaded: percent }); - }, - }; - - this.uploadPromise = request(buildApiPath(this.props.parent.uploadDocumentPath), options).then(() => { - _.map(files, ((file) => { - this.props.parent.documentAdded(this.props.parent, file.name); - })); - this.setState({ uploadInProgress: false, percentUploaded: null }); - this.fetch(); - }, (err) => { - this.setState({ uploadInProgress: false, fileUploadError: err }); - }); - }; - - render() { - var parent = this.props.parent; - - return ( - Documents for { parent.name } } - footer={ } - > -
- {this.state.uploadInProgress ? - - : - -
- -
Select one or more files{ parent.name ? ` to attach to ${ parent.name }` : null }
- The maximum size of each file is { Constant.MAX_ATTACHMENT_FILE_SIZE_READABLE }. - { this.state.uploadError &&
{ this.state.uploadError }
} -
-
- } -
- {(() => { - if (this.state.loading) { return
; } - - var numDocuments = Object.keys(this.state.documents).length; - - if (numDocuments === 0) { return No documents; } - - var documents = _.sortBy(this.state.documents, this.state.ui.sortField); - if (this.state.ui.sortDesc) { - _.reverse(documents); - } - - var headers = [ - { field: 'timestampSort', title: 'Uploaded On' }, - { field: 'userName', title: 'Uploaded By' }, - { field: 'fileName', title: 'File Name' }, - { field: 'fileSize', title: 'File Size' }, - { field: 'attachDocument', title: 'Attach Document', style: { textAlign: 'right' } }, - ]; - - return - { - _.map(documents, (document) => { - return - { document.formattedTimestamp } - { document.userName } - { document.fileName } - { document.fileSizeDisplay } - - - - - - - ; - }) - } - ; - })()} -
-
-
- ); - } -} - -function mapStateToProps(state) { - return { - documents: state.models.documents, - users: state.lookups.users, - ui: state.ui.documents, - }; -} - -export default connect(mapStateToProps)(DocumentsListDialog); diff --git a/client/src/js/views/dialogs/EquipmentAddDialog.jsx b/client/src/js/views/dialogs/EquipmentAddDialog.jsx deleted file mode 100644 index 5157aad77..000000000 --- a/client/src/js/views/dialogs/EquipmentAddDialog.jsx +++ /dev/null @@ -1,308 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank, notBlank } from '../../utils/string'; -import { isValidYear } from '../../utils/date'; - - -class EquipmentAddDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object.isRequired, - owner: PropTypes.object.isRequired, - localAreas: PropTypes.object.isRequired, - districtEquipmentTypes: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - localAreaId: props.owner.localArea.id || 0, - equipmentTypeId: 0, - licencePlate: '', - serialNumber: '', - make: '', - model: '', - year: '', - size: '', - type: '', - licencedGvw: '', - legalCapacity: '', - pupLegalCapacity: '', - localAreaError: '', - equipmentTypeError: '', - serialNumberError: '', - duplicateSerialNumberWarning: false, - makeError: '', - modelError: '', - yearError: '', - }; - } - - componentDidMount() { - Api.getDistrictEquipmentTypes(); - } - - componentDidUpdate(prevProps, prevState) { - if (!_.isEqual(this.state.serialNumber, prevState.serialNumber)) { - this.setState({ duplicateSerialNumberWarning: false, serialNumberError: '' }); - } - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.localAreaId !== 0) { return true; } - if (this.state.equipmentTypeId !== 0) { return true; } - if (this.state.serialNumber !== '') { return true; } - if (this.state.licencePlate !== '') { return true; } - if (this.state.make !== '') { return true; } - if (this.state.model !== '') { return true; } - if (this.state.year !== '') { return true; } - if (this.state.size !== '') { return true; } - if (this.state.type !== '') { return true; } - if (this.state.licencedGvw !== '') { return true; } - if (this.state.legalCapacity !== '') { return true; } - if (this.state.pupLegalCapacity !== '') { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - localAreaError: '', - equipmentTypeError: '', - serialNumberError: '', - makeError: '', - modelError: '', - yearError: '', - }); - - var valid = true; - - if (this.state.localAreaId === 0) { - this.setState({ localAreaError: 'Service area / local area is required.' }); - valid = false; - } - - if (this.state.equipmentTypeId === 0) { - this.setState({ equipmentTypeError: 'Equipment type is required.' }); - valid = false; - } - - if (isBlank(this.state.make)) { - this.setState({ makeError: 'Make is required.' }); - valid = false; - } - - if (isBlank(this.state.model)) { - this.setState({ modelError: 'Model is required.' }); - valid = false; - } - - if (isBlank(this.state.year)) { - this.setState({ yearError: 'Year is required.' }); - valid = false; - } else if (notBlank(this.state.year) && !isValidYear(this.state.year)) { - this.setState({ yearError: 'This is not a valid year.' }); - valid = false; - } - - if (isBlank(this.state.serialNumber)) { - this.setState({ serialNumberError: 'Serial number is required.' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.state.duplicateSerialNumberWarning) { - // proceed regardless of duplicates - this.setState({ duplicateSerialNumberWarning: false }); - return this.saveEquipment(); - } - - this.setState({ isSaving: true }); - - return Api.equipmentDuplicateCheck(0, this.state.serialNumber).then((response) => { - this.setState({ isSaving: false }); - - if (response.data.length > 0) { - const equipmentCodes = response.data.map((district) => { - return district.duplicateEquipment.equipmentCode; - }); - var districts = _.chain(response.data) - .map(district => district.districtName) - .uniq() - .value(); - const districtsPlural = districts.length === 1 ? 'district' : 'districts'; - this.setState({ - serialNumberError: `Serial number is currently in use for the equipment ${equipmentCodes.join(', ')}, in the following ${districtsPlural}: ${districts.join(', ')}`, - duplicateSerialNumberWarning: true, - }); - return null; - } else { - this.setState({ duplicateSerialNumberWarning: false }); - return this.saveEquipment(); - } - }); - } - }; - - saveEquipment = () => { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const equipment = { - owner: { id: this.props.owner.id }, - localArea: { id: this.state.localAreaId }, - districtEquipmentType: { id: this.state.equipmentTypeId }, - licencePlate: this.state.licencePlate, - serialNumber: this.state.serialNumber, - make: this.state.make, - model: this.state.model, - year: this.state.year, - size: this.state.size, - type: this.state.type, - licencedGvw: this.state.licencedGvw, - legalCapacity: this.state.legalCapacity, - pupLegalCapacity: this.state.pupLegalCapacity, - status: Constant.EQUIPMENT_STATUS_CODE_PENDING, - }; - - return Api.addEquipment(equipment).then((savedEquipment) => { - this.setState({ isSaving: false }); - this.props.onSave(savedEquipment); - }); - } - }; - - render() { - var owner = this.props.owner; - - var localAreas = _.sortBy(this.props.localAreas, 'name'); - - var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) - .filter(type => type.district.id == this.props.currentUser.district.id) - .sortBy('districtEquipmentName') - .value(); - - var equipment = _.find(districtEquipmentTypes, equipment => { - return equipment.id == this.state.equipmentTypeId; - }); - - var isDumpTruck = equipment && equipment.equipmentType.isDumpTruck; - - return ( - - - Owner -

{ owner.organizationName }

-
- - Service Area - Local Area * - - { this.state.localAreaError } - - - Equipment Type * - - { this.state.equipmentTypeError } - - - Make * - - { this.state.makeError } - - - Model * - - { this.state.modelError } - - - Year * - - { this.state.yearError } - - - Size - - - - Type - - - - Licence Number - - - - Serial Number * - - { this.state.serialNumberError } - - { isDumpTruck && -
- - Licenced GVW - - - - Truck Legal Capacity - - - - Pup Legal Capacity - - -
- } -
- ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - localAreas: state.lookups.localAreas, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - }; -} - -export default connect(mapStateToProps)(EquipmentAddDialog); diff --git a/client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx b/client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx deleted file mode 100644 index f99d81d07..000000000 --- a/client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx +++ /dev/null @@ -1,98 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - - -class EquipmentChangeStatusDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - status: PropTypes.string.isRequired, - equipment: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - onStatusChanged: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - saving: false, - comment: '', - commentError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - isValid = () => { - this.setState({ - commentError: '', - }); - - var valid = true; - - if (isBlank(this.state.comment)) { - this.setState({ commentError: 'Comment is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - this.setState({isSaving: true}); - const status = { - id: this.props.equipment.id, - status: this.props.status, - statusComment: this.state.comment, - }; - - Api.changeEquipmentStatus(status).then(() => { - this.setState({isSaving: false}); - this.props.onStatusChanged(); - Log.equipmentStatusModified(this.props.equipment, status.status, status.statusComment); - }).catch((error) => { - if (error.status === 400 && (error.errorCode === 'HETS-39' || error.errorCode === 'HETS-41')) { - this.setState({ commentError: error.errorDescription }); - } else { - throw error; - } - }); - } - }; - - render() { - var maxLength = Constant.MAX_LENGTH_STATUS_COMMENT; - - return ( - - - Comment - - {this.state.commentError} -

Maximum { maxLength } characters.

-
-
- ); - } -} - -export default EquipmentChangeStatusDialog; diff --git a/client/src/js/views/dialogs/EquipmentEditDialog.jsx b/client/src/js/views/dialogs/EquipmentEditDialog.jsx deleted file mode 100644 index 666a3d965..000000000 --- a/client/src/js/views/dialogs/EquipmentEditDialog.jsx +++ /dev/null @@ -1,382 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { connect } from 'react-redux'; - -import _ from 'lodash'; - -import { Grid, Row, Col, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; - -import { isBlank, notBlank } from '../../utils/string'; -import { isValidYear } from '../../utils/date'; - -class EquipmentEditDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - equipment: PropTypes.object.isRequired, - localAreas: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - isNew: props.equipment.id === 0, - - localAreaId: props.equipment.localArea.id || 0, - equipmentTypeId: props.equipment.districtEquipmentTypeId || null, - serialNumber: props.equipment.serialNumber || '', - make: props.equipment.make || '', - size: props.equipment.size || '', - model: props.equipment.model || '', - year: props.equipment.year || '', - licencePlate: props.equipment.licencePlate || '', - type: props.equipment.type || '', - licencedGvw: props.equipment.licencedGvw || '', - legalCapacity: props.equipment.legalCapacity || '', - pupLegalCapacity: props.equipment.pupLegalCapacity || '', - - localAreaError: '', - localAreaSeniorityChangeWarning: false, - equipmentTypeError: '', - equipmentTypeSeniorityChangeWarning: false, - serialNumberError: '', - duplicateSerialNumberWarning: false, - makeError: '', - modelError: '', - yearError: '', - }; - } - - componentDidMount() { - Api.getDistrictEquipmentTypes(); - } - - componentDidUpdate(prevProps, prevState) { - if (!_.isEqual(this.state.serialNumber, prevState.serialNumber)) { - this.setState({ duplicateSerialNumberWarning: false, serialNumberError: '' }); - } - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.localAreaId !== this.props.equipment.localArea.id) { return true; } - if (this.state.equipmentTypeId !== 0) { return true; } - if (this.state.serialNumber !== this.props.equipment.serialNumber) { return true; } - if (this.state.make !== this.props.equipment.make) { return true; } - if (this.state.size !== this.props.equipment.size) { return true; } - if (this.state.model !== this.props.equipment.model) { return true; } - if (this.state.year !== this.props.equipment.year) { return true; } - if (this.state.licencePlate !== this.props.equipment.licencePlate) { return true; } - if (this.state.type !== this.props.equipment.type) { return true; } - if (this.state.licencedGvw !== this.props.equipment.licencedGvw) { return true; } - if (this.state.legalCapacity !== this.props.equipment.legalCapacity) { return true; } - if (this.state.pupLegalCapacity !== this.props.equipment.pupLegalCapacity) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - localAreaError: '', - equipmentTypeError: '', - serialNumberError: '', - makeError: '', - modelError: '', - yearError: '', - }); - - var valid = true; - - if (this.state.equipmentTypeId === 0) { - this.setState({ equipmentTypeError: 'Equipment type is required.' }); - valid = false; - } - - if (isBlank(this.state.serialNumber)) { - this.setState({ serialNumberError: 'Serial number is required' }); - valid = false; - } - - if (isBlank(this.state.make)) { - this.setState({ makeError: 'Make is required.' }); - valid = false; - } - - if (isBlank(this.state.model)) { - this.setState({ modelError: 'Model is required.' }); - valid = false; - } - - if (isBlank(this.state.year)) { - this.setState({ yearError: 'Year is required.' }); - valid = false; - } else if (notBlank(this.state.year) && !isValidYear(this.state.year)) { - this.setState({ yearError: 'This is not a valid year.' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - if (this.state.duplicateSerialNumberWarning) { - // proceed regardless of duplicates - this.setState({ duplicateSerialNumberWarning: false }); - return this.saveEquipment(); - } - - return Api.equipmentDuplicateCheck(this.props.equipment.id, this.state.serialNumber).then((response) => { - if (response.data.length > 0) { - const equipmentCodes = response.data.map((district) => { - return district.duplicateEquipment.equipmentCode; - }); - var districts = _.chain(response.data) - .map(district => district.districtName) - .uniq() - .value(); - const districtsPlural = districts.length === 1 ? 'district' : 'districts'; - this.setState({ - serialNumberError: `Serial number is currently in use for the equipment ${equipmentCodes.join(', ')}, in the following ${districtsPlural}: ${districts.join(', ')}`, - duplicateSerialNumberWarning: true, - }); - return null; - } else { - this.setState({ duplicateSerialNumberWarning: false }); - return this.saveEquipment(); - } - }); - } else { - this.props.onClose(); - } - } - }; - - saveEquipment = () => { - this.setState({ isSaving: true }); - - const equipment = { - ...this.props.equipment, - localArea: { id: this.state.localAreaId }, - districtEquipmentTypeId: this.state.equipmentTypeId, - serialNumber: this.state.serialNumber, - make: this.state.make, - size: this.state.size, - model: this.state.model, - year: this.state.year, - licencePlate: this.state.licencePlate, - type: this.state.type, - licencedGvw: this.state.licencedGvw, - legalCapacity: this.state.legalCapacity, - pupLegalCapacity: this.state.pupLegalCapacity, - }; - - const promise = Api.updateEquipment(equipment); - - promise.then(() => { - Log.equipmentModified(this.props.equipment); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - }; - - onLocalAreaChanged() { - if (this.state.localAreaId !== this.props.equipment.localArea.id) { - this.setState({ - localAreaError: 'This action will change the seniority of the equipment.', - localAreaSeniorityChangeWarning: true, - }); - } else { - this.setState({ - localAreaError: '', - localAreaSeniorityChangeWarning: false, - }); - } - } - - onEquipmentTypeChanged() { - if (this.state.equipmentTypeId !== this.props.equipment.districtEquipmentTypeId) { - this.setState({ - equipmentTypeError: 'This action will change the seniority of the equipment.', - equipmentTypeSeniorityChangeWarning: true, - }); - } else { - this.setState({ - equipmentTypeError: '', - equipmentTypeSeniorityChangeWarning: false, - }); - } - } - - render() { - var equipment = this.props.equipment; - - var localAreas = _.sortBy(this.props.localAreas, 'name'); - - var districtEquipmentTypes = _.chain(this.props.districtEquipmentTypes.data) - .filter(type => type.district.id == this.props.currentUser.district.id) - .sortBy('districtEquipmentName') - .value(); - - const saveWarning = this.state.duplicateSerialNumberWarning || this.state.localAreaSeniorityChangeWarning || this.state.equipmentTypeSeniorityChangeWarning; - - return ( - - - - - - Service Area - Local Area - this.updateState(state, this.onLocalAreaChanged) } - items={ localAreas } - className="full-width" - /> - { this.state.localAreaError } - - - - - - - Equipment Type * - this.updateState(state, this.onEquipmentTypeChanged) }/> - { this.state.equipmentTypeError } - - - - - - - Make * - - { this.state.makeError } - - - - - - - Model * - - { this.state.modelError } - - - - - - - Year * - - { this.state.yearError } - - - - - - - Size - - - - - - - - Type - - - - - - - - Licence Number - - - - - - - - Serial Number * - - { this.state.serialNumberError } - - - - { equipment.isDumpTruck && -
- - - - Licenced GVW - - - - - - - - Truck Legal Capacity - - - - - - - - Pup Legal Capacity - - - - -
- } -
-
- ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - localAreas: state.lookups.localAreas, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - }; -} - -export default connect(mapStateToProps)(EquipmentEditDialog); diff --git a/client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx b/client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx deleted file mode 100644 index 7f4e6f8dc..000000000 --- a/client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx +++ /dev/null @@ -1,134 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Grid, Row, Col } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - - -class EquipmentRentalRatesEditDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - rentalAgreement: PropTypes.object.isRequired, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - equipmentRate: props.rentalAgreement.equipmentRate || 0, - ratePeriod: props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY, - rateComment: props.rentalAgreement.rateComment || '', - - equipmentRateError: '', - ratePeriodError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.equipmentRate !== this.props.rentalAgreement.equipmentRate) { return true; } - if (this.state.ratePeriod !== this.props.rentalAgreement.ratePeriod) { return true; } - if (this.state.rateComment !== this.props.rentalAgreement.rateComment) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - equipmentRateError: '', - ratePeriodError: '', - }); - - var valid = true; - - if (isBlank(this.state.equipmentRate) ) { - this.setState({ equipmentRateError: 'Pay rate is required' }); - valid = false; - } else if (this.state.equipmentRate < 0) { - this.setState({ equipmentRateError: 'Pay rate not valid' }); - valid = false; - } - - if (isBlank(this.state.ratePeriod)) { - this.setState({ ratePeriodError: 'Period is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const rentalAgreement = { - ...this.props.rentalAgreement, - equipmentRate: this.state.equipmentRate, - ratePeriod: this.state.ratePeriod, - rateComment: this.state.rateComment, - }; - - Api.updateRentalAgreement(rentalAgreement).then(() => { - if (this.props.onSave) { this.props.onSave(); } - }); - } - - this.props.onClose(); - } - }; - - render() { - // Read-only if the user cannot edit the rental agreement - var isReadOnly = !this.props.rentalAgreement.canEdit && this.props.rentalAgreement.id !== 0; - var ratePeriods = [ Constant.RENTAL_RATE_PERIOD_HOURLY, Constant.RENTAL_RATE_PERIOD_DAILY, Constant.RENTAL_RATE_PERIOD_WEEKLY, Constant.RENTAL_RATE_PERIOD_MONTHLY, Constant.RENTAL_RATE_PERIOD_NEGOTIATED ]; - - return ( - - - - - - Pay Rate * - - { this.state.equipmentRateError } - - - - - Period * - - { this.state.ratePeriodError } - - - - - Comment - - - - - - - ); - } -} - -export default EquipmentRentalRatesEditDialog; diff --git a/client/src/js/views/dialogs/EquipmentTransferDialog.jsx b/client/src/js/views/dialogs/EquipmentTransferDialog.jsx deleted file mode 100644 index 83a73e8a8..000000000 --- a/client/src/js/views/dialogs/EquipmentTransferDialog.jsx +++ /dev/null @@ -1,312 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { connect } from 'react-redux'; - -import { Button, Row, Col, FormGroup, ControlLabel, HelpBlock, Checkbox } from 'react-bootstrap'; - -import _ from 'lodash'; - -import * as Api from '../../api'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; -import ModalDialog from '../../components/ModalDialog.jsx'; -import Spinner from '../../components/Spinner.jsx'; -import TableControl from '../../components/TableControl.jsx'; - -import { isBlank } from '../../utils/string'; - -const STAGE_SELECT_OWNER = 1; -const STAGE_SELECT_EQUIPMENT = 2; -const STAGE_CONFIRM = 3; -const STAGE_COMPLETE = 4; - -const OPTION_EQUIPMENT_ONLY = { id: 1, name: 'Transfer Equipment Only' }; -const OPTION_EQUIPMENT_AND_SENIORITY = { id: 2, name: 'Transfer Equipment and Seniority' }; - -class EquipmentTransferDialog extends React.Component { - static propTypes = { - equipment: PropTypes.object.isRequired, - owners: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - stage: STAGE_SELECT_OWNER, - donorOwnerCode: '', - recipientOwnerCode: '', - seniorityOption: 1, - donorOwnerCodeError: '', - recipientOwnerCodeError: '', - seniorityOptionError: '', - selectedEquipmentIds: [], - selectAllEquipment: false, - waitingForResponse: false, - equipmentTransferError: '', - }; - } - - componentDidMount() { - Api.getOwnersLite(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - getOwner = (code) => { - var owner = _.find(this.props.owners.data, { ownerCode: code }); - return owner; - }; - - validateOwnerCode = (code, errorState) => { - if (isBlank(code)) { - this.setState({ [errorState]: 'This owner code is required' }); - return false; - } - - if (this.getOwner(code) === undefined) { - this.setState({ [errorState]: 'This owner code is either not valid or not approved' }); - return false; - } - - return true; - }; - - validateSelectOwner = () => { - this.setState({ donorOwnerCodeError: '', recipientOwnerCodeError: '', seniorityOptionError: '' }); - - var valid = this.validateOwnerCode(this.state.donorOwnerCode, 'donorOwnerCodeError'); - valid &= this.validateOwnerCode(this.state.recipientOwnerCode, 'recipientOwnerCodeError'); - - if (!valid) { - return false; - } - - if (this.state.donorOwnerCode === this.state.recipientOwnerCode) { - this.setState({ recipientOwnerCodeError: 'The owner codes must be different' }); - return false; - } - - var donor = this.getOwner(this.state.donorOwnerCode); - var recipient = this.getOwner(this.state.recipientOwnerCode); - - if (this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id && donor.localAreaId !== recipient.localAreaId) { - this.setState({ seniorityOptionError: 'Both Transfer From and Transfer To Owners/Companies should be from the same local area' }); - return false; - } - - return true; - }; - - renderSelectOwner = () => { - var seniorityOptions = [ OPTION_EQUIPMENT_ONLY, OPTION_EQUIPMENT_AND_SENIORITY ]; - - return
- - - Transfer Equipment From (Owner Code) * - - - Action * - - - Transfer Equipment To (Owner Code) * - - - - - - - { this.state.donorOwnerCodeError } - - - - - - { this.state.seniorityOptionError } - - - - - - { this.state.recipientOwnerCodeError } - - - -
; - }; - - handleEquipmentCheckedChange = (e, id) => { - var checked = e.target.checked; - - var selectedEquipmentIds = [ ...this.state.selectedEquipmentIds ]; - if (checked && !_.includes(selectedEquipmentIds, id)) { - selectedEquipmentIds.push(id); - } else { - _.remove(selectedEquipmentIds, x => x === id); - } - - this.setState({ selectedEquipmentIds: selectedEquipmentIds }); - }; - - handleSelectAllEquipmentCheckedChange = (e) => { - var checked = e.target.checked; - - var selectedEquipmentIds = checked ? _.map(this.props.equipment.data, x => x.id) : []; - - this.setState({ selectedEquipmentIds: selectedEquipmentIds, selectAllEquipment: checked }); - }; - - validateSelectEquipment = () => { - return this.state.selectedEquipmentIds.length > 0; - }; - - renderSelectEquipment = () => { - if (this.props.equipment.loading) { return
; } - - var equipmentList = this.props.equipment.data; - - var selectAllCheckbox = Select All; - - var headers = [ - { field: '', node: selectAllCheckbox }, - { field: 'equipmentCode', title: 'Equip. ID' }, - { field: 'equipmentType', title: 'Equip. Type' }, - { field: 'details', title: 'Make/Model/Size/Year' }, - { field: 'attachmentCount', title: 'Attachments' }, - ]; - - return - { - _.map(equipmentList, (equipment) => { - return ( - - this.handleEquipmentCheckedChange(e, equipment.id) } /> - { equipment.equipmentCode } - { equipment.districtEquipmentType.districtEquipmentName } - { equipment.details } - { _.map(equipment.equipmentAttachments, a => a.description).join(', ') } - - ); - }) - } - ; - }; - - renderConfirm = () => { - return
-

This action will transfer all selected equipment from the first owner/company to the second owner/company.

-
    -
  • The piece(s) of equipment from the first company will be archived.
  • - { this.state.seniorityOption === OPTION_EQUIPMENT_ONLY.id &&
  • The piece(s) of equipment will be added to the “Transfer To” owner/company as new equipment.
  • } - { this.state.seniorityOption === OPTION_EQUIPMENT_ONLY.id &&
  • All previous seniority data will be lost.
  • } - { this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id &&
  • The piece(s) of equipment will be added to the “Transfer To” owner/company while retaining their seniority.
  • } -
- { !this.state.waitingForResponse &&

Do you want to continue?

} - { this.state.waitingForResponse &&

Please wait while the equipment is transferred. This may take some time.

} -
; - }; - - renderComplete = () => { - return
- { this.state.equipmentTransferError &&
Error: { this.state.equipmentTransferError }
} - { this.state.equipmentTransferError &&

The selected equipment has not been transferred.

} - { !this.state.equipmentTransferError &&

The selected equipment has been successfully transferred.

} -
; - }; - - render() { - var content = null; - var transferText = 'Transfer'; - var transferEnabled = false; - var transferFunc = function() { }; - - if (!this.props.owners.loaded) { return
; } - - switch(this.state.stage) { - case STAGE_SELECT_OWNER: - content = this.renderSelectOwner(); - transferEnabled = !isBlank(this.state.donorOwnerCode) && !isBlank(this.state.recipientOwnerCode); - transferFunc = function() { - if (this.validateSelectOwner()) { - var ownerId = this.getOwner(this.state.donorOwnerCode).id; - Api.getOwnerEquipment(ownerId); - - this.setState({ stage: STAGE_SELECT_EQUIPMENT }); - } - }; - break; - case STAGE_SELECT_EQUIPMENT: - content = this.renderSelectEquipment(); - transferEnabled = this.state.selectedEquipmentIds.length > 0; - transferFunc = function() { - if (this.validateSelectEquipment()) { - this.setState({ stage: STAGE_CONFIRM }); - } - }; - break; - case STAGE_CONFIRM: - content = this.renderConfirm(); - transferText = this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id ? 'Transfer Equipment and Seniority' : 'Transfer Equipment Only'; - transferEnabled = true; - transferFunc = function() { - this.setState({ waitingForResponse: true }); - - var donorOwnerId = this.getOwner(this.state.donorOwnerCode).id; - var recipientOwnerId = this.getOwner(this.state.recipientOwnerCode).id; - var equipment = _.filter(this.props.equipment.data, x => _.includes(this.state.selectedEquipmentIds, x.id)); - var includeSeniority = this.state.seniorityOption === OPTION_EQUIPMENT_AND_SENIORITY.id; - - Api.transferEquipment(donorOwnerId, recipientOwnerId, equipment, includeSeniority).catch((error) => { - if (error.status === 400 && (error.errorCode === 'HETS-31' || error.errorCode === 'HETS-32' || error.errorCode === 'HETS-33' || error.errorCode === 'HETS-34')) { - this.setState({ equipmentTransferError: error.errorDescription }); - } else { - throw error; - } - }).finally(() => { - this.setState({ waitingForResponse: false, stage: STAGE_COMPLETE }); - }); - }; - break; - case STAGE_COMPLETE: - content = this.renderComplete(); - break; - } - - var displayTransferButton = this.state.stage !== STAGE_COMPLETE && this.state.waitingForResponse !== true; - - return ( - - - { displayTransferButton && } - - }> - {content} - - ); - } -} - -function mapStateToProps(state) { - return { - equipment: state.models.ownerEquipment, - owners: state.lookups.owners.lite, - }; -} - -export default connect(mapStateToProps)(EquipmentTransferDialog); diff --git a/client/src/js/views/dialogs/ErrorDialog.jsx b/client/src/js/views/dialogs/ErrorDialog.jsx deleted file mode 100644 index 18179d7cf..000000000 --- a/client/src/js/views/dialogs/ErrorDialog.jsx +++ /dev/null @@ -1,123 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Button } from 'react-bootstrap'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; - -import ModalDialog from '../../components/ModalDialog.jsx'; -import {closeErrorDialog} from '../../actions'; - -class ErrorDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - title: PropTypes.string, - apiError: PropTypes.object, - appError: PropTypes.object, - closeErrorDialog: PropTypes.func.isRequired, - }; - - closeDialog = () => { - this.props.closeErrorDialog(); - }; - - reloadButtonClicked = () => { - window.location.reload(); - }; - - render() { - const {apiError, appError, show} = this.props; - - var modalTitle = 'Unexpected Error'; - var errorMessage = 'An error occured'; - var details = null; - var shouldReload = false; - var buttonText = 'Close'; - - if (appError) { - errorMessage = appError.message; - - if (appError.unrecoverable) { - shouldReload = true; - buttonText = 'Reload'; - } - } else if (apiError) { - // NOTE: If we get a status code of `null` we only know that the request has failed. We will - // guess that it is a SiteMinder timeout that failed the request. What has happened is that - // the original request will get a 302 and the browser will make a subsequent request to - // https://logontest7.gov.bc.ca/clp-cgi/int/logon.cgi. The request will fail because of CORS - // and the browser will erase any response data for security so we can't inspect any headers - // or response data. - const possibleSMError = apiError.status === 401 || apiError.status === 403 || apiError.status === null; - shouldReload = true; - - if (possibleSMError) { - modalTitle = 'Session expired'; - errorMessage = 'It looks like your session has expired. You will need to log in again.'; - buttonText = 'Log in'; - } else { - modalTitle = 'Server Error'; - errorMessage = apiError.message; - buttonText = 'Reload'; - - if (apiError.json) { - if (apiError.json.error) { - errorMessage = Error message: {errorMessage}; - } - - details = ( -
-

- A HTTP {apiError.method.toUpperCase()} request to - {apiError.path} - returned a - {apiError.status} - status code. -

-
-

Response body:

-
-                  {JSON.stringify(apiError.json, null, 2)}
-                
-
-
- ); - } - } - } - - const footer = ( - - - - ); - - return ( - {modalTitle}} - footer={footer} - onClose={this.closeDialog}> -
{errorMessage}
- {details} -
- ); - } -} - -function mapStateToProps(state) { - return { - showSessionTimeoutDialog: state.ui.showSessionTimeoutDialog, - appError: state.ui.appError, - apiError: state.ui.requests.error, - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators({ - closeErrorDialog, - }, dispatch); -} - -export default connect(mapStateToProps, mapDispatchToProps)(ErrorDialog); diff --git a/client/src/js/views/dialogs/HireOfferEditDialog.jsx b/client/src/js/views/dialogs/HireOfferEditDialog.jsx deleted file mode 100644 index 57e9d9777..000000000 --- a/client/src/js/views/dialogs/HireOfferEditDialog.jsx +++ /dev/null @@ -1,354 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Grid, Row, Col, Radio, FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import ConfirmForceHireDialog from '../dialogs/ConfirmForceHireDialog.jsx'; -import ConfirmDialog from '../dialogs/ConfirmDialog.jsx'; - -import CheckboxControl from '../../components/CheckboxControl.jsx'; -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { today, toZuluTime, formatDateTime } from '../../utils/date'; -import { isBlank } from '../../utils/string'; - - -const STATUS_YES = 'Yes'; -const STATUS_NO = 'No'; -const STATUS_ASKED = 'Asked'; -const STATUS_FORCE_HIRE = 'Force Hire'; - -const refusalReasons = [ - Constant.HIRING_REFUSAL_EQUIPMENT_NOT_AVAILABLE, - Constant.HIRING_REFUSAL_EQUIPMENT_NOT_SUITABLE, - Constant.HIRING_REFUSAL_NO_RESPONSE, - Constant.HIRING_REFUSAL_MAXIMUM_HOURS_REACHED, - Constant.HIRING_REFUSAL_MAINTENANCE_CONTRACTOR, - Constant.HIRING_REFUSAL_OTHER, -]; - - -class HireOfferEditDialog extends React.Component { - static displayName = 'HireOfferEditDialog'; - - static propTypes = { - hireOffer: PropTypes.object.isRequired, - showAllResponseFields: PropTypes.bool.isRequired, - rentalRequest: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = this.buildInitialState(); - } - - buildInitialState() { - return { - isSaving: false, - - isForceHire: this.props.hireOffer.isForceHire || false, - wasAsked: this.props.hireOffer.wasAsked || false, - askedDateTime: this.props.hireOffer.askedDateTime || '', - offerResponse: this.props.hireOffer.offerResponse || '', - offerStatus: this.props.hireOffer.offerResponse || '', - offerRefusalReason: this.props.hireOffer.offerRefusalReason, - offerResponseDatetime: this.props.hireOffer.offerResponseDatetime || '', - offerResponseNote: this.props.hireOffer.offerResponseNote || '', - note: this.props.hireOffer.note || '', - - offerResponseError: '', - offerResponseNoteError: '', - offerRefusalReasonError: '', - - showConfirmForceHireDialog: false, - showConfirmMaxHoursHireDialog: false, - - equipmentVerifiedActive: false, - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - offerStatusChanged = (value) => { - this.setState({ - offerStatus: value, - offerResponse: value, - offerResponseDatetime: value !== STATUS_ASKED ? today() : null, - isForceHire: value === STATUS_FORCE_HIRE, - wasAsked: STATUS_ASKED, - askedDateTime: value === STATUS_ASKED ? today() : null, - equipmentVerifiedActive: (value === STATUS_YES || value === STATUS_FORCE_HIRE) ? true : false, - }); - }; - - didChange = () => { - if (this.state.isForceHire !== this.props.hireOffer.isForceHire) { return true; } - if (this.state.wasAsked !== this.props.hireOffer.wasAsked) { return true; } - if (this.state.askedDateTime !== this.props.hireOffer.askedDateTime) { return true; } - if (this.state.offerResponse !== this.props.hireOffer.offerResponse) { return true; } - if (this.state.offerRefusalReason !== this.props.hireOffer.offerRefusalReason) { return true; } - if (this.state.offerResponseDatetime !== this.props.hireOffer.offerResponseDatetime) { return true; } - if (this.state.offerResponseNote !== this.props.hireOffer.offerResponseNote) { return true; } - if (this.state.note !== this.props.hireOffer.note) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - offerResponseError: '', - offerRefusalReasonError: '', - offerResponseNoteError: '', - rentalAgreementError: '', - }); - - var valid = true; - - if (isBlank(this.state.offerResponse)) { - this.setState({ offerResponseError: 'A response is required' }); - valid = false; - } - - if (this.state.offerResponse === STATUS_NO && isBlank(this.state.offerRefusalReason)) { - this.setState({ offerRefusalReasonError: 'A refusal reason is required' }); - valid = false; - } - - if (this.state.offerStatus == STATUS_NO && this.state.offerRefusalReason === Constant.HIRING_REFUSAL_OTHER && isBlank(this.state.offerResponseNote)) { - this.setState({ offerResponseNoteError: 'Note is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var isDumpTruck = this.props.hireOffer.equipment.districtEquipmentType.equipmentType.isDumpTruck; - var hoursYtd = this.props.hireOffer.equipment.hoursYtd; - - if (this.state.offerStatus !== STATUS_NO && !isDumpTruck && hoursYtd >= 300) { - this.openConfirmMaxHoursHireDialog(); - } else if (this.state.offerStatus !== STATUS_NO && isDumpTruck && hoursYtd >= 600) { - this.openConfirmMaxHoursHireDialog(); - } else if (this.state.offerStatus == STATUS_FORCE_HIRE) { - this.openConfirmForceHireDialog(); - } else { - this.saveHireOffer(); - } - } else { - this.props.onClose(); - } - } - }; - - onCancelMaxHoursHire = () => { - if (this.state.offerResponse === STATUS_FORCE_HIRE) { - this.setState(this.buildInitialState()); - } else { - this.offerStatusChanged(STATUS_NO); - this.setState({ offerRefusalReason: Constant.HIRING_REFUSAL_MAXIMUM_HOURS_REACHED }); - } - this.closeConfirmMaxHoursHireDialog(); - }; - - onConfirmMaxHoursHire = () => { - if (this.state.offerStatus == STATUS_FORCE_HIRE) { - return this.openConfirmForceHireDialog(); - } - - this.saveHireOffer(); - }; - - saveHireOffer = () => { - var promise = Promise.resolve(); - - if (this.state.equipmentVerifiedActive) { - // Update Equipment's last verified date - const equipment = { - ...this.props.hireOffer.equipment, - lastVerifiedDate: toZuluTime(today()), - }; - - promise = Api.updateEquipment(equipment); - } - - promise.then(() => { - const hireOffer = { - ..._.omit(this.props.hireOffer, 'displayFields', 'rentalAgreement'), - isForceHire: this.state.isForceHire, - wasAsked: this.state.wasAsked ? true : false, - askedDateTime: this.state.offerResponse === STATUS_ASKED ? formatDateTime(new Date()) : toZuluTime(this.state.askedDateTime), - offerResponse: this.state.offerResponse, - offerResponseDatetime: toZuluTime(this.state.offerResponseDatetime), - offerRefusalReason: this.state.offerRefusalReason, - offerResponseNote: this.state.offerResponseNote, - note: this.state.note, - }; - - Api.updateRentalRequestRotationList(hireOffer, this.props.rentalRequest).then(() => { - this.setState({isSaving: false}); - if (this.props.onSave) { this.props.onSave(hireOffer); } - }); - }); - }; - - onConfirmForceHire = (reasonForForceHire) => { - this.setState({ note: reasonForForceHire, showConfirmForceHireDialog: false }, this.saveHireOffer); - }; - - openConfirmForceHireDialog = () => { - this.setState({ showConfirmForceHireDialog: true }); - }; - - closeConfirmForceHireDialog = () => { - this.setState({ showConfirmForceHireDialog: false, isSaving: false }); - }; - - openConfirmMaxHoursHireDialog = () => { - this.setState({ showConfirmMaxHoursHireDialog: true }); - }; - - closeConfirmMaxHoursHireDialog = () => { - this.setState({ showConfirmMaxHoursHireDialog: false, isSaving: false }); - }; - - render() { - // Read-only if the user cannot edit the rental agreement - var isReadOnly = !this.props.rentalRequest.canEdit && this.props.rentalRequest.id !== 0; - - return ( - - - - - Response - - - - this.offerStatusChanged(STATUS_YES) } - checked={ this.state.offerStatus == STATUS_YES } - disabled={ !this.props.showAllResponseFields && !this.props.hireOffer.offerResponse }> - Yes - - - - - - - - this.offerStatusChanged(STATUS_NO) } - checked={ this.state.offerStatus == STATUS_NO } - disabled={ !this.props.showAllResponseFields && !this.props.hireOffer.offerResponse }> - No - - - - - { this.state.offerStatus == STATUS_NO && - - - - {/*TODO - use lookup list*/} - Refusal Reason - - { this.state.offerRefusalReasonError } - - - - } - - - - this.offerStatusChanged(STATUS_FORCE_HIRE) } - checked={ this.state.offerStatus == STATUS_FORCE_HIRE }> - Force Hire - - - - - - - - this.offerStatusChanged(STATUS_ASKED) } - checked={ this.state.offerStatus == STATUS_ASKED } - disabled={ !this.props.showAllResponseFields && !this.props.hireOffer.offerResponse }> - Asked - - - - - { this.state.offerResponseError } - - - - - - Note - - { this.state.offerResponseNoteError } - - - - - - - Verified Active - - - - - { this.state.showConfirmForceHireDialog && ( - - )} - { this.state.showConfirmMaxHoursHireDialog && ( - -

- Equipment/Dump Truck has already reached the maximum hours for the year. Do you still - want to hire this Equipment/Dump Truck? -

-
- )} -
- ); - } -} - -function mapStateToProps() { - return { }; -} - -export default connect(mapStateToProps)(HireOfferEditDialog); diff --git a/client/src/js/views/dialogs/NotesAddDialog.jsx b/client/src/js/views/dialogs/NotesAddDialog.jsx deleted file mode 100644 index 5c2dee2ca..000000000 --- a/client/src/js/views/dialogs/NotesAddDialog.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import * as Constant from '../../constants'; - -import { isBlank } from '../../utils/string'; - -class NotesAddDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onUpdate: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - note: PropTypes.object, - }; - - constructor(props) { - super(props); - - this.state = { - noteId: props.note.id || 0, - note: props.note.text || '', - concurrencyControlNumber: props.note.concurrencyControlNumber || 0, - noteError: '', - isNoLongerRelevant: false, - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.props.note.text !== this.state.note) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - noteError: '', - }); - - var valid = true; - - if (isBlank(this.state.note)) { - this.setState({ noteError: 'Note is required' }); - valid = false; - } - - return valid; - }; - - onFormSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - // If note id === 0 then you are adding a new note, otherwise you are updating an existing note - if (this.state.noteId === 0) { - this.props.onSave({ - id: 0, - text: this.state.note, - isNoLongerRelevant: false, - createDate: new Date().toISOString(), - }); - } else { - this.props.onUpdate({ - id: this.state.noteId, - text: this.state.note, - concurrencyControlNumber: this.state.concurrencyControlNumber, - isNoLongerRelevant: false, - }); - } - } else { - this.props.onClose(); - } - } - }; - - render() { - const { noteId } = this.state; - var maxLength = Constant.MAX_LENGTH_NOTE_TEXT; - - return ( - - - Note - - { this.state.noteError } -

Maximum { maxLength } characters.

-
-
- ); - } -} - -export default NotesAddDialog; diff --git a/client/src/js/views/dialogs/NotesDialog.jsx b/client/src/js/views/dialogs/NotesDialog.jsx deleted file mode 100644 index 813a815cb..000000000 --- a/client/src/js/views/dialogs/NotesDialog.jsx +++ /dev/null @@ -1,156 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { ButtonGroup, Button, Glyphicon, Alert } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import NotesAddDialog from './NotesAddDialog.jsx'; -import ModalDialog from '../../components/ModalDialog.jsx'; -import TableControl from '../../components/TableControl.jsx'; -import DeleteButton from '../../components/DeleteButton.jsx'; -import EditButton from '../../components/EditButton.jsx'; -import Authorize from '../../components/Authorize.jsx'; - -import { formatDateTimeUTCToLocal } from '../../utils/date'; - - -class NotesDialog extends React.Component { - static propTypes = { - id: PropTypes.string.isRequired, - show: PropTypes.bool, - notes: PropTypes.array, - // Api call to get notes for particular entity - getNotes: PropTypes.func.isRequired, - // Api function to call on save - saveNote: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - note: {}, - notes: props.notes || [], - }; - } - - componentWillReceiveProps(nextProps) { - if (!_.isEqual(this.props.notes, nextProps.notes)) { - this.setState({ notes: nextProps.notes }); - } - } - - openNotesAddDialog = () => { - this.setState({ showNotesAddDialog : true }); - }; - - closeNotesAddDialog = () => { - this.setState({ - note: {}, - showNotesAddDialog: false, - }); - }; - - onNoteAdded = (note) => { - this.setState({ notes: this.state.notes.concat([note]) }); - this.props.saveNote(this.props.id, note).then(() => { - this.props.getNotes(this.props.id); - }); - this.closeNotesAddDialog(); - }; - - onNoteUpdated = (note) => { - const noteId = note.id; - const updatedNotes = this.state.notes.map((_note) => { - return _note.id === noteId ? {..._note, ...note} : _note; - }); - - this.setState({ notes: updatedNotes }); - Api.updateNote(note).then(() => { - this.props.getNotes(this.props.id); - }); - this.closeNotesAddDialog(); - }; - - deleteNote = (note) => { - const noteId = note.id; - const updatedNotes = this.state.notes.filter((note) => { - return note.id !== noteId; - }); - - this.setState({ notes: updatedNotes }); - Api.deleteNote(note.id).then(() => { - this.props.getNotes(this.props.id); - }); - }; - - editNote = (note) => { - this.setState({ - note: note, - showNotesAddDialog: true, - }); - }; - - onClose = () => { - this.props.onClose(); - }; - - render() { - const notes = _.orderBy(this.state.notes, ['createDate'], ['desc']); - var headers = [ - { field: 'date', title: 'Date' }, - { field: 'note', title: 'Note' }, - { field: 'blank' }, - ]; - - const showNoNotesMessage = !notes || notes.length === 0; - - return ( - Notes}> - - { - notes.map((note) => { - return ( - - { formatDateTimeUTCToLocal(note.createDate, Constant.DATE_YEAR_SHORT_MONTH_DAY) } - { note.text } - - - - - - - - ); - }) - } - - {showNoNotesMessage && ( - No notes - )} - - - - { this.state.showNotesAddDialog && ( - - )} - - ); - } -} - -export default NotesDialog; diff --git a/client/src/js/views/dialogs/OvertimeRateEditDialog.jsx b/client/src/js/views/dialogs/OvertimeRateEditDialog.jsx deleted file mode 100644 index 910e47fe3..000000000 --- a/client/src/js/views/dialogs/OvertimeRateEditDialog.jsx +++ /dev/null @@ -1,138 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { FormGroup, HelpBlock, ControlLabel, Row, Col } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - -class OvertimeRateEditDialog extends React.Component { - static propTypes = { - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - overtimeRateType: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - rateId: props.overtimeRateType.id, - rateType: props.overtimeRateType.rateType || '', - description: props.overtimeRateType.description || '', - value: props.overtimeRateType.rate || 0, - concurrencyControlNumber: props.overtimeRateType.concurrencyControlNumber || 0, - descriptionError: '', - valueError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.description !== this.props.overtimeRateType.description) { return true; } - if (this.state.value !== this.props.overtimeRateType.value) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - descriptionError: '', - valueError: '', - }); - - var valid = true; - - if (isBlank(this.state.description)) { - this.setState({ descriptionError: 'Description is required' }); - valid = false; - } - - var moneyRegex = new RegExp(Constant.MONEY_REGEX); - if (isBlank(this.state.value)) { - this.setState({ valueError: 'Value is required' }); - valid = false; - } else if (this.state.value < 0) { - this.setState({ valueError: 'Value must be positive' }); - valid = false; - } else if (!moneyRegex.test(this.state.value)) { - this.setState({ valueError: 'Value must have at most 2 digits after the decimal' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var rateType = { - id: this.state.rateId, - rateType: this.state.rateType, - description: this.state.description, - rate: this.state.value.toFixed(2), - periodType: Constant.RENTAL_RATE_PERIOD_HOURLY, - concurrencyControlNumber: this.state.concurrencyControlNumber, - active: true, - }; - - const promise = Api.updateOvertimeRateType(rateType); - - promise.then(() => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - return ( - - - - - Description * - - { this.state.descriptionError } - - - - - Value * -
- $ - - per hour -
- { this.state.valueError } -
- -
-
- ); - } -} - -export default OvertimeRateEditDialog; diff --git a/client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx b/client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx deleted file mode 100644 index 3095bd539..000000000 --- a/client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx +++ /dev/null @@ -1,160 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; -import { OWNER_STATUS_CODE_APPROVED } from '../../constants'; - -const ARCHIVE_WARNING_MESSAGE = 'This action will archive the owner and all their equipment and remove them from the seniority list.'; - -class ChangeStatusDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - status: PropTypes.string.isRequired, - owner: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - onStatusChanged: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - comment: '', - commentError: '', - statusError: '', - archiveWarning: props.status === Constant.OWNER_STATUS_CODE_ARCHIVED ? ARCHIVE_WARNING_MESSAGE : '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - return true; - }; - - isValid = () => { - this.setState({ - commentError: '', - statusError: '', - }); - - var valid = true; - - if (isBlank(this.state.comment)) { - this.setState({ commentError: 'Comment is required' }); - valid = false; - } - - if (this.props.owner && this.props.status === OWNER_STATUS_CODE_APPROVED && (this.statusRequirements()).length > 0) { - this.setState({ statusError: this.statusRequirements() }); - valid = false; - } - - return valid; - }; - - statusRequirements = () => { - const { owner } = this.props; - var requirements = []; - - if (!owner.primaryContact) { - requirements.push('Primary contact'); - } - if (isBlank(owner.workSafeBCPolicyNumber)) { - requirements.push('WorkSafeBC policy number'); - } - if (!owner.address1 || !owner.city || !owner.province || !owner.province) { - requirements.push('Company address'); - } - if (!owner.meetsResidency) { - requirements.push('Meets residency'); - } - - return requirements; - }; - - formSubmitted = () => { - if (this.isValid()) { - this.setState({isSaving: true}); - const status = { - id: this.props.owner.id, - status: this.props.status, - statusComment: this.state.comment, - }; - var currentStatus = this.props.owner.status; - var equipmentList = { ...this.props.owner.equipmentList }; - - return Api.changeOwnerStatus(status).then(() => { - this.setState({isSaving: false}); - this.props.onStatusChanged(status); - Log.ownerModifiedStatus(this.props.owner, status.status, status.statusComment); - // If owner status goes from approved to unapproved/archived or unapproved to archived - // this will change all it's equipment statuses. This should be reflected in the equipment history. - if ( - (currentStatus === Constant.OWNER_STATUS_CODE_APPROVED || currentStatus === Constant.OWNER_STATUS_CODE_PENDING) - && (status.status === Constant.OWNER_STATUS_CODE_PENDING || status.status === Constant.OWNER_STATUS_CODE_ARCHIVED) - ) { - _.map(equipmentList, equipment => { - if (equipment.status !== status.status) { - Log.equipmentStatusModified(equipment, status.status, status.statusComment); - } - }); - } - }).catch((error) => { - if (error.status === 400 && error.errorCode === 'HETS-40') { - this.setState({ commentError: error.errorDescription }); - } else { - throw error; - } - }); - } - }; - - render() { - var statusErrorText = this.state.statusError && this.state.statusError.length <= 1 ? 'The following is also required:' : 'The following are also required:'; - var maxLength = Constant.MAX_LENGTH_STATUS_COMMENT; - - const archiving = this.props.status === Constant.OWNER_STATUS_CODE_ARCHIVED; - - return ( - - - Comment - - {this.state.commentError} -

Maximum { maxLength } characters.

- {this.state.statusError && statusErrorText} -
    - { - _.map(this.state.statusError, (error) => { - return
  • {error}
  • ; - }) - } -
-
- { archiving &&
{ this.state.archiveWarning }
} -
-
- ); - } -} - -export default ChangeStatusDialog; diff --git a/client/src/js/views/dialogs/OwnersAddDialog.jsx b/client/src/js/views/dialogs/OwnersAddDialog.jsx deleted file mode 100644 index 684b9481d..000000000 --- a/client/src/js/views/dialogs/OwnersAddDialog.jsx +++ /dev/null @@ -1,378 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import CheckboxControl from '../../components/CheckboxControl.jsx'; -import DropdownControl from '../../components/DropdownControl.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank, onlyLetters } from '../../utils/string'; - -const HELP_TEXT = { - prefix: 'This field must include only letters, up to 7 characters and be unique across all owners', - residency: 'You have not indicated the owner meets the Residency requirements of the HETS Program. If that is the case, the owner may not be registered in this local area until they have met this requirement. If this check was missed inadvertently, return and activate the checkbox. If the owner does not meet the residency requirement, return and cancel from the Add Owner popup.', -}; - -class OwnersAddDialog extends React.Component { - static propTypes = { - owners: PropTypes.object, - currentUser: PropTypes.object, - localAreas: PropTypes.object, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - name: '', - doingBusinessAs: '', - givenName: '', - surname: '', - address1: '', - address2: '', - city: '', - province: 'BC', - postalCode: '', - ownerCode: '', - // localAreaId: defaultLocalAreaId.id || 0, - localAreaId: 0, - isMaintenanceContractor: false, - meetsResidency: true, - registeredCompanyNumber: '', - workSafeBCPolicyNumber: '', - primaryContactPhone: '', - primaryContactGivenName: '', - primaryContactSurname: '', - primaryContactRole: '', - status: Constant.OWNER_STATUS_CODE_APPROVED, - - nameError: '', - ownerGivenNameError: '', - ownerSurameError: '', - address1Error: '', - cityError: '', - provinceError: '', - postalCodeError: '', - ownerCodeError: '', - localAreaError: '', - residencyError: '', - workSafeBCPolicyNumberError: '', - primaryContactPhoneError: '', - }; - } - - componentDidMount() { - Api.getOwnersLite(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.organizationName !== '') { return true; } - if (this.state.doingBusinessAs !== '') { return true; } - if (this.state.givenName !== '') { return true; } - if (this.state.surname !== '') { return true; } - if (this.state.address1 !== '') { return true; } - if (this.state.address2 !== '') { return true; } - if (this.state.city !== '') { return true; } - if (this.state.province !== 'BC') { return true; } - if (this.state.postalCode !== '') { return true; } - if (this.state.ownerCode !== '') { return true; } - if (this.state.localAreaId !== 0) { return true; } - if (this.state.registeredCompanyNumber !== '') { return true; } - if (this.state.workSafeBCPolicyNumber != '') { return true; } - if (this.state.primaryContactGivenName !== '') { return true; } - if (this.state.primaryContactSurname !== '') { return true; } - if (this.state.primaryContactPhone !== '') { return true; } - if (this.state.primaryContactRole !== '') { return true; } - if (this.state.status != Constant.OWNER_STATUS_CODE_APPROVED) { return true; } - - return false; - }; - - isValid = () => { - // Clear out any previous errors - var valid = true; - - this.setState({ - nameError: '', - address1Error: '', - cityError: '', - provinceError: '', - postalCodeError: '', - ownerCodeError: '', - localAreaError: '', - residencyError: '', - workSafeBCPolicyNumberError: '', - primaryContactGivenNameError: '', - primaryContactPhoneError: '', - }); - - if (isBlank(this.state.name)) { - this.setState({ nameError: 'Name is required' }); - valid = false; - } else { - // Does the name already exist? - var nameIgnoreCase = this.state.name.toLowerCase().trim(); - var other = _.find(this.props.owners.data, (other) => other.organizationName.toLowerCase().trim() === nameIgnoreCase); - if (other) { - this.setState({ nameError: 'This company name already exists in the system' }); - valid = false; - } - } - - if (isBlank(this.state.givenName)) { - this.setState({ ownerGivenNameError: 'Owner first name is required' }); - valid = false; - } - - if (isBlank(this.state.surname)) { - this.setState({ ownerSurameError: 'Owner last name is required' }); - valid = false; - } - - if (isBlank(this.state.address1)) { - this.setState({ address1Error: 'Address line 1 is required' }); - valid = false; - } - - if (isBlank(this.state.city)) { - this.setState({ cityError: 'City is required' }); - valid = false; - } - - if (isBlank(this.state.province)) { - this.setState({ provinceError: 'Province is required' }); - valid = false; - } - - if (isBlank(this.state.postalCode)) { - this.setState({ postalCodeError: 'Postal code is required' }); - valid = false; - } else if (!Constant.POSTAL_CODE_REGEX.test(this.state.postalCode)) { - this.setState({ postalCodeError: 'Invalid postal code' }); - valid = false; - } - - if (isBlank(this.state.ownerCode)) { - this.setState({ ownerCodeError: 'Owner code is required' }); - valid = false; - } else { - var code = this.state.ownerCode.toLowerCase().trim(); - - // Must only include letters, up to 7 characters - if (!onlyLetters(code) || code.length > 7) { - this.setState({ ownerCodeError: 'This owner code must only include letters, up to 7 characters, and has to be unique to each owner' }); - valid = false; - } - } - - if (this.state.localAreaId === 0) { - this.setState({ localAreaError: 'Service area / local area is required' }); - valid = false; - } - - if (this.state.meetsResidency === false) { - this.setState({ residencyError: HELP_TEXT.residency }); - valid = false; - } - - if (isBlank(this.state.workSafeBCPolicyNumber)) { - this.setState({ workSafeBCPolicyNumberError: 'WCB number is required' }); - valid = false; - } - - if (isBlank(this.state.primaryContactGivenName)) { - this.setState({ primaryContactGivenNameError: 'First name is required' }); - valid = false; - } - - if (isBlank(this.state.primaryContactPhone)) { - this.setState({ primaryContactPhoneError: 'Phone number is required' }); - valid = false; - } else if (!Constant.NANP_REGEX.test(this.state.primaryContactPhone)) { - this.setState({ primaryContactPhoneError: 'Invalid phone number' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var owner = { - organizationName: this.state.name, - doingBusinessAs: this.state.doingBusinessAs, - givenName: this.state.givenName, - surname: this.state.surname, - address1: this.state.address1, - address2: this.state.address2, - city: this.state.city, - province: this.state.province, - postalCode: this.state.postalCode, - ownerCode: this.state.ownerCode, - localArea: { id: this.state.localAreaId }, - isMaintenanceContractor: this.state.isMaintenanceContractor, - meetsResidency: this.state.meetsResidency, - registeredCompanyNumber: this.state.registeredCompanyNumber, - workSafeBCPolicyNumber: this.state.workSafeBCPolicyNumber, - primaryContactGivenName: this.state.primaryContactGivenName, - primaryContactSurname: this.state.primaryContactSurname, - primaryContactPhone: this.state.primaryContactPhone, - primaryContactRole: this.state.primaryContactRole, - status: this.state.status, - }; - - const promise = Api.addOwner(owner); - - promise.then((newOwner) => { - Log.ownerAdded(newOwner); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(newOwner); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - // Constrain the local area drop downs to those in the District of the current logged in user - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - return ( - - - Company Name * - - { this.state.nameError } - - - Doing Business As - - - - Owner First Name * - - { this.state.ownerGivenNameError } - - - Owner Last Name * - - { this.state.ownerSurameError } - - - Address Line 1 * - - { this.state.address1Error } - - - Address Line 2 - - - - City * - - { this.state.cityError } - - - Province * - - { this.state.provinceError } - - - Postal Code * - - { this.state.postalCodeError } - - - Owner Code * - - { this.state.ownerCodeError || HELP_TEXT.prefix } - - - Service Area - Local Area * - - { this.state.localAreaError } - - - WCB Number * - - { this.state.workSafeBCPolicyNumberError } - - - Primary Contact First Name * - - { this.state.primaryContactGivenNameError } - - - Primary Contact Last Name - - - - Primary Contact Phone * - - { this.state.primaryContactPhoneError } - - - Primary Contact Role - - - - Status - - - - Registered BC Company Number - - - - Maintenance Contractor - - - Meets Residency - { this.state.residencyError } - - - ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - owners: state.lookups.owners.lite, - localAreas: state.lookups.localAreas, - }; -} - -export default connect(mapStateToProps)(OwnersAddDialog); diff --git a/client/src/js/views/dialogs/OwnersEditDialog.jsx b/client/src/js/views/dialogs/OwnersEditDialog.jsx deleted file mode 100644 index fad95c515..000000000 --- a/client/src/js/views/dialogs/OwnersEditDialog.jsx +++ /dev/null @@ -1,267 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import CheckboxControl from '../../components/CheckboxControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - - -class OwnersEditDialog extends React.Component { - static propTypes = { - owner: PropTypes.object, - owners: PropTypes.object, - localAreas: PropTypes.object, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - var owner = props.owner; - - this.state = { - organizationName: owner.organizationName || '', - givenName: owner.givenName || '', - surname: owner.surname || '', - address1: owner.address1 || '', - address2: owner.address2 || '', - city: owner.city || '', - province: owner.province || '', - postalCode: owner.postalCode || '', - localAreaId: owner.localArea.id || 0, - isMaintenanceContractor: owner.isMaintenanceContractor || false, - doingBusinessAs: owner.doingBusinessAs || '', - registeredCompanyNumber: owner.registeredCompanyNumber || '', - status: owner.status || '', - - address1Error: '', - cityError: '', - provinceError: '', - postalCodeError: '', - organizationNameError: '', - localAreaError: '', - localAreaSeniorityChangeWarning: false, - }; - } - - componentDidMount() { - Api.getOwnersLite(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - var owner = this.props.owner; - - if (this.state.organizationName !== owner.organizationName) { return true; } - if (this.state.givenName !== owner.givenName) { return true; } - if (this.state.surname !== owner.surname) { return true; } - if (this.state.address1 !== owner.address1) { return true; } - if (this.state.address2 !== owner.address2) { return true; } - if (this.state.city !== owner.city) { return true; } - if (this.state.province !== owner.province) { return true; } - if (this.state.postalCode !== owner.postalCode) { return true; } - if (this.state.localAreaId !== owner.localArea.id) { return true; } - if (this.state.doingBusinessAs !== owner.doingBusinessAs) { return true; } - if (this.state.registeredCompanyNumber !== owner.registeredCompanyNumber) { return true; } - if (this.state.isMaintenanceContractor !== owner.isMaintenanceContractor) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - companyAddressError: '', - organizationNameError: '', - localAreaError: '', - }); - - var valid = true; - var owner = this.props.owner; - var orgName = this.state.organizationName; - - if (isBlank(orgName)) { - this.setState({ organizationNameError: 'Company name is required' }); - valid = false; - } else if (orgName !== owner.organizationName) { - // Does the name already exist? - var nameIgnoreCase = orgName.toLowerCase().trim(); - var otherOwners = _.reject(this.props.owners.data, { id: owner.id }); - var other = _.find(otherOwners, other => other.organizationName.toLowerCase().trim() === nameIgnoreCase); - if (other) { - this.setState({ organizationNameError: 'This company name already exists in the system' }); - valid = false; - } - } - - if (isBlank(this.state.address1)) { - this.setState({ address1Error: 'Address line 1 is required' }); - valid = false; - } - - if (isBlank(this.state.city)) { - this.setState({ cityError: 'City is required' }); - valid = false; - } - - if (isBlank(this.state.province)) { - this.setState({ provinceError: 'Province is required' }); - valid = false; - } - - if (isBlank(this.state.postalCode)) { - this.setState({ postalCodeError: 'Postal code is required' }); - valid = false; - } else if (!Constant.POSTAL_CODE_REGEX.test(this.state.postalCode)) { - this.setState({ postalCodeError: 'Invalid postal code' }); - valid = false; - } - - if (this.state.localAreaId === 0) { - this.setState({ localAreaError: 'Service area / local area is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const owner = { - ...this.props.owner, - organizationName: this.state.organizationName, - givenName: this.state.givenName, - surname: this.state.surname, - address1: this.state.address1, - address2: this.state.address2, - city: this.state.city, - province: this.state.province, - postalCode: this.state.postalCode, - localArea: { id: this.state.localAreaId }, - isMaintenanceContractor: this.state.isMaintenanceContractor, - doingBusinessAs: this.state.doingBusinessAs, - registeredCompanyNumber: this.state.registeredCompanyNumber, - status: this.state.status, - }; - - Api.updateOwner(owner).then(() => { - if (this.props.onSave) { this.props.onSave(); } - }); - } - - this.props.onClose(); - } - }; - - onLocalAreaChanged() { - if (this.state.localAreaId !== this.props.owner.localArea.id) { - this.setState({ - localAreaError: 'This action will change the local area and seniority of all the equipment for this owner.', - localAreaSeniorityChangeWarning: true, - }); - } else { - this.setState({ - localAreaError: '', - localAreaSeniorityChangeWarning: false, - }); - } - } - - render() { - var owner = this.props.owner; - var localAreas = _.sortBy(this.props.localAreas, 'name'); - - const saveWarning = this.state.localAreaSeniorityChangeWarning; - - return ( - - - Owner Code -

{ owner.ownerCode }

-
- - Company Name * - - { this.state.organizationNameError } - - - Doing Business As - - - - Owner First Name - - - - Owner Last Name - - - - Address Line 1 * - - { this.state.address1Error } - - - Address Line 2 - - - - City * - - { this.state.cityError } - - - Province * - - { this.state.provinceError } - - - Postal Code * - - { this.state.postalCodeError } - - - Service Area - Local Area * - this.updateState(state, this.onLocalAreaChanged) } className="full-width" /> - { this.state.localAreaError } - - - Registered BC Company Number - - - - Maintenance Contractor - -
- ); - } -} - -function mapStateToProps(state) { - return { - owners: state.lookups.owners.lite, - localAreas: state.lookups.localAreas, - }; -} - -export default connect(mapStateToProps)(OwnersEditDialog); diff --git a/client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx b/client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx deleted file mode 100644 index 122da07b6..000000000 --- a/client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormGroup, ControlLabel, HelpBlock, Row, Col } from 'react-bootstrap'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import DateControl from '../../components/DateControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isValidDate, toZuluTime } from '../../utils/date'; -import { notBlank, isBlank } from '../../utils/string'; - - -class OwnersPolicyEditDialog extends React.Component { - static propTypes = { - owner: PropTypes.object, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - var owner = props.owner; - - this.state = { - workSafeBCPolicyNumber: owner.workSafeBCPolicyNumber || '', - workSafeBCExpiryDate: owner.workSafeBCExpiryDate || '', - cglCompanyName: owner.cglCompanyName || '', - cglPolicyNumber: owner.cglPolicyNumber || '', - cglEndDate: owner.cglEndDate || '', - - workSafeBCPolicyNumberError: '', - workSafeBCExpiryDateError: '', - cglEndDateError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - var owner = this.props.owner; - - if (this.state.workSafeBCPolicyNumber !== owner.workSafeBCPolicyNumber) { return true; } - if (this.state.workSafeBCExpiryDate !== owner.workSafeBCExpiryDate) { return true; } - if (this.state.cglCompanyName !== owner.cglCompanyName) { return true; } - if (this.state.cglPolicyNumber !== owner.cglPolicyNumber) { return true; } - if (this.state.cglEndDate !== owner.cglEndDate) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - workSafeBCPolicyNumberError: '', - workSafeBCExpiryDateError: '', - cglEndDateError: '', - }); - - var valid = true; - - if (isBlank(this.state.workSafeBCPolicyNumber)) { - this.setState({ workSafeBCPolicyNumberError: 'WBC is required' }); - valid = false; - } - - if (notBlank(this.state.workSafeBCExpiryDate) && !isValidDate(this.state.workSafeBCExpiryDate)) { - this.setState({ workSafeBCExpiryDateError: 'Date not valid' }); - valid = false; - } - - if (notBlank(this.state.cglEndDate) && !isValidDate(this.state.cglEndDate)) { - this.setState({ cglEndDateError: 'Date not valid' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const owner = { - ...this.props.owner, - workSafeBCPolicyNumber: this.state.workSafeBCPolicyNumber, - workSafeBCExpiryDate: toZuluTime(this.state.workSafeBCExpiryDate), - cglCompanyName: this.state.cglCompanyName, - cglPolicyNumber: this.state.cglPolicyNumber, - cglEndDate: toZuluTime(this.state.cglEndDate), - }; - - Api.updateOwner(owner).then(() => { - if (this.props.onSave) { this.props.onSave(); } - }); - } - - this.props.onClose(); - } - }; - - render() { - return ( - - - - - WCB Number * - - { this.state.workSafeBCPolicyNumberError } - - - - - WCB Expiry Date - - { this.state.workSafeBCExpiryDateError } - - - - - - - CGL Insurance Company - - - - - - - - CGL Policy Number - - - - - - CGL Policy End Date - - { this.state.cglEndDateError } - - - - - ); - } -} - -export default OwnersPolicyEditDialog; diff --git a/client/src/js/views/dialogs/ProjectsAddDialog.jsx b/client/src/js/views/dialogs/ProjectsAddDialog.jsx deleted file mode 100644 index 51e08c592..000000000 --- a/client/src/js/views/dialogs/ProjectsAddDialog.jsx +++ /dev/null @@ -1,266 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import _ from 'lodash'; -import { FormGroup, HelpBlock, ControlLabel, FormControl, Grid, Row, Col } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank, notBlank } from '../../utils/string'; - -class ProjectsAddDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - projects: PropTypes.object, - fiscalYears: PropTypes.array, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - name: '', - fiscalYear: _.first(_.takeRight(props.fiscalYears, 2)), - provincialProjectNumber: '', - responsibilityCentre: '', - serviceLine: '', - stob: '', - product: '', - businessFunction: '', - workActivity: '', - costType: '', - information: '', - - nameError: '', - fiscalYearError: '', - provincialProjectNumberError: '', - }; - } - - componentDidMount() { - Api.getProjects(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - return notBlank(this.state.name) || - notBlank(this.state.fiscalYear) || - notBlank(this.state.provincialProjectNumber) || - notBlank(this.state.responsibilityCentre) || - notBlank(this.state.serviceLine) || - notBlank(this.state.stob) || - notBlank(this.state.product) || - notBlank(this.state.businessFunction) || - notBlank(this.state.workActivity) || - notBlank(this.state.costType) || - notBlank(this.state.information); - }; - - isValid = () => { - // Clear out any previous errors - var valid = true; - - this.setState({ - nameError: '', - fiscalYearError: '', - provincialProjectNumberError: '', - }); - - const { name, fiscalYear, provincialProjectNumber } = this.state; - - if (isBlank(name)) { - this.setState({ nameError: 'Project name is required' }); - valid = false; - } - - if (isBlank(fiscalYear)) { - this.setState({ fiscalYearError: 'Fiscal year is required' }); - valid = false; - } - - if (isBlank(provincialProjectNumber)) { - this.setState({ provincialProjectNumberError: 'Provincial project number is required' }); - valid = false; - } - - if (!valid) { - return false; - } - - const duplicateProject = _.find(this.props.projects.data, project => { - return project.name.toLowerCase().trim() === name.toLowerCase().trim() && - project.fiscalYear.toLowerCase().trim() === fiscalYear.toLowerCase().trim() && - project.provincialProjectNumber.toLowerCase().trim() === provincialProjectNumber.toLowerCase().trim(); - }); - - if (duplicateProject) { - this.setState({ nameError: 'A project with the same name and project number exists for the selected fiscal year.'}); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var project = { - name: this.state.name, - fiscalYear: this.state.fiscalYear, - provincialProjectNumber: this.state.provincialProjectNumber, - district: { id: this.props.currentUser.district.id }, - status: Constant.PROJECT_STATUS_CODE_ACTIVE, - responsibilityCentre: this.state.responsibilityCentre, - serviceLine: this.state.serviceLine, - stob: this.state.stob, - product: this.state.product, - businessFunction: this.state.businessFunction, - workActivity: this.state.workActivity, - costType: this.state.costType, - information: this.state.information, - }; - - const promise = Api.addProject(project); - - promise.then((newProject) => { - Log.projectAdded(newProject); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(newProject); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - return ( - - - - - - Project Name * - - { this.state.nameError } - - - - - - - District - { this.props.currentUser.district.name } - - - - - Fiscal Year * - - { this.state.fiscalYearError } - - - - - - - Provincial Project Number * - - { this.state.provincialProjectNumberError } - - - - - Responsibility Centre - - - - - - - - Service Line - - - - - - STOB - - - - - - - - Product - - - - - - Business Function - - - - - - - - Work Activity - - - - - - Cost Type - - - - - - - - Project Information - - - - - - - ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - projects: state.lookups.projects, - fiscalYears: state.lookups.fiscalYears, - }; -} - -export default connect(mapStateToProps)(ProjectsAddDialog); diff --git a/client/src/js/views/dialogs/ProjectsEditDialog.jsx b/client/src/js/views/dialogs/ProjectsEditDialog.jsx deleted file mode 100644 index 6b3236f63..000000000 --- a/client/src/js/views/dialogs/ProjectsEditDialog.jsx +++ /dev/null @@ -1,267 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { connect } from 'react-redux'; - -import { Grid, Row, Col, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import _ from 'lodash'; - -import * as Action from '../../actionTypes'; -import * as Api from '../../api'; -import * as Log from '../../history'; -import store from '../../store'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; -import Form from '../../components/Form.jsx'; - -import { isBlank } from '../../utils/string'; - -class ProjectsEditDialog extends React.Component { - static propTypes = { - fiscalYears: PropTypes.array, - project: PropTypes.object, - projects: PropTypes.object, - - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - name: props.project.name || '', - fiscalYear: props.project.fiscalYear || _.first( _.takeRight(props.fiscalYears, 2)), - provincialProjectNumber: props.project.provincialProjectNumber || '', - responsibilityCentre: props.project.responsibilityCentre || '', - serviceLine: props.project.serviceLine || '', - stob: props.project.stob || '', - product: props.project.product || '', - businessFunction: props.project.businessFunction || '', - workActivity: props.project.workActivity || '', - costType: props.project.costType || '', - projectInformation: props.project.information || '', - concurrencyControlNumber: props.project.concurrencyControlNumber || 0, - nameError: '', - fiscalYearError: '', - provincialProjectNumberError: '', - }; - } - - componentDidMount() { - Api.getProjects(); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - var project = this.props.project; - - if (this.state.name !== project.name) { return true; } - if (this.state.fiscalYear !== project.fiscalYear) { return true; } - if (this.state.provincialProjectNumber !== project.provincialProjectNumber) { return true; } - if (this.state.responsibilityCentre !== project.responsibilityCentre) { return true; } - if (this.state.serviceLine !== project.serviceLine) { return true; } - if (this.state.stob !== project.stob) { return true; } - if (this.state.product !== project.product) { return true; } - if (this.state.businessFunction !== project.businessFunction) { return true; } - if (this.state.workActivity !== project.workActivity) { return true; } - if (this.state.costType !== project.costType) { return true; } - if (this.state.projectInformation !== project.information) { return true; } - - return false; - }; - - isValid = () => { - var valid = true; - - this.setState({ - nameError: '', - fiscalYearError: '', - provincialProjectNumberError: '', - }); - - const { name, fiscalYear, provincialProjectNumber } = this.state; - - if (isBlank(name)) { - this.setState({ nameError: 'Project name is required' }); - valid = false; - } - - if (isBlank(fiscalYear)) { - this.setState({ fiscalYearError: 'Fiscal year is required' }); - valid = false; - } - - if (isBlank(provincialProjectNumber)) { - this.setState({ provincialProjectNumberError: 'Provincial project number is required' }); - valid = false; - } - - if (!valid) { - return false; - } - - const duplicateProject = _.find(this.props.projects.data, project => { - return project.id !== this.props.project.id && - project.name.toLowerCase().trim() === name.toLowerCase().trim() && - project.fiscalYear.toLowerCase().trim() === fiscalYear.toLowerCase().trim() && - project.provincialProjectNumber.toLowerCase().trim() === provincialProjectNumber.toLowerCase().trim(); - }); - - if (duplicateProject) { - this.setState({ nameError: 'A project with the same name and project number exists for the selected fiscal year.'}); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const project = { - ...this.props.project, - id: this.props.project.id, - district: this.props.project.district, - name: this.state.name, - fiscalYear: this.state.fiscalYear, - provincialProjectNumber: this.state.provincialProjectNumber, - responsibilityCentre: this.state.responsibilityCentre, - serviceLine: this.state.serviceLine, - stob: this.state.stob, - product: this.state.product, - businessFunction: this.state.businessFunction, - workActivity: this.state.workActivity, - costType: this.state.costType, - information: this.state.projectInformation, - concurrencyControlNumber: this.state.concurrencyControlNumber, - }; - - store.dispatch({ type: Action.UPDATE_PROJECT, project }); - - Log.projectModified(this.props.project); - - Api.updateProject(project); - } - - this.props.onClose(); - } - }; - - render() { - // TODO: Restrict Information box resize - return ( - -
- - - - - Project Name * - - { this.state.nameError } - - - - - - - Fiscal Year * - - { this.state.fiscalYearError } - - - - - Provincial Project Number * - - { this.state.provincialProjectNumberError } - - - - - - - Responsibility Centre - - - - - - - - Service Line - - - - - - STOB - - - - - - - - Product - - - - - - Business Function - - - - - - - - Work Activity - - - - - - Cost Type - - - - - - - - Project Information - - - - - -
-
- ); - } -} - -function mapStateToProps(state) { - return { - fiscalYears: state.lookups.fiscalYears, - projects: state.lookups.projects, - }; -} - -export default connect(mapStateToProps)(ProjectsEditDialog); diff --git a/client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx b/client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx deleted file mode 100644 index 2e8c47ad0..000000000 --- a/client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx +++ /dev/null @@ -1,109 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Grid, Row, Col, FormGroup, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import CheckboxControl from '../../components/CheckboxControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - - -class RentalAgreementOvertimeNotesDialog extends React.Component { - static propTypes = { - show: PropTypes.bool.isRequired, - rentalAgreement: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - overtime: _.some(props.rentalAgreement.overtimeRates, 'active'), - overtimeRates: props.rentalAgreement.overtimeRates || [], - note: props.rentalAgreement.note || '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - return true; - }; - - isValid = () => { - return true; - }; - - formSubmitted = () => { - const { onSave, onClose } = this.props; - if (this.isValid()) { - if (this.didChange()) { - const rentalAgreement = { - ...this.props.rentalAgreement, - overtimeRates: this.state.overtimeRates, - note: this.state.note, - }; - - Api.updateRentalAgreement(rentalAgreement).then(() => { - if (onSave) { onSave(); } - }); - } - - onClose(); - } - }; - - overtimeCheckboxChanged = (e) => { - var active = e.target.checked; - - var overtimeRates = _.map(this.state.overtimeRates, rate => ({ ...rate, active: active })); - - this.setState({ overtimeRates: overtimeRates }); - }; - - render() { - const maxNoteLength = Constant.MAX_LENGTH_RENTAL_AGREEMENT_NOTE; - const rates = _.orderBy(this.state.overtimeRates, ['rate']); - - return ( - - - - - Overtime Rates -
- - { - _.map(rates, rate => rate.comment).join(', ') - } - -
- - - - Notes/Special Instructions - -

Maximum { maxNoteLength } characters.

-
- -
-
-
- ); - } -} - -export default RentalAgreementOvertimeNotesDialog; diff --git a/client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx b/client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx deleted file mode 100644 index fbc8bc9c4..000000000 --- a/client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx +++ /dev/null @@ -1,150 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Row, Col } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; - -import DateControl from '../../components/DateControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isValidDate } from '../../utils/date'; -import { isBlank, notBlank } from '../../utils/string'; - - -class RentalAgreementsEditDialog extends React.Component { - static propTypes = { - rentalAgreement: PropTypes.object.isRequired, - show: PropTypes.bool, - owner: PropTypes.object, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - estimateStartWork: props.rentalAgreement.estimateStartWork || '', - estimateHours: props.rentalAgreement.estimateHours || 0, - datedOn: props.rentalAgreement.datedOn || '', - agreementCity: props.rentalAgreement.agreementCity || '', - - estimateStartWorkError: '', - estimateHoursError: '', - datedOnError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.estimateStartWork !== this.props.rentalAgreement.estimateStartWork) { return true; } - if (this.state.estimateHours !== this.props.rentalAgreement.estimateHours) { return true; } - if (this.state.datedOn !== this.props.rentalAgreement.datedOn) { return true; } - if (this.state.note !== this.props.rentalAgreement.note) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - estimateStartWorkError: '', - estimateHoursError: '', - datedOnError: '', - }); - - var valid = true; - - if (notBlank(this.state.estimateStartWork) && !isValidDate(this.state.estimateStartWork)) { - this.setState({ estimateStartWorkError: 'Date not valid' }); - valid = false; - } - - if (notBlank(this.state.datedOn) && !isValidDate(this.state.datedOn)) { - this.setState({ datedOnError: 'Date not valid' }); - valid = false; - } - - if (isBlank(this.state.estimateHours)) { - this.setState({ estimateHoursError: 'Estimated hours are required' }); - valid = false; - } else if (this.state.estimateHours < 1) { - this.setState({ estimateHoursError: 'Estimated hours not valid' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const rentalAgreement = { - ...this.props.rentalAgreement, - estimateStartWork: this.state.estimateStartWork, - estimateHours: this.state.estimateHours, - datedOn: this.state.datedOn, - agreementCity: this.state.agreementCity, - }; - - Api.updateRentalAgreement(rentalAgreement).then(() => { - if (this.props.onSave) { this.props.onSave(); } - }); - } - - this.props.onClose(); - } - }; - - render() { - // Read-only if the user cannot edit the rental agreement - var isReadOnly = !this.props.rentalAgreement.canEdit && this.props.rentalAgreement.id !== 0; - - return ( - - - - - Estimated Commencement - - { this.state.estimateStartWorkError } - - - - - Estimated Period Hours * - - { this.state.estimateHoursError } - - - - - - - Dated On - - { this.state.datedOnError } - - - - - Dated At - - - - - - ); - } -} - -export default RentalAgreementsEditDialog; diff --git a/client/src/js/views/dialogs/RentalConditionsEditDialog.jsx b/client/src/js/views/dialogs/RentalConditionsEditDialog.jsx deleted file mode 100644 index b7304b936..000000000 --- a/client/src/js/views/dialogs/RentalConditionsEditDialog.jsx +++ /dev/null @@ -1,210 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; -import { NON_STANDARD_CONDITION } from '../../constants'; - - -class RentalConditionsEditDialog extends React.Component { - static propTypes = { - show: PropTypes.bool.isRequired, - rentalAgreementId: PropTypes.number.isRequired, - rentalCondition: PropTypes.object.isRequired, - rentalConditions: PropTypes.object.isRequired, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isNew: props.rentalCondition.id === 0, - - forms: [{ - conditionName: props.rentalCondition.conditionName || '', - comment: props.rentalCondition.comment || '', - - conditionNameError: '', - commentError: '', - }], - concurrencyControlNumber: props.rentalCondition.concurrencyControlNumber || 0, - }; - } - - componentDidMount() { - Api.getRentalConditions(); - } - - updateState = (value) => { - let property = Object.keys(value)[0]; - let stateValue = _.values(value)[0]; - let number = property.match(/\d+/g)[0]; - let stateName = property.match(/[a-zA-Z]+/g)[0]; - let state = { [stateName]: stateValue }; - const updatedForms = this.state.forms.slice(); - updatedForms.splice(number, 1, { ...updatedForms[number], ...state}); - this.setState({ forms: updatedForms }); - }; - - didChange = () => { - return true; - }; - - isValid = () => { - const forms = this.state.forms.slice(); - - forms.forEach((form, i) => { - let state = { - ...form, - conditionNameError: '', - commentError: '', - }; - forms[i] = state; - }); - - let valid = true; - - forms.forEach((form, i) => { - if (form.conditionName === NON_STANDARD_CONDITION && isBlank(form.comment)) { - forms[i] = { ...form, commentError: 'Comment is required for non-standard conditions.' }; - valid = false; - } - - if (isBlank(form.conditionName)) { - forms[i] = { ...form, conditionNameError: 'Rental condition is required' }; - valid = false; - } - }); - - this.setState({ forms }); - - return valid; - }; - - formSubmitted = () => { - const { rentalAgreementId, onSave, onClose } = this.props; - - if (this.isValid()) { - if (this.didChange()) { - const forms = this.state.forms; - const conditions = forms.map((form) => { - return { - id: this.props.rentalCondition.id || 0, - rentalAgreement: { id: rentalAgreementId }, - conditionName: form.conditionName, - comment: form.conditionName === NON_STANDARD_CONDITION ? form.comment : '', - concurrencyControlNumber: this.state.concurrencyControlNumber, - }; - }); - - (this.state.isNew ? Api.addRentalConditions(rentalAgreementId, conditions) : Api.updateRentalCondition(_.first(conditions))).then(() => { - if (onSave) { onSave(); } - }); - } - onClose(); - } - }; - - addInput = () => { - if (this.state.forms.length < 10) { - const forms = this.state.forms.slice(); - forms.push({ - conditionName: '', - comment: '', - conditionNameError: '', - commentError: '', - }); - - this.setState({ forms }); - } - }; - - removeInput = () => { - if (this.state.forms.length > 1) { - const forms = this.state.forms.slice(); - forms.pop(); - this.setState({ forms }); - } - }; - - render() { - // Read-only if the user cannot edit the rental agreement - var isReadOnly = !this.props.rentalCondition.canEdit && this.props.rentalCondition.id !== 0; - var conditions = _.map([ ...this.props.rentalConditions.data, { description: NON_STANDARD_CONDITION } ], 'description'); - - return ( - -
- { this.state.forms.map((form, i) => ( -
-
- - Conditions * - {/*TODO - use lookup list*/} - - { form.conditionNameError } - -
- { form.conditionName === NON_STANDARD_CONDITION && ( -
- - Comment * - - { form.commentError } - -
- )} -
- ))} -
-
- { this.state.isNew && this.state.forms.length > 1 && ( - - )} - { this.state.isNew && this.state.forms.length < 10 && ( - - )} -
-
- ); - } -} - - -function mapStateToProps(state) { - return { - rentalConditions: state.lookups.rentalConditions, - }; -} - -export default connect(mapStateToProps)(RentalConditionsEditDialog); diff --git a/client/src/js/views/dialogs/RentalRatesEditDialog.jsx b/client/src/js/views/dialogs/RentalRatesEditDialog.jsx deleted file mode 100644 index 77b8ecd21..000000000 --- a/client/src/js/views/dialogs/RentalRatesEditDialog.jsx +++ /dev/null @@ -1,258 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { Row, Col } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - -const ratePeriods = [ - Constant.RENTAL_RATE_PERIOD_HOURLY, - Constant.RENTAL_RATE_PERIOD_DAILY, - Constant.RENTAL_RATE_PERIOD_WEEKLY, - Constant.RENTAL_RATE_PERIOD_MONTHLY, - Constant.RENTAL_RATE_PERIOD_NEGOTIATED, -]; - -class RentalRatesEditDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - rentalRate: PropTypes.object.isRequired, - rentalAgreement: PropTypes.object, - provincialRateTypes: PropTypes.array, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - const ratePeriod = props.rentalRate.id === 0 ? - props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY : - props.rentalRate.ratePeriod; - - this.state = { - isNew: props.rentalRate.id === 0, - - forms: [{ - isIncludedInTotal: props.rentalRate.isIncludedInTotal || false, - rateType: {}, - rate: props.rentalRate.rate || 0.0, - ratePeriod: ratePeriod, - uiRatePeriod: props.rentalRate.set ? Constant.RENTAL_RATE_PERIOD_SET : ratePeriod, - set: props.rentalRate.set || false, - comment: props.rentalRate.comment || '', - - componentNameError: '', - rateError: '', - commentError: '', - }], - concurrencyControlNumber: props.rentalRate.concurrencyControlNumber || 0, - }; - } - - updateState = (value) => { - let property = Object.keys(value)[0]; - let stateValue = _.values(value)[0]; - let number = property.match(/\d+/g)[0]; - let stateName = property.match(/[a-zA-Z]+/g)[0]; - let state = { [stateName]: stateValue }; - const updatedForms = this.state.forms.slice(); - updatedForms.splice(number, 1, { ...updatedForms[number], ...state}); - this.setState({ forms: updatedForms }); - }; - - updateUiRatePeriod = (value, index) => { - const uiRatePeriod = _.values(value)[0]; - const updatedForms = this.state.forms.slice(); - const state = { - uiRatePeriod: uiRatePeriod, - set: uiRatePeriod === Constant.RENTAL_RATE_PERIOD_SET, - ratePeriod: uiRatePeriod === Constant.RENTAL_RATE_PERIOD_SET ? this.props.rentalAgreement.ratePeriod : uiRatePeriod, - }; - updatedForms.splice(index, 1, { ...updatedForms[index], ...state}); - this.setState({ forms: updatedForms }); - }; - - didChange = () => { - return true; - }; - - isValid = () => { - const forms = this.state.forms.slice(); - - forms.forEach((form, i) => { - let state = { - ...form, - rateError: '', - commentError: '', - }; - forms[i] = state; - }); - - let valid = true; - - forms.forEach((form, i) => { - if (isBlank(form.comment)) { - forms[i] = { ...forms[i], commentError: 'Comment is required.' }; - valid = false; - } - - if (isBlank(form.rate) ) { - forms[i] = { ...forms[i], rateError: 'Pay rate is required' }; - valid = false; - } else if (form.rate < 0) { - forms[i] = { ...forms[i], rateError: 'Pay rate not valid' }; - valid = false; - } - }); - - this.setState({ forms }); - - return valid; - }; - - formSubmitted = () => { - const { rentalAgreement, onSave, onClose } = this.props; - - if (this.isValid()) { - if (this.didChange()) { - const forms = this.state.forms; - const rates = forms.map((form) => { - return { - id: this.props.rentalRate.id || 0, - rentalAgreement: { id: this.props.rentalRate.rentalAgreement.id }, - rate: form.rate, - ratePeriod: form.ratePeriod, - comment: form.comment, - set: form.set, - isIncludedInTotal: this.props.rentalRate.isIncludedInTotal, - concurrencyControlNumber: this.state.concurrencyControlNumber, - }; - }); - - (this.state.isNew ? Api.addRentalRates(rentalAgreement.id, rates) : Api.updateRentalRate(_.first(rates))).then(() => { - if (onSave) { onSave(); } - }); - } - - onClose(); - } - }; - - addInput = () => { - if (this.state.forms.length < 10) { - const forms = this.state.forms.slice(); - - const ratePeriod = this.props.rentalAgreement.ratePeriod || Constant.RENTAL_RATE_PERIOD_HOURLY; - - forms.push({ - isIncludedInTotal: this.props.rentalRate.isIncludedInTotal || false, - rate: this.props.rentalRate.rate || 0.0, - ratePeriod: ratePeriod, - uiRatePeriod: this.props.rentalRate.set ? Constant.RENTAL_RATE_PERIOD_SET : ratePeriod, - set: this.props.rentalRate.set || false, - comment: this.props.rentalRate.comment || '', - - rateError: '', - commentError: '', - }); - - this.setState({ forms }); - } - }; - - removeInput = () => { - if (this.state.forms.length > 1) { - const forms = this.state.forms.slice(); - forms.pop(); - this.setState({ forms }); - } - }; - - renderForm(form, i) { - // Read-only if the user cannot edit the rental agreement - const isReadOnly = !this.props.rentalRate.canEdit && this.props.rentalRate.id !== 0; - - const uiRatePeriods = _.concat(ratePeriods, Constant.RENTAL_RATE_PERIOD_SET); - - const ratePeriodElement = this.props.rentalRate.isIncludedInTotal ? - <> - Period -
{ form.uiRatePeriod }
- - : - - Period * - this.updateUiRatePeriod(state, i) } - items={ uiRatePeriods } /> - ; - - return ( -
- - - - Rate * - - { form.rateError } - - - - { ratePeriodElement } - - - - Comment * - - { form.commentError } - - - -
- ); - } - - render() { - var status = this.props.rentalRate.isIncludedInTotal ? 'Included' : 'As-Needed'; - - return ( - -
- { this.state.forms.map((form, i) => this.renderForm(form, i))} -
-
- { this.state.isNew && this.state.forms.length > 1 && ( - - )} - { this.state.isNew && this.state.forms.length < 10 && ( - - )} -
-
- ); - } -} - -export default RentalRatesEditDialog; diff --git a/client/src/js/views/dialogs/RentalRequestsAddDialog.jsx b/client/src/js/views/dialogs/RentalRequestsAddDialog.jsx deleted file mode 100644 index 7b10bff13..000000000 --- a/client/src/js/views/dialogs/RentalRequestsAddDialog.jsx +++ /dev/null @@ -1,336 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel, Alert } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import DateControl from '../../components/DateControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isValidDate, today } from '../../utils/date'; -import { isBlank } from '../../utils/string'; - - -class RentalRequestsAddDialog extends React.Component { - static propTypes = { - currentUser: PropTypes.object, - localAreas: PropTypes.object, - districtEquipmentTypes: PropTypes.object, - projects: PropTypes.object, - project: PropTypes.object, - onRentalAdded: PropTypes.func, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - viewOnly: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - savingError: '', - projectId: props.project ? props.project.id : 0, - localAreaId: 0, - equipmentTypeId: 0, - count: 1, - expectedHours: '', - expectedStartDate: today(), - expectedEndDate: '', - rentalRequestAttachments: [], - - projectError: '', - localAreaError: '', - equipmentTypeError: '', - countError: '', - expectedHoursError: '', - expectedStartDateError: '', - expectedEndDateError: '', - }; - } - - componentDidMount() { - Api.getDistrictEquipmentTypes(); - if (this.canChangeProject()) { - Api.getProjectsCurrentFiscal(); - } - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateEquipmentTypeState = (state) => { - var selectedEquipment =_.find(this.props.districtEquipmentTypes.data, { id: state.equipmentTypeId }); - var isDumpTruck = selectedEquipment.equipmentType.isDumpTruck; - var expectedHours = isDumpTruck ? 600 : 300; - this.setState({ ...state, expectedHours }); - }; - - didChange = () => { - if (this.state.projectId !== 0) { return true; } - if (this.state.localAreaId !== 0) { return true; } - if (this.state.equipmentTypeId !== 0) { return true; } - if (this.state.count !== 1) { return true; } - if (this.state.expectedHours !== '') { return true; } - if (this.state.expectedStartDate !== today()) { return true; } - if (this.state.expectedEndDate !== '') { return true; } - if (this.state.rentalRequestAttachments !== '') { return true; } - - return false; - }; - - isValid = () => { - // Clear out any previous errors - var valid = true; - this.setState({ - projectError: '', - localAreaError: '', - equipmentTypeError: '', - countError: '', - expectedHoursError: '', - expectedStartDateError: '', - expectedEndDateError: '', - }); - - if (this.state.projectId === 0 && !this.props.viewOnly) { - this.setState({ projectError: 'Project is required' }); - valid = false; - } - - if (this.state.localAreaId === 0) { - this.setState({ localAreaError: 'Local area is required' }); - valid = false; - } - - if (this.state.equipmentTypeId === 0) { - this.setState({ equipmentTypeError: 'Equipment type is required' }); - valid = false; - } - - // all fields for view-only requests have now been validated - if (this.props.viewOnly) { - return valid; - } - - if (isBlank(this.state.count)) { - this.setState({ countError: 'Equipment quantity is required' }); - valid = false; - } else if (this.state.count < 1) { - this.setState({ countError: 'Equipment quantity not valid' }); - valid = false; - } - - if (isBlank(this.state.expectedHours)) { - this.setState({ expectedHoursError: 'Estimated hours are required' }); - valid = false; - } else if (this.state.expectedHours < 1) { - this.setState({ expectedHoursError: 'Estimated hours not valid' }); - valid = false; - } - - if (isBlank(this.state.expectedStartDate)) { - this.setState({ expectedStartDateError: 'Start date is required' }); - valid = false; - } else if (!isValidDate(this.state.expectedStartDate)) { - this.setState({ expectedStartDateError: 'Date not valid' }); - valid = false; - } - - if (Moment(this.state.expectedEndDate).isBefore(this.state.expectedStartDate)) { - this.setState({ expectedEndDateError: 'End date must be later than the start date' }); - valid = false; - } - - return valid; - }; - - onLocalAreaSelected = (localArea) => { - // clear the selected equipment type if it's not included in the types for the new local area - var districtEquipmentTypes = this.getFilteredEquipmentTypes(localArea.id); - if (_.filter(districtEquipmentTypes, type => type.id === this.state.equipmentTypeId).length === 0) { - this.setState({ equipmentTypeId: 0 }); - } - }; - - onProjectSelected = () => { - // TODO Restrict the available local areas to a project service area - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({isSaving: true}); - - const { rentalRequestAttachments } = this.state; - - var request = { - project: { id: this.state.projectId }, - localArea: { id: this.state.localAreaId }, - districtEquipmentType: { id: this.state.equipmentTypeId }, - equipmentCount: this.state.count, - status: Constant.RENTAL_REQUEST_STATUS_CODE_IN_PROGRESS, - expectedHours: this.state.expectedHours, - expectedStartDate: this.state.expectedStartDate, - expectedEndDate: this.state.expectedEndDate, - rentalRequestAttachments: [{ - id: 0, - attachment: rentalRequestAttachments.length === 0 ? undefined : rentalRequestAttachments, - }], - }; - - Api.addRentalRequest(request, this.props.viewOnly).then((response) => { - this.setState({ isSaving: false }); - - this.props.onRentalAdded(response); - this.props.onClose(); - }).catch((error) => { - this.setState({ isSaving: false }); - if (error.status === 400 && error.errorCode === 'HETS-28') { - this.setState({ savingError: error.errorDescription }); - } else { - throw error; - } - }); - } - } - }; - - getFilteredEquipmentTypes = (localAreaId) => { - return _.chain(this.props.districtEquipmentTypes.data) - .filter(type => type.equipmentCount > 0 && !localAreaId || _.filter(type.localAreas, localArea => localArea.id === localAreaId && localArea.equipmentCount > 0).length > 0) - .sortBy('districtEquipmentName') - .value(); - }; - - canChangeProject = () => { - return !this.props.project && !this.props.viewOnly; - }; - - renderForm = () => { - const { project } = this.props; - - // Constrain the local area drop downs to those in the District of the current logged in user - var localAreas = _.chain(this.props.localAreas) - .sortBy('name') - .value(); - - var districtEquipmentTypes = this.getFilteredEquipmentTypes(this.state.localAreaId); - - var projects = _.sortBy(this.props.projects.data, 'name'); - - const hasPickedLocalArea = Boolean(this.state.localAreaId); - - return ( -
- - Project {!project && !this.props.viewOnly && (*)} - { this.canChangeProject() ? ( - - ) :
{project ? project.name : 'Request - View Only' }
- } - { this.state.projectError } -
- - Local Area * - - { this.state.localAreaError } - - - Equipment Type * - - { this.state.equipmentTypeError } - - { !this.props.viewOnly && ( - - Quantity * - - { this.state.countError } - - )} - { !this.props.viewOnly && ( - - Attachment(s) - - - )} - { !this.props.viewOnly && ( - - Expected Hours * - - { this.state.expectedHoursError } - - )} - { !this.props.viewOnly && ( - - Start Date * - - { this.state.expectedStartDateError } - - )} - { !this.props.viewOnly && ( - - End Date - - { this.state.expectedEndDateError } - - )} - { this.state.savingError && - { this.state.savingError } - } -
- ); - }; - - render() { - const { isSaving } = this.state; - const { show, onClose } = this.props; - - return ( - - { this.renderForm()} - - ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - localAreas: state.lookups.localAreas, - districtEquipmentTypes: state.lookups.districtEquipmentTypes, - projects: state.lookups.projectsCurrentFiscal, - }; -} - -export default connect(mapStateToProps)(RentalRequestsAddDialog); diff --git a/client/src/js/views/dialogs/RentalRequestsEditDialog.jsx b/client/src/js/views/dialogs/RentalRequestsEditDialog.jsx deleted file mode 100644 index 89db7d75a..000000000 --- a/client/src/js/views/dialogs/RentalRequestsEditDialog.jsx +++ /dev/null @@ -1,175 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormGroup, HelpBlock, ControlLabel, FormControl } from 'react-bootstrap'; -import Moment from 'moment'; - -import * as Api from '../../api'; -import * as Log from '../../history'; - -import DateControl from '../../components/DateControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isValidDate } from '../../utils/date'; -import { isBlank } from '../../utils/string'; - - -class RentalRequestsEditDialog extends React.Component { - static propTypes = { - rentalRequest: PropTypes.object.isRequired, - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - const rentalRequest = props.rentalRequest; - - this.state = { - equipmentCount: rentalRequest.equipmentCount || 0, - expectedHours: rentalRequest.expectedHours || 0, - expectedStartDate: rentalRequest.expectedStartDate || '', - expectedEndDate: rentalRequest.expectedEndDate || '', - rentalRequestAttachments: rentalRequest.rentalRequestAttachments && rentalRequest.rentalRequestAttachments[0] ? rentalRequest.rentalRequestAttachments[0].attachment : '', - rentalRequestAttachmentId: rentalRequest.rentalRequestAttachments && rentalRequest.rentalRequestAttachments[0] ? rentalRequest.rentalRequestAttachments[0].id : undefined, - - equipmentCountError: '', - expectedHoursError: '', - expectedStartDateError: '', - expectedEndDateError: '', - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.equipmentCount !== this.props.rentalRequest.equipmentCount) { return true; } - if (this.state.expectedHours !== this.props.rentalRequest.expectedHours) { return true; } - if (this.state.expectedStartDate !== this.props.rentalRequest.expectedStartDate) { return true; } - if (this.state.expectedEndDate !== this.props.rentalRequest.expectedEndDate) { return true; } - if (this.state.rentalRequestAttachments !== this.props.rentalRequest.rentalRequestAttachments) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - equipmentCountError: '', - expectedHoursError: '', - expectedStartDateError: '', - expectedEndDateError: '', - }); - - var valid = true; - - if (isBlank(this.state.equipmentCount)) { - this.setState({ equipmentCountError: 'Quantity is required' }); - valid = false; - } else if (this.state.equipmentCount < 1) { - this.setState({ equipmentCountError: 'Quantity not valid' }); - valid = false; - } else if (this.state.equipmentCount < this.props.rentalRequest.yesCount) { - this.setState({ equipmentCountError: 'Quantity can not be less than number of equipment already hired' }); - valid = false; - } - - if (isBlank(this.state.expectedHours)) { - this.setState({ expectedHoursError: 'Estimated hours are required' }); - valid = false; - } else if (this.state.expectedHours < 1) { - this.setState({ expectedHoursError: 'Estimated hours not valid' }); - valid = false; - } - - if (isBlank(this.state.expectedStartDate)) { - this.setState({ expectedStartDateError: 'Start date is required' }); - valid = false; - } else if (!isValidDate(this.state.expectedStartDate)) { - this.setState({ expectedStartDateError: 'Date not valid' }); - valid = false; - } - - if (Moment(this.state.expectedEndDate).isBefore(this.state.expectedStartDate)) { - this.setState({ expectedEndDateError: 'End date must be later than the start date' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - const rentalRequest = { - ...this.props.rentalRequest, - equipmentCount: this.state.equipmentCount, - expectedHours: this.state.expectedHours, - expectedStartDate: this.state.expectedStartDate, - expectedEndDate: this.state.expectedEndDate, - rentalRequestAttachments: [{ - id: this.state.rentalRequestAttachmentId, - attachment: this.state.rentalRequestAttachments, - }], - }; - - Api.updateRentalRequest(rentalRequest).then(() => { - Log.rentalRequestModified(this.props.rentalRequest); - if (this.props.onSave) { this.props.onSave(); } - }); - } - - this.props.onClose(); - } - }; - - render() { - // Read-only if the user cannot edit the rental agreement - var isReadOnly = !this.props.rentalRequest.canEdit && this.props.rentalRequest.id !== 0; - // var numRequestAttachments = Object.keys(this.props.rentalRequest.rentalRequestAttachments || []).length; - // var requestAttachments = (this.props.rentalRequest.rentalRequestAttachments || []).join(', '); - - return ( - - - Equipment Type - { this.props.rentalRequest.equipmentTypeName } - - - Attachment(s) - - - - Quantity * - - { this.state.equipmentCountError } - - - Expected Hours * - - { this.state.expectedHoursError } - - - Start Date * - - { this.state.expectedStartDateError } - - - End Date * - - { this.state.expectedEndDateError } - - - ); - } -} - -export default RentalRequestsEditDialog; diff --git a/client/src/js/views/dialogs/SeniorityEditDialog.jsx b/client/src/js/views/dialogs/SeniorityEditDialog.jsx deleted file mode 100644 index 13df4dfe8..000000000 --- a/client/src/js/views/dialogs/SeniorityEditDialog.jsx +++ /dev/null @@ -1,230 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; - -import { Grid, Row, Col } from 'react-bootstrap'; -import { FormControl, FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; - -import * as Api from '../../api'; -import * as Log from '../../history'; - -import FormDialog from '../../components/FormDialog.jsx'; -import DateControl from '../../components/DateControl.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { daysFromToday, isValidDate, toZuluTime, today } from '../../utils/date'; -import { isBlank, formatHours } from '../../utils/string'; - -class SeniorityEditDialog extends React.Component { - static propTypes = { - equipment: PropTypes.object, - - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - isNew: props.equipment.id === 0, - - hoursYtd: props.equipment.hoursYtd, - serviceHoursLastYear: props.equipment.serviceHoursLastYear, - serviceHoursTwoYearsAgo: props.equipment.serviceHoursTwoYearsAgo, - serviceHoursThreeYearsAgo: props.equipment.serviceHoursThreeYearsAgo, - approvedDate: props.equipment.approvedDate || today(), - yearsRegistered: props.equipment.yearsOfService, - isSeniorityOverridden: props.equipment.isSeniorityOverridden, - seniorityOverrideReason: props.equipment.seniorityOverrideReason, - - approvedDateError: null, - serviceHoursLastYearError: null, - serviceHoursTwoYearsAgoError: null, - serviceHoursThreeYearsAgoError: null, - yearsRegisteredError: null, - overrideReasonError: null, - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.serviceHoursLastYear !== this.props.equipment.serviceHoursLastYear) { return true; } - if (this.state.serviceHoursTwoYearsAgo !== this.props.equipment.serviceHoursTwoYearsAgo) { return true; } - if (this.state.serviceHoursThreeYearsAgo !== this.props.equipment.serviceHoursThreeYearsAgo) { return true; } - if (this.state.approvedDate !== this.props.equipment.approvedDate) { return true; } - if (this.state.yearsRegistered !== this.props.equipment.yearsRegistered) { return true; } - if (this.state.isSeniorityOverridden !== this.props.equipment.isSeniorityOverridden) { return true; } - if (this.state.seniorityOverrideReason !== this.props.equipment.seniorityOverrideReason) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - approvedDateError: null, - serviceHoursLastYearError: null, - serviceHoursTwoYearsAgoError: null, - serviceHoursThreeYearsAgoError: null, - yearsRegisteredError: null, - overrideReasonError: null, - }); - - var valid = true; - // Validate service hours - if (isBlank(this.state.serviceHoursLastYear)) { - this.setState({ serviceHoursLastYearError: 'Service hours are required' }); - valid = false; - } - - if (isBlank(this.state.serviceHoursTwoYearsAgo)) { - this.setState({ serviceHoursTwoYearsAgoError: 'Service hours are required' }); - valid = false; - } - - if (isBlank(this.state.serviceHoursThreeYearsAgo)) { - this.setState({ serviceHoursThreeYearsAgoError: 'Service hours are required' }); - valid = false; - } - - // Validate registered date - if (isBlank(this.state.approvedDate)) { - this.setState({ approvedDateError: 'Registered date is required' }); - valid = false; - } else if (!isValidDate(this.state.approvedDate)) { - this.setState({ approvedDateError: 'Registered date not valid' }); - valid = false; - } else if (daysFromToday(this.state.approvedDate) > 0) { - this.setState({ approvedDateError: 'Registration date must be today or earlier' }); - valid = false; - } - - if (this.didChange() && (isBlank(this.state.seniorityOverrideReason) || (this.state.seniorityOverrideReason === this.props.equipment.seniorityOverrideReason))) { - this.setState({ overrideReasonError: 'A new reason must be provided each time seniority is manually overriden' }); - valid = false; - } - - if (this.state.yearsRegistered < 0) { - this.setState({ yearsRegisteredError: 'Years registered must be an integer greater than 0.' }); - valid = false; - } - - return valid; - }; - - seniorityOverrriden = () => { - this.setState({ isSeniorityOverridden: true }); - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const equipment = { - ...this.props.equipment, - serviceHoursLastYear: (this.state.serviceHoursLastYear || 0).toFixed(2), - serviceHoursTwoYearsAgo: (this.state.serviceHoursTwoYearsAgo || 0).toFixed(2), - serviceHoursThreeYearsAgo: (this.state.serviceHoursThreeYearsAgo || 0).toFixed(2), - approvedDate: toZuluTime(this.state.approvedDate), - yearsOfService: this.state.yearsRegistered, - isSeniorityOverridden: this.state.isSeniorityOverridden, - seniorityOverrideReason: this.state.seniorityOverrideReason, - }; - - const promise = Api.updateEquipment(equipment); - - promise.then(() => { - Log.equipmentSeniorityModified(this.props.equipment); - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - return ( - - - - - - Hours YTD - { formatHours(this.state.hoursYtd) } - - - - - - - Hours { this.props.equipment.yearMinus1 } * - - { this.state.serviceHoursLastYearError } - - - - - - - Hours { this.props.equipment.yearMinus2 } * - - { this.state.serviceHoursTwoYearsAgoError } - - - - - - - Hours { this.props.equipment.yearMinus3 } * - - { this.state.serviceHoursThreeYearsAgoError } - - - - - - - Registered Date * - - { this.state.approvedDateError } - - - - - - - Years Registered - - { this.state.yearsRegisteredError } - - - - - - - Override Reason * - - { this.state.overrideReasonError } - - - - - - ); - } -} - -export default SeniorityEditDialog; diff --git a/client/src/js/views/dialogs/TimeEntryDialog.jsx b/client/src/js/views/dialogs/TimeEntryDialog.jsx deleted file mode 100644 index b073338ea..000000000 --- a/client/src/js/views/dialogs/TimeEntryDialog.jsx +++ /dev/null @@ -1,555 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Grid, Row, Col, FormGroup, ControlLabel, HelpBlock, Button, Glyphicon } from 'react-bootstrap'; -import _ from 'lodash'; -import Moment from 'moment'; - -import * as Api from '../../api'; - -import FormDialog from '../../components/FormDialog.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; -import DateControl from '../../components/DateControl.jsx'; -import DeleteButton from '../../components/DeleteButton.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import Spinner from '../../components/Spinner.jsx'; - -import { isBlank, formatHours } from '../../utils/string'; -import { formatDateTime } from '../../utils/date'; - -class TimeEntryDialog extends React.Component { - static propTypes = { - onClose: PropTypes.func.isRequired, - show: PropTypes.bool.isRequired, - multipleEntryAllowed: PropTypes.bool.isRequired, - rentalAgreementId: PropTypes.number, - rentalAgreementTimeRecords: PropTypes.object, - project: PropTypes.object, - projectId: PropTypes.number, - projects: PropTypes.object.isRequired, - equipment: PropTypes.object.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - isSaving: false, - loaded: false, - rentalAgreementId: props.rentalAgreementId, - equipmentId: null, - projectId: props.projectId || null, - projectFiscalYearStartDate: props.project ? props.project.fiscalYearStartDate : null, - equipmentIdError: '', - projectIdError: '', - selectingAgreement: props.rentalAgreementId ? false : true, - showAllTimeRecords: false, - numberOfInputs: 1, - timeEntry: { - 1: { - hours: '', - date: '', - errorHours: '', - errorDate: '', - }, - }, - }; - } - - resetStateToSelectAgreement = (clearSelections) => { - this.setState({ - rentalAgreementId: null, - equipmentId: clearSelections ? null : this.state.equipmentId, - projectId: clearSelections ? null : this.state.projectId, - projectFiscalYearStartDate: clearSelections ? null : this.state.projectFiscalYearStartDate, - selectingAgreement: true, - showAllTimeRecords: false, - numberOfInputs: 1, - timeEntry: { - 1: { - hours: '', - date: '', - errorHours: '', - errorDate: '', - }, - }, - }); - }; - - componentDidMount() { - if (this.state.selectingAgreement) { - Api.getProjectsCurrentFiscal(); - Api.getEquipmentLite(); - } else { - this.setState({ loaded: false }); - Promise.all([ - !this.props.project ? this.fetchProject(this.props.projectId) : null, - this.fetchTimeRecords(), - ]).then(() => { - this.setState({ loaded: true }); - }); - } - } - - fetchTimeRecords = () => { - return Api.getRentalAgreementTimeRecords(this.state.rentalAgreementId); - }; - - fetchProject = (projectId) => { - return Api.getProject(projectId).then((project) => { - this.setState({projectFiscalYearStartDate: project.fiscalYearStartDate}); - }); - }; - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - validateSelectAgreement = () => { - var valid = true; - - this.setState({ equipmentIdError: '', projectIdError: '' }); - - if (isBlank(this.state.equipmentId)) { - this.setState({ equipmentIdError: 'Equipment ID is required' }); - valid = false; - } - - if (isBlank(this.state.projectId)) { - this.setState({ projectIdError: 'Project is required' }); - valid = false; - } - - return valid; - }; - - selectAgreementFormSubmitted = () => { - if (this.validateSelectAgreement()) { - this.setState({ isSaving: true }); - - Api.getLatestRentalAgreement(this.state.equipmentId, this.state.projectId).then((agreement) => { - this.setState({ loaded: false, rentalAgreementId: agreement.id }); - return Promise.all([ this.fetchProject(this.state.projectId), this.fetchTimeRecords() ]).then(() => { - this.setState({ isSaving: false, selectingAgreement: false, loaded: true }); - }); - }).catch((error) => { - this.setState({ isSaving: false }); - if (error.status === 400 && error.errorCode === 'HETS-35') { - this.setState({ projectIdError: error.errorDescription }); - } else { - throw error; - } - }); - } - }; - - updateTimeEntryState = (value) => { - let property = Object.keys(value)[0]; - let stateValue = _.values(value)[0]; - let number = property.match(/\d+/g)[0]; - let stateName = property.match(/[a-zA-Z]+/g)[0]; - let state = { [stateName]: stateValue }; - let updatedState = { ...this.state.timeEntry, [number]: { ...this.state.timeEntry[number], ...state } }; - this.setState({ timeEntry: updatedState }); - }; - - didChange = () => { - // todo - return true; - }; - - isValid = () => { - let timeEntry = { ...this.state.timeEntry }; - - let timeEntryResetObj = timeEntry; - Object.keys(timeEntry).forEach((key) => { - let state = { ...timeEntry[key], errorHours: '', errorDate: '' }; - timeEntryResetObj[key] = state; - }); - - this.setState({ timeEntry: timeEntryResetObj }); - let valid = true; - - let timeEntryErrorsObj = timeEntry; - Object.keys(timeEntry).forEach((key) => { - if (isBlank(timeEntry[key].hours)) { - let state = { ...timeEntry[key], errorHours: 'Hours are required' }; - timeEntryErrorsObj[key] = state; - valid = false; - } - if (isBlank(timeEntry[key].date)) { - let state = { ...timeEntry[key], errorDate: 'Date is required' }; - timeEntryErrorsObj[key] = state; - valid = false; - } else { - var date = Moment.utc(timeEntry[key].date); - if (this.isBeforeFiscalStartDate(date)) { - let state = { ...timeEntry[key], errorDate: 'Date must be in the current fiscal year' }; - timeEntryErrorsObj[key] = state; - valid = false; - } else if (this.isInFuture(date)) { - let state = { ...timeEntry[key], errorDate: 'Date must not be in the future' }; - timeEntryErrorsObj[key] = state; - valid = false; - } else if (!this.isSaturdayOrMarch31st(date)) { - let state = { ...timeEntry[key], errorDate: 'Date must be a Saturday or March 31st' }; - timeEntryErrorsObj[key] = state; - valid = false; - } - Object.keys(timeEntry).forEach((otherKey) => { - if (key !== otherKey && timeEntry[key].date === timeEntry[otherKey].date) { - let state = { ...timeEntry[key], errorDate: 'Time record for this date already exists' }; - timeEntryErrorsObj[key] = state; - valid = false; - } - }); - Object.keys(this.props.rentalAgreementTimeRecords.timeRecords).forEach((index) => { - var existingDate = Moment.utc(this.props.rentalAgreementTimeRecords.timeRecords[index].workedDate); - if (date.isSame(existingDate)) { - let state = { ...timeEntry[key], errorDate: 'Time record for this date already exists' }; - timeEntryErrorsObj[key] = state; - valid = false; - } - }); - } - }); - this.setState({ timeEntry: timeEntryErrorsObj }); - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - var timeEntry = { ...this.state.timeEntry }; - Object.keys(timeEntry).forEach((key) => { - timeEntry[key].hours = (timeEntry[key].hours || 0).toFixed(2); - }); - - const promise = Api.addRentalAgreementTimeRecords(this.state.rentalAgreementId, timeEntry); - - promise.then(() => { - this.setState({ isSaving: false }); - if (this.props.multipleEntryAllowed) { - this.resetStateToSelectAgreement(true); - } else { - this.props.onClose(); - } - }); - } else { - this.props.onClose(); - } - } - }; - - onClose = () => { - if (this.props.multipleEntryAllowed) { - this.resetStateToSelectAgreement(false); - } else { - this.props.onClose(); - } - }; - - onEquipmentSelected = () => { - this.setState({ projectId: null }); - }; - - getFilteredProjects = () => { - const projects = this.props.projects.data; - - if (this.state.equipmentId) { - var equipment = this.props.equipment.data[this.state.equipmentId] || null; - if (equipment) { - return _.intersectionWith(projects, equipment.projectIds, (p, pid) => p.id === pid); - } - } - - return projects; - }; - - addTimeEntryInput = () => { - if (this.state.numberOfInputs < 10) { - let numberOfInputs = Object.keys(this.state.timeEntry).length; - this.setState({ - numberOfInputs: this.state.numberOfInputs + 1, - timeEntry: { - ...this.state.timeEntry, - [numberOfInputs + 1]: { - hours: '', - date: '', - errorHours: '', - errorDate: '', - }, - }, - }); - } - }; - - removeTimeEntryInput = () => { - if (this.state.numberOfInputs > 1) { - let numberOfInputs = Object.keys(this.state.timeEntry).length; - let timeEntry = { ...this.state.timeEntry }; - delete timeEntry[numberOfInputs]; - this.setState({ - numberOfInputs: this.state.numberOfInputs - 1, - timeEntry: timeEntry, - }); - } - }; - - deleteTimeRecord = (timeRecord) => { - Api.deleteTimeRecord(timeRecord.id).then(() => { - Api.getRentalAgreementTimeRecords(this.state.rentalAgreementId); - }); - }; - - showAllTimeRecords = () => { - this.setState({ showAllTimeRecords: !this.state.showAllTimeRecords }); - }; - - getHoursYtdClassName = () => { - var equipment = this.props.rentalAgreementTimeRecords; - - if (equipment.hoursYtd > (0.85 * equipment.maximumHours)) { - return true; - } - - return false; - }; - - isBeforeFiscalStartDate = (date) => { - return date.isBefore(Moment(this.state.projectFiscalYearStartDate)); - } - - isInFuture = (date) => { - // The next Saturday is allowed but not after - return date.isAfter(Moment().day(6)); - } - - isSaturdayOrMarch31st = (date) => { - return date.day() === 6 || date.month() === 2 && date.date() === 31; - } - - isValidDate = (current) => { - if (this.isBeforeFiscalStartDate(current)) { - return false; - } - - if (this.isInFuture(current)) { - return false; - } - - return this.isSaturdayOrMarch31st(current); - }; - - render() { - if (this.state.selectingAgreement) { - return this.renderSelectAgreement(); - } else { - return this.renderEditDialog(); - } - } - - renderSelectAgreement = () => { - var equipment = _.sortBy(this.props.equipment.data, 'equipmentCode'); - var projects = this.getFilteredProjects(); - - return ( - - - - - - Equipment ID * - - { this.state.equipmentIdError } - - - - - Project * - - { this.state.projectIdError } - - - - - - ); - }; - - renderTimeRecordItem = (timeRecord) => { - return ( - - -
{ formatDateTime(timeRecord.workedDate, 'YYYY-MMM-DD') }
- - -
{ formatHours(timeRecord.hours) }
- - - this.deleteTimeRecord(timeRecord) }/> - -
- ); - }; - - renderEditDialog = () => { - const rentalAgreementTimeRecords = this.props.rentalAgreementTimeRecords; - var sortedTimeRecords = _.sortBy(rentalAgreementTimeRecords.timeRecords, 'workedDate').reverse(); - - return ( - - - {(() => { - if (!this.state.loaded) { return
; } - - return ( -
- - -
Equipment ID
-
{ rentalAgreementTimeRecords.equipmentCode }
- - -
YTD Hours
-
- { formatHours(rentalAgreementTimeRecords.hoursYtd) }{ this.getHoursYtdClassName() } -
- - -
Project
-
{ rentalAgreementTimeRecords.projectName }
- - -
Project Number
-
{ rentalAgreementTimeRecords.provincialProjectNumber }
- -
-
- -
Week Ending
-
Hours
-
- { (sortedTimeRecords.length === 0) && - -
No time records have been added yet.
-
- } - - { (sortedTimeRecords.length > 0) && !this.state.showAllTimeRecords ? - - {this.renderTimeRecordItem(sortedTimeRecords[0])} - - : - - -
    - { _.map(sortedTimeRecords, timeRecord => ( -
  • - {this.renderTimeRecordItem(timeRecord)} -
  • - ))} -
- -
- } -
- { (sortedTimeRecords.length > 1) && - - } -
- ); - })()} -
- { Object.keys(this.state.timeEntry).map(key => { - return ( - - - - Week Ending - - { this.state.timeEntry[key].errorDate } - - - - - Hours - - { this.state.timeEntry[key].errorHours } - - - - ); - })} - - - { this.state.numberOfInputs < 10 && ( - - )} - { this.state.numberOfInputs > 1 && ( - - )} - - -
-
- ); - }; -} - -function mapStateToProps(state) { - return { - rentalAgreementTimeRecords: state.models.rentalAgreementTimeRecords, - projects: state.lookups.projectsCurrentFiscal, - equipment: state.lookups.equipment.ts, - }; -} - -export default connect(mapStateToProps)(TimeEntryDialog); diff --git a/client/src/js/views/dialogs/UserRoleAddDialog.jsx b/client/src/js/views/dialogs/UserRoleAddDialog.jsx deleted file mode 100644 index f6957d4e6..000000000 --- a/client/src/js/views/dialogs/UserRoleAddDialog.jsx +++ /dev/null @@ -1,178 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { Grid, Row, Col } from 'react-bootstrap'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Api from '../../api'; -import * as Constant from '../../constants'; - -import DateControl from '../../components/DateControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import DropdownControl from '../../components/DropdownControl.jsx'; -import Spinner from '../../components/Spinner.jsx'; - -import { isValidDate, toZuluTime } from '../../utils/date'; -import { isBlank, notBlank } from '../../utils/string'; - - -class UserRoleAddDialog extends React.Component { - static propTypes = { - show: PropTypes.bool, - user: PropTypes.object, - roles: PropTypes.object, - currentUser: PropTypes.object, - onSave: PropTypes.func, - onClose: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - - this.state = { - loading: false, - isSaving: false, - - roleId: 0, - effectiveDate: '', - expiryDate: '', - - roleIdError: '', - effectiveDateError: '', - expiryDateError: '', - }; - } - - componentDidMount() { - this.setState({ loading: true }); - Api.getRoles().then(() => { - this.setState({ loading: false }); - }); - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - didChange = () => { - if (this.state.roleId !== 0) { return true; } - if (notBlank(this.state.effectiveDate)) { return true; } - if (notBlank(this.state.expiryDate)) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - roleIdError: false, - effectiveDateError: false, - expiryDateError: false, - }); - - var valid = true; - if (!this.state.roleId) { - this.setState({ roleIdError: 'Role is required' }); - valid = false; - } - - if (isBlank(this.state.effectiveDate)) { - this.setState({ effectiveDateError: 'Effective date is required' }); - valid = false; - } else if (!isValidDate(this.state.effectiveDate)) { - this.setState({ effectiveDateError: 'Effective date not valid' }); - valid = false; - } - - if (notBlank(this.state.expiryDate) && !isValidDate(this.state.expiryDate)) { - this.setState({ expiryDateError: 'Expiry date not valid' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const userRole = { - roleId: this.state.roleId, - effectiveDate: toZuluTime(this.state.effectiveDate), - expiryDate: toZuluTime(this.state.expiryDate), - }; - - Api.addUserRole(this.props.user.id, userRole).then(() => { - this.setState({ isSaving: false }); - if (this.props.onSave) { this.props.onSave(); } - this.props.onClose(); - }); - - } else { - this.props.onClose(); - } - } - }; - - render() { - var isAdministrator = _.some(this.props.currentUser.userRoles, { roleName: Constant.ADMINISTRATOR_ROLE }); - - var filteredRoles = isAdministrator ? this.props.roles : _.reject(this.props.roles, { name: Constant.ADMINISTRATOR_ROLE }); - - var roles = _.sortBy(filteredRoles, 'name'); - - return ( - - {(() => { - if (this.state.loading) { return
; } - - return ( - - - - - Role * - - { this.state.roleIdError } - - - - - Effective Date * - - { this.state.effectiveDateError } - - - - - Expiry Date - - { this.state.expiryDateError } - - - - - ); - })()} -
- ); - } -} - -function mapStateToProps(state) { - return { - currentUser: state.user, - roles: state.lookups.roles, - }; -} - -export default connect(mapStateToProps)(UserRoleAddDialog); diff --git a/client/src/js/views/dialogs/UsersEditDialog.jsx b/client/src/js/views/dialogs/UsersEditDialog.jsx deleted file mode 100644 index fc90d7ba7..000000000 --- a/client/src/js/views/dialogs/UsersEditDialog.jsx +++ /dev/null @@ -1,227 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { FormGroup, HelpBlock, ControlLabel } from 'react-bootstrap'; -import _ from 'lodash'; - -import * as Constant from '../../constants'; -import * as Api from '../../api'; - -import DropdownControl from '../../components/DropdownControl.jsx'; -import FormDialog from '../../components/FormDialog.jsx'; -import FilterDropdown from '../../components/FilterDropdown.jsx'; -import FormInputControl from '../../components/FormInputControl.jsx'; - -import { isBlank } from '../../utils/string'; - - -class UsersEditDialog extends React.Component { - static propTypes = { - user: PropTypes.object.isRequired, - districts: PropTypes.object, - - onSave: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - show: PropTypes.bool, - isNew: PropTypes.bool, - }; - - static defaultProps = { - isNew: false, - }; - - constructor(props) { - super(props); - - var isNew = props.isNew; - - this.state = { - isNew: isNew, - - isSaving: false, - - active: !isNew ? props.user.active === true : false, - givenName: !isNew ? props.user.givenName : '', - surname: !isNew ? props.user.surname : '', - smUserId: !isNew ? props.user.smUserId : '', - email: !isNew ? props.user.email : '', - districtId: !isNew ? props.user.district.id : 0, - agreementCity: !isNew ? props.user.agreementCity : '', - - status: !isNew && props.user.active ? Constant.USER_STATUS_ACTIVE : Constant.USER_STATUS_ARCHIVED, - - givenNameError: false, - surnameError: false, - smUserIdError: false, - emailError: false, - districtIdError: false, - }; - } - - updateState = (state, callback) => { - this.setState(state, callback); - }; - - updateStatus = (state, callback) => { - this.setState({ - status: state.status, - active: state.status === Constant.USER_STATUS_ACTIVE, - }, callback); - }; - - didChange = () => { - if (this.props.isNew) { return true; } - if (this.state.active !== this.props.user.active) { return true; } - if (this.state.givenName !== this.props.user.givenName) { return true; } - if (this.state.surname !== this.props.user.surname) { return true; } - if (this.state.smUserId !== this.props.user.smUserId) { return true; } - if (this.state.email !== this.props.user.email) { return true; } - if (this.state.districtId !== this.props.user.districtId) { return true; } - if (this.state.agreementCity !== this.props.user.agreementCity) { return true; } - - return false; - }; - - isValid = () => { - this.setState({ - givenNameError: false, - surnameError: false, - smUserIdError: false, - emailError: false, - districtIdError: false, - }); - - var valid = true; - - if (isBlank(this.state.givenName)) { - this.setState({ givenNameError: 'Given Name is required' }); - valid = false; - } - - if (isBlank(this.state.surname)) { - this.setState({ surnameError: 'Surname is required' }); - valid = false; - } - - if (isBlank(this.state.smUserId)) { - this.setState({ smUserIdError: 'User ID is required' }); - valid = false; - } - - if (isBlank(this.state.email)) { - this.setState({ emailError: 'E-mail address is required' }); - valid = false; - } - - if (this.state.districtId === 0) { - this.setState({ districtIdError: 'District is required' }); - valid = false; - } - - return valid; - }; - - formSubmitted = () => { - if (this.isValid()) { - if (this.didChange()) { - this.setState({ isSaving: true }); - - const user = { - ...this.props.user, - active: this.state.active, - givenName: this.state.givenName, - surname: this.state.surname, - smUserId: this.state.smUserId, - email: this.state.email, - district: { id: this.state.districtId }, - agreementCity: this.state.agreementCity, - }; - - const isNewUser = this.state.isNew; - const addOrUpdateUser = isNewUser ? Api.addUser : Api.updateUser; - - addOrUpdateUser(user).then((userResponse) => { - this.setState({ isSaving: false }); - - // Make sure we get the new user's ID - if (isNewUser) { - user.id = userResponse.id; - } - - // Let the parent page component know that the user has been saved - this.props.onSave(user); - }, (err) => { - this.setState({ isSaving: false }); - - if (err.errorCode === 'HETS-38') { - this.setState({ smUserIdError: err.errorDescription }); - } else { - this.props.onClose(); - throw err; - } - }); - } else { - this.props.onClose(); - } - } - }; - - render() { - var districts = _.sortBy(this.props.districts, 'name'); - - return ( - - - Given Name * - - { this.state.givenNameError } - - - Surname * - - { this.state.surnameError } - - - User ID * - - { this.state.smUserIdError } - - - Status - - - - E-mail * - - { this.state.emailError } - - - District * - - { this.state.districtIdError } - - - Location - - - - ); - } -} - -function mapStateToProps(state) { - return { - districts: state.lookups.districts, - }; -} - -export default connect(mapStateToProps)(UsersEditDialog); diff --git a/client/src/robots.txt b/client/src/robots.txt deleted file mode 100644 index 1f53798bb..000000000 --- a/client/src/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: / diff --git a/client/src/sass/components/all.scss b/client/src/sass/components/all.scss deleted file mode 100644 index a8a6b3e7f..000000000 --- a/client/src/sass/components/all.scss +++ /dev/null @@ -1,21 +0,0 @@ -@import './badge-label'; -@import './clone-dialog'; -@import './date-control'; -@import './dropdown-control'; -@import './form-dialog'; -@import './favourites'; -@import './file-upload'; -@import './filter-dropdown'; -@import './form-input-control'; -@import './history'; -@import './link-control'; -@import './multi-dropdown'; -@import './return-button'; -@import './print-button'; -@import './search-control'; -@import './sort-table'; - -@import './ui/add-button-container'; -@import './ui/page-header'; -@import './ui/subheader'; -@import './ui/search-bar'; diff --git a/client/src/sass/components/badge-label.scss b/client/src/sass/components/badge-label.scss deleted file mode 100644 index e538943d6..000000000 --- a/client/src/sass/components/badge-label.scss +++ /dev/null @@ -1,5 +0,0 @@ -.badge-label { - border-radius: 1em; - font-size: 100%; - margin: 0 .2em; -} diff --git a/client/src/sass/components/clone-dialog.scss b/client/src/sass/components/clone-dialog.scss deleted file mode 100644 index 1337494fd..000000000 --- a/client/src/sass/components/clone-dialog.scss +++ /dev/null @@ -1,18 +0,0 @@ -#clone-dialog { - .radio { - margin: 0; - } - - .table tr > td { - vertical-align: middle; - } - - .dropdown-control { - position: relative; - max-width: 225px; - - .dropdown-menu { - width: 100%; - } - } -} diff --git a/client/src/sass/components/date-control.scss b/client/src/sass/components/date-control.scss deleted file mode 100644 index d1442d37b..000000000 --- a/client/src/sass/components/date-control.scss +++ /dev/null @@ -1,38 +0,0 @@ -.date-control { - .rdt { - display: inline; - } - - .rdtPicker { - top: 34px; - } - - .form-control { - margin: 0; - width: 102px !important; - } - - .input-group-btn { - float: left; - } - - label { - float: left; - margin-top: 7px; - margin-right: 5px; - font-weight: normal; - } - - .btn { - padding-top: 5px; - } -} - -.has-error .date-control { - .btn { - color: #a94442; - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } -} diff --git a/client/src/sass/components/dropdown-control.scss b/client/src/sass/components/dropdown-control.scss deleted file mode 100644 index dcaf37132..000000000 --- a/client/src/sass/components/dropdown-control.scss +++ /dev/null @@ -1,72 +0,0 @@ -.dropdown-control { - .dropdown-toggle { - max-width: 200px; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 22px; - - .caret { - position: absolute; - top: 50%; - right: 10px; - } - } - - &.full-width { - .dropdown-menu { - width: 100%; - } - } - - .dropdown-menu { - padding: 0; - - ul { - margin: 0; - padding: 0; - list-style: none; - max-height: 262px; - overflow-y: auto; - } - - li { - margin: 0; - } - - a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333; - white-space: nowrap; - } - - a:hover, - a:focus { - color: #262626; - text-decoration: none; - background-color: #f5f5f5; - } - } -} - -.form-group .dropdown-control { - display: flex; - - .btn { - width: 100%; - max-width: none; - text-align: left; - } -} - -.has-error .dropdown-control { - .btn { - color: #a94442; - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } -} diff --git a/client/src/sass/components/favourites.scss b/client/src/sass/components/favourites.scss deleted file mode 100644 index 410917649..000000000 --- a/client/src/sass/components/favourites.scss +++ /dev/null @@ -1,40 +0,0 @@ -.favourites { - .dropdown-toggle { - width: 105px; - } - - .dropdown-menu { - width: 250px; - padding: 0px; - - .favourites-button-bar { - padding: 6px; - - button { - width: 100%; - } - } - - ul { - margin: 0px; - padding: 6px; - list-style: none; - max-height: 200px; - overflow-y: auto; - } - - li { - .btn-toolbar { - float: right; - - .btn { - margin-left: 6px; - } - } - - a { - cursor: pointer; - } - } - } -} diff --git a/client/src/sass/components/file-upload.scss b/client/src/sass/components/file-upload.scss deleted file mode 100644 index b488cbc42..000000000 --- a/client/src/sass/components/file-upload.scss +++ /dev/null @@ -1,73 +0,0 @@ -.file-picker { - display: inline-block; - - input[type='file'] { - display: none; - } - - label { - display: inline-block; - margin-bottom: 0; - } -} - -.file-upload { - .progress { - width: 500px; - margin: 6px 0; - } - - .file-upload-error-message { - color: #9a133e; - position: relative; - cursor: pointer; - padding-right: 20px; - - .glyphicon-remove { - width: 16px; - height: 16px; - font-size: 16px; - position: absolute; - top: 50%; - right: 0; - margin-top: -8px; - } - } -} - -.file-upload-dialog { - .note { - text-align: center; - } - - ol.file-list { - border-bottom: 1px solid #eeeeee; - margin: 0 0 20px 0; - padding: 0 0 15px 0; - list-style: none; - - li { - padding: 5px 15px; - margin: 0 -15px; - - &:hover { - background-color: #eeeeee; - } - - .glyphicon { - float: right; - cursor: pointer; - - &:hover { - color: #9e0a0a; - } - } - } - } - - .modal-footer { - .file-upload { - float: right; - } - } -} diff --git a/client/src/sass/components/filter-dropdown.scss b/client/src/sass/components/filter-dropdown.scss deleted file mode 100644 index 8153121aa..000000000 --- a/client/src/sass/components/filter-dropdown.scss +++ /dev/null @@ -1,104 +0,0 @@ -.filter-dropdown { - .dropdown-toggle { - max-width: 200px; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 22px; - - .caret { - position: absolute; - top: 50%; - right: 10px; - } - } - - &.full-width { - width: 100%; - - .dropdown-toggle { - width: 100%; - max-width: 100%; - } - - .dropdown-menu { - width: 100%; - } - } - - .dropdown-menu { - padding: 0; - - ul { - margin: 0; - padding: 0 0; - list-style: none; - max-height: 222px; - overflow-y: auto; - } - - li { - margin: 0; - } - - a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333; - white-space: nowrap; - } - - a:hover, - a:focus { - color: #262626; - text-decoration: none; - background-color: #f5f5f5; - } - - .well-sm { - padding: 7px; - margin: 0; - border-radius: 2px; - } - } - - &.disabled { - cursor: not-allowed; - - &>button { - pointer-events: none; - } - } -} - -.form-group .filter-dropdown { - display: flex; - - .btn { - width: 100%; - text-align: left; - } -} - -.has-error .filter-dropdown { - .btn { - color: #a94442; - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } - - .form-control { - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } - - .form-control:focus { - border-color: #66afe9; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); - } -} diff --git a/client/src/sass/components/form-dialog.scss b/client/src/sass/components/form-dialog.scss deleted file mode 100644 index e44c81b68..000000000 --- a/client/src/sass/components/form-dialog.scss +++ /dev/null @@ -1,18 +0,0 @@ -.form-dialog { - [class*='col-'] { - padding-left: 7px; - padding-right: 7px; - - &:first-child { - padding-left: 0; - } - - &:last-child { - padding-right: 0; - } - } - - h4 { - font-size: 18px; - } -} diff --git a/client/src/sass/components/form-input-control.scss b/client/src/sass/components/form-input-control.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/sass/components/history.scss b/client/src/sass/components/history.scss deleted file mode 100644 index 566efde47..000000000 --- a/client/src/sass/components/history.scss +++ /dev/null @@ -1,18 +0,0 @@ -#history-list { - width: 100%; - white-space: nowrap; - max-height: 250px; - overflow-y: auto; - - .btn { - margin: 0; - } - - .history-event { - white-space: normal; - } - - .table { - margin: 0; - } -} diff --git a/client/src/sass/components/link-control.scss b/client/src/sass/components/link-control.scss deleted file mode 100644 index 27ba425d9..000000000 --- a/client/src/sass/components/link-control.scss +++ /dev/null @@ -1,8 +0,0 @@ -.link-control { - label { - float: left; - margin-top: 7px; - margin-right: 5px; - font-weight: normal; - } -} diff --git a/client/src/sass/components/multi-dropdown.scss b/client/src/sass/components/multi-dropdown.scss deleted file mode 100644 index 9c18fff2a..000000000 --- a/client/src/sass/components/multi-dropdown.scss +++ /dev/null @@ -1,96 +0,0 @@ -.multi-dropdown { - .dropdown-toggle { - max-width: 200px; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 22px; - - .caret { - position: absolute; - top: 50%; - right: 10px; - } - } - - &.full-width { - .dropdown-toggle { - width: 100%; - max-width: 100%; - } - - .dropdown-menu { - width: 100%; - } - } - - .dropdown-menu { - padding: 0px; - - ul { - margin: 0; - padding: 0 7px; - list-style: none; - max-height: 200px; - overflow-y: auto; - } - - li { - margin: 5px 0; - } - - .well-sm { - padding: 7px 7px 0; - margin: 0; - border-radius: 2px; - } - - .checkbox { - margin-top: 5px; - margin-bottom: 5px; - - label { - white-space: nowrap; - } - } - - .select-all { - label { - font-weight: 600; - } - } - } -} - -.form-group .multi-dropdown { - display: flex; - - .btn { - width: 100%; - text-align: left; - } -} - -.has-error .multi-dropdown { - .btn { - color: #a94442; - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } - - .checkbox { - color: #494949; - } - - .form-control { - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - } - - .form-control:focus { - border-color: #66afe9; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); - } -} diff --git a/client/src/sass/components/print-button.scss b/client/src/sass/components/print-button.scss deleted file mode 100644 index 668a3ab05..000000000 --- a/client/src/sass/components/print-button.scss +++ /dev/null @@ -1,7 +0,0 @@ -.print-button { - margin-right: 5px; - - span:not(:empty) { - margin-left: 5px; - } -} diff --git a/client/src/sass/components/return-button.scss b/client/src/sass/components/return-button.scss deleted file mode 100644 index f102efda7..000000000 --- a/client/src/sass/components/return-button.scss +++ /dev/null @@ -1,8 +0,0 @@ -.return-button { - margin-left: 5px; - - .glyphicon { - vertical-align: middle; - top: -1px; - } -} diff --git a/client/src/sass/components/search-control.scss b/client/src/sass/components/search-control.scss deleted file mode 100644 index 5010c9fcd..000000000 --- a/client/src/sass/components/search-control.scss +++ /dev/null @@ -1,11 +0,0 @@ -@media (min-width: 768px) { - .search-control .input-group { - display: inline-table; - vertical-align: middle; - } - - .search-control .input-group .input-group-btn, - .search-control .input-group .form-control { - width: auto; - } -} diff --git a/client/src/sass/components/sort-table.scss b/client/src/sass/components/sort-table.scss deleted file mode 100644 index de796a1a2..000000000 --- a/client/src/sass/components/sort-table.scss +++ /dev/null @@ -1,30 +0,0 @@ -.sort-table { - width: 100%; - overflow-y: auto; - position: relative; - - @media print { - overflow-y: visible !important; - } - - #sort-table-refreshing-overlay { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - border-radius: 5px; - box-shadow: 0 0 5px rgba(0,0,0,0.1); - background-color: rgba(0,0,0,0.1); - z-index: 1000; - pointer-events: none; - - .spinner { - position: absolute; - top: 50%; - left: 50%; - margin-top: -12px; - margin-left: -12px; - } - } -} diff --git a/client/src/sass/components/ui/add-button-container.scss b/client/src/sass/components/ui/add-button-container.scss deleted file mode 100644 index c8eb1f562..000000000 --- a/client/src/sass/components/ui/add-button-container.scss +++ /dev/null @@ -1,4 +0,0 @@ -#add-button-container { - float: right; - margin-top: 10px; -} diff --git a/client/src/sass/components/ui/page-header.scss b/client/src/sass/components/ui/page-header.scss deleted file mode 100644 index a28d4e92b..000000000 --- a/client/src/sass/components/ui/page-header.scss +++ /dev/null @@ -1,13 +0,0 @@ -h1.ui-page-header { - small { - font-size: 85%; - } - - .btn-group { - float: right; - - .btn { - width: 40px; - } - } -} diff --git a/client/src/sass/components/ui/search-bar.scss b/client/src/sass/components/ui/search-bar.scss deleted file mode 100644 index d354ffe0f..000000000 --- a/client/src/sass/components/ui/search-bar.scss +++ /dev/null @@ -1,38 +0,0 @@ -.search-bar { - #filters { - .btn-group { - .btn { - text-align: left; - } - } - - .btn-toolbar { - @include flex; - flex-wrap: wrap; - } - - .btn-toolbar > div, .btn-toolbar > button, .btn-toolbar > span { - margin: 5px; - } - - .btn-toolbar > label.checkbox-control { - margin: 12px 10px 5px 5px; - } - - .btn-toolbar > input { - float: left; - min-width: 175px; - margin: 5px; - width: auto; - } - - .btn-toolbar > div.date-control { - padding-left: 2px; - } - } - - #search-buttons > .row > div, #search-buttons > .row > button { - width: 105px; - margin: 5px 0; - } -} diff --git a/client/src/sass/components/ui/subheader.scss b/client/src/sass/components/ui/subheader.scss deleted file mode 100644 index 6e7c35c73..000000000 --- a/client/src/sass/components/ui/subheader.scss +++ /dev/null @@ -1,3 +0,0 @@ -h3.ui-subheader { - font-weight: 600; -} diff --git a/client/src/sass/gov3.scss b/client/src/sass/gov3.scss deleted file mode 100644 index e515adf93..000000000 --- a/client/src/sass/gov3.scss +++ /dev/null @@ -1,2259 +0,0 @@ -@import "./variables.scss"; - -html, body { - height: 100%; -} - -body { - font-family: Calibri, Arial, 'sans serif'; - background-color: #f1f1f1; - color: #494949; - font-size: 13px; -} - -a { - color: #1a5a96; -} - -h1, h2, h3, h4, h5 { - margin-top: 0; - color: #494949; -} - -h1 { - font-size: 24px; - font-weight: 600; -} - -h2 { - font-size: 21px; -} - -h3 { - font-size: 18px; -} - -h4 { - font-size: 15px; -} - -[class*='col-'] { - padding-left: 0; - padding-right: 0; -} - -table { - margin: 10px 0; -} - -td { - padding: 4px; -} - -th { - padding: 4px; - text-align: center; -} - -.row { - margin: 0; -} - -.table-responsive { - border: none; -} - -.modal-title { - font-weight: bold; -} - -.nowrap { - white-space: nowrap; -} - -#header { - width: 100%; - z-index: 2; -} - -#header-main { - background-color: #003366; - border: none; - /* border-bottom: 2px solid #fcba19; */ - /* padding-bottom: 5px; */ -} - -#header .header-main-left, #header .header-main-right { - padding: 0; -} - -#logo { - float: left; -} - -#header .logo { - display: block; -} - -#access { - display: inline; - height: 0; - position: absolute; - width: 0; - z-index: 9; -} - -#access ul { - padding-left: 10px; - list-style: none; -} - -#access li a { - margin: 10px 0 0 -5000px; - width: 90px; - padding: 5px; - position: absolute; - top: 0; - color: #fcba19; -} - -#access li a:focus { - margin-left: 0; -} - -#header .qa-banner { - background-color: black; -} - -#header .qa-banner .container { - text-align: center; - max-width: 1140px; - padding: 15px; -} - -#header .qa-banner .container .qa-banner-text { - color: #fff; - font-size: 18px; -} - -#header .menu-button { - background-color: #38598a; - margin-top: 14px; - padding: 4px 0 3px; - text-align: center; - width: 155px; - color: #fff; - border: 1px solid white; - cursor: pointer; -} - -#header .menu-button:hover { - background-color: #5475A7; -} - -#header .menu-button span { - margin: 0; - font-weight: 400; - cursor: pointer; -} - -#header .menu-button img { - margin-right: 6px; - margin-bottom: 2px; -} - -#header .search, #searchWidget .search { - /*height: 25px; - width: 100%; */ - margin-top: 4px; - margin-left: 10px; - position: relative; -} - -#searchWidget{ - background-color: #f1f1f2; - padding: 15px; - margin-bottom: 15px; -} - -.noWhiteBorder, .yesWhiteBorder{ - margin-bottom: 15px; -} - -.yesWhiteBorder{ - border: 5px solid #fff; -} - -#searchWidget p.searchWidget_heading{ - font-weight: bold; - margin: 0; -} - -#searchWidget .search { - margin-left: 0; -} - -#header .search input, #searchWidget .search input { - border: 1px solid #fff; - height: 30px; - padding: 3px 10px; - width: 100%; -} - -#header .search .search-trigger, #searchWidget .search .search-trigger { - margin-top: -30px; - cursor: pointer; - height: 30px; - position: relative; - right: 6px; - float: right; - width: 30px; - background-image: url("../images/search-ico.png"); - background-position: 98% center; - background-repeat: no-repeat; -} - -#searchWidget .search .search-trigger { - background-image: url("../images/search-ico-blue.png"); - right: 0; -} - -#preSetSearchTerms, #allOption{ - display: none; -} - -#header-links { - margin-top: 10px; -} - -#header-links a { - color: #fff; -} - -@media ( min-width : 768px) { - #header-links>ul li>a { - padding: 0; - } -} - -#header-main-row2 { - padding-bottom: 10px; -} - -.navigationRibbon { - -webkit-box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); - -moz-box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); - box-shadow: 0px 3px 3px 1px rgba(51, 51, 51, 0.5); - border-top: 2px solid #fcba19; -} - -.navigationRibbon a { - color: #fff; - display: table-cell; - text-align: center; - vertical-align: middle; - padding: 10px 15px; - position: relative; -} - -.navigationRibbon a+a:after { - content: ""; - background: #748bad; - position: absolute; - bottom: 25%; - left: 0; - height: 50%; - width: 1px; -} - -.navigationRibbon a.current { - text-decoration: underline; - font-weight: bold; -} - -.navigationRibbon .level2Navigation a.current { - background-image: url("../images/nav-ribbon-arrow.png"); - background-position: center bottom; - background-repeat: no-repeat; -} - -.navigationRibbon .level2Navigation { - background-color: #38598a; -} - -.navigationRibbon .level3Navigation { - background-color: #5475a7; -} - -.header-main-right { - margin-top: 5px; -} - -#breadcrumbContainer { - position: relative; - height: 80px; -} - -.breadcrumb { - background: none; - padding: 0; - margin: 0; - position: absolute; - bottom: 30px; -} - -.breadcrumb>li { - list-style-type: none; - display: inline; -} - -.breadcrumb>li::after, .breadcrumb>li+li::after { - content: "/ "; - padding: 0 5px; -} - -.breadcrumb>li+li::before { - content: none; -} - -#breadcrumb li a { - font-size: 13px; -} - -#breadcrumb li #themeBreadcrumb { - font-size: 18px; -} - -#shareIcons{ - position:relative; -} - -#shareContainer{ - position: fixed; - right: 10px; - display: block; - bottom: 10px; - z-index: 1300; -} - -#shareContainer.footer-overlap { - position: absolute; - top: -122px; -} - - -#shareButton { - background-repeat: no-repeat; - float: right; - background-color: #abaeb7; - padding: 14px 14px 14px 15px; - border-radius: 3px; - color: #FFF; - text-decoration: none; - opacity: 0.75; - height: 53px; - width: 53px; - background-position: 56% 46%; -} - -#shareButton:hover { - opacity: 0.90; -} - -#shareBubble{ - background-color: #FFFFFF; - height: 120px !important; - width: 325px; - display: none; - z-index: 10; - position: absolute; - bottom: 0; - right: 53px; - border: 1px solid #e3e3e3; -} - -#shareBubble h4{ - line-height: 1.8em; - padding: 10px 10px 8px 10px; - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.share_link { - padding: 0 10px 10px 10px; -} - -.share_link_buttons { - float: right; - padding: 3px; - margin-top: -4px; - margin-right: 7px; -} - -.share_link input{ - width: 100%; - padding: 5px; -} - -/*RA-578 2016.07.18 r.lowe - added to prevent floated images from entering RC on mobile*/ -#body { - overflow: hidden; -} - -/*RA-597: Additional White Space */ -#body > p:first-of-type { - margin: 0px; -} - -#main-content-anchor { - display: block; - visibility: hidden; -} - -#main-content .table-responsive { - overflow-x: visible; - overflow-y: visible; -} - -ul.inline { - list-style-type: none; - margin: 0; - overflow: hidden; - padding: 0; -} - -ul.inline li { - float: left; - padding: 2px 10px; - position: relative; -} - -@media ( min-width : 768px) { - ul.inline li+li { - border-left: 1px solid #4b5e73; - } -} - -ul.inline li a:link, nav ul.inline li a:visited { - color: white; - display: block; - text-align: center; -} - -.iframe-video-embed, .iframe-video-embed>iframe { - max-width: 100%; -} - -.iframe-map-embed, .iframe-map-embed>iframe { - max-width: 100%; -} - -.iframe-visualization-embed, .iframe-visualization-embed>iframe { - max-width: 100%; -} - -#footer { - background-color: transparent; - border-top: 2px solid #fcba19; - position: relative; - height: $footer-height; -} - -#footer.expanded { - z-index: 1040; -} - -#footer a, #footer h2 { - color: #fff; -} - -#footer h2 { - font-size: 18px; - margin-bottom: 10px; - margin-top: 22px; - padding-right: 20px; -} - -#footer hr { - background: none repeat scroll 0 0 #4b5e73; - border: 0 none; - height: 1px; - margin: 10px 0; -} - -#footer #footerWrapper { - /* position: absolute; */ - width: 100%; - bottom: 0; -} - -#footerAdminSection ul { - clear: both; - padding: 10px 0; -} - -#footerAdminLinks { - clear: both; -} - -@media ( min-width : 768px) { - #footerMediaLinks ul { - padding-top: 22px; - } -} - -#footerMediaLinks h2 { - display: inline-block; -} - -#footerFeedback { - position: relative; - height: 50px; -} - -#footerToggle { - background-color: #003366; - text-align: center; -} - -#footerCollapsible { - display: none; - background-color: #003366; - border: 1px solid transparent; -} - -#footerAdminSection { - background-color: #003366; -} - -#feedbackWrapper { - position: absolute; - bottom: 0; - right: 0; - color: #fff; -} - -#feedbackToggle { - background-color: #38598a; - cursor: pointer; - width: 220px; - height: 40px; - padding: 10px 0; - text-align: center; -} - -#feedbackForm { - display: none; - width: 220px; - height: 300px; - background-color: #38598a; -} - -.template { - min-height: calc(100% - #{$footer-height}); - padding-bottom: 80px; - background-color: #fff; - font-size: 14px; -} - -#homeTemplate { - background-color: transparent; - margin-top: -20px; -} - -#errorPage { - padding: 10px; -} - -@media ( min-width : 768px) { - #homeTemplate { - padding-top: 200px; - } - #errorPage { - padding-top: 150px; - } -} - -#themeTemplate { - background-position: right 150px; - background-repeat: no-repeat; - background-color: transparent; -} - -#errorPage { - background-position: right 150px; - background-repeat: no-repeat; - background-color: transparent; -} - -@media ( min-width : 992px) { - .contentPageRightColumn, .homePageRightColumn { - padding-left: 15px; - } -} - -@media ( min-width : 768px) { - .contentPageLeftNavigation { - padding-right: 15px; - } -} - -.contentPageLeftNavigation ul { - list-style: none; - padding-left: 0; -} - -.contentPageLeftNavigation ul.leftNav { - border: 1px solid #e1e1e1; - padding-bottom: 10px; - padding-right: 10px; - padding-left: 10px; - width: 100%; -} - -.contentPageLeftNavigation ul li { - width: 100%; -} - -.contentPageLeftNavigation>div { - padding-left: 10px; -} - -.contentPageLeftNavigation ul li { - list-style: none; - background-position: 0 4px; - background-repeat: no-repeat; - line-height: 14px; - margin-top: 10px; - padding-left: 10px; - padding-right: 10px; -} - -ul.leftNav>li:first-child { - margin-top: 0; -} - -.contentPageLeftNavigation div>ul { - padding-bottom: 26px; - padding-top: 10px; - top: 10px; -} - -.contentPageLeftNavigation ul li.closed { - background-image: url("../images/sidecolumnnav_closed.gif"); - background-position: 0 2px; -} - -.contentPageLeftNavigation ul li ul { - display: none; -} - -.contentPageLeftNavigation ul li.open ul { - display: block; -} - -.contentPageLeftNavigation ul li.solo { - background-image: none; -} - -.contentPageLeftNavigation ul li.open { - background-image: url("../images/sidecolumnnav_open.gif"); - background-position: 0 2px; -} - -.contentPageLeftNavigation ul li a { - text-decoration: none; - display: block; - padding: 2px 0 0 4px; -} - -#topicLeftNav, #topicLeftNav .navbar-collapse { - padding: 0; - border: none; -} - -#topicLeftNav li.open a { - background-color: inherit; -} - -.contentPageLeftNavigation ul li a:hover { - text-decoration: underline; -} - -.contentPageLeftNavigation ul li.active>div.leftNav-item-wrapper a { - font-weight: bold; - text-decoration: underline; -} - -.contentPageLeftNavigation ul li.current>div.leftNav-item-wrapper a { - font-weight: bold; - text-decoration: underline; -} - -.blue-heading-bar { - background-color: #003366; /* for IE */ - background-color: rgba(0, 51, 102, 0.80); - color: #fff; - font-size: 24px; - margin: 0; - padding: 8px 15px 7px 15px; -} - -.contentPageMainColumn .blue-heading-bar { - margin: 0; -} - -.featureBoxes-3col, .tiles-container { - display: table; - width: 100%; -} - -.tiles-row { - display: table-row; -} - -.featureBoxes-3col { - margin-bottom: 15px; -} - -.featureBoxes-3col>.featureBox, .tiles-row>.tile { - background-color: #fff; /* for IE */ - background-color: rgba(255, 255, 255, 0.80); - display: table-cell; - float: none; - vertical-align: top; - padding: 20px 15px; -} - -.tiles-container-3col .tiles-row .tile { - border-top: 1px solid #e3e3e3; - width: 33%; -} - -.tiles-container-3col .tiles-row:first-child .tile { - border-top: 0; -} - -.tiles-container-2col .tiles-row .tile { - border-top: 1px solid #e3e3e3; -} - -.tiles-container-2col .tiles-row:first-child .tile { - border-top: 0; -} - -.tiles-container-2col.level2 .tiles-row:first-child .tile { - border: 1px solid #e3e3e3; -} - -.tiles-container-2col.level2 .tiles-row .tile { - border: 1px solid #e3e3e3; - border-top: 0; -} - -@media ( min-width : 768px) { - .tiles-container-2col.level2 .tiles-row .tile+.tile { - border-left: 0; - } -} - -.tiles-container-3col .tiles-row .tile+.tile, .tiles-container-2col .tiles-row .tile+.tile - { - border-left: 1px solid #e3e3e3; -} - -.featureBoxes-3col .featureBox+.featureBox { - border-left: 1px solid #e3e3e3; -} - -.featureBoxes-3col .featureBox .title, .tiles-container .tile .title { - font-size: 18px; - color: #1a5a96; -} - -.featureBoxes-3col .featureBox .text, .tiles-row .tile .tileText { - margin-top: 0; - font-size: 13px; - /* color: #7a7a7a; */ -} - - -.featureBoxes-3col .featureBox img { - width: 100% !important; - height: auto !important; -} - -.homepage-tile { - background-color: #fff; - border-bottom: 1px solid #e3e3e3; - height: 70px; - position: relative; -/* overflow: hidden; */ -} - -.homepage-tile .tile-icon { - float: left; - height: 70px; - width: 85px; - position: relative; - padding: 0 15px; -} - -.homepage-tile .down-arrow-top { - position: absolute; - top: 0; - left: 36px; - background: url("/StaticWebResources/static/gov3/images/down-arrow.png") - no-repeat scroll 0 0 transparent; - height: 7px; - width: 12px; -} - -.homepage-tile .down-arrow-bottom { - position: absolute; - bottom: 0; - left: 36px; - background: url("/StaticWebResources/static/gov3/images/down-arrow.png") - no-repeat scroll 0 0 transparent; - height: 7px; - width: 12px; -} - -.homepage-tile.first .down-arrow-top, .homepage-tile.last .down-arrow-bottom -{ - display: none; -} - -.homepage-tile .tile-content { - position: relative; - overflow: hidden; -} - -.homepage-tile .tile-text { - height: 70px; - font-size: 13px; - padding: 0 25px; -} - -.homepage-tile .tile-text .title { - padding: 5px 0 3px 0; - margin: 0; -} - -.homepage-tile .tile-search { - position: absolute; - top: 0; - right: 0; - display: none; - height: 99%; - width: 40px; - z-index: 3; - background: #fff url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") no-repeat left center; -} - -.homepage-tile .tile-search.touchable { - position: absolute; - top: 0; - right: 0; - display: block; - height: 99%; - width: 40px; - z-index: 3; - background: #fff url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") no-repeat left center; -} - -.homepage-tile:hover .tile-search, -.homepage-tile.flyout-expanded .tile-search -{ - display: block; -} - -.homepage-tile .tile-search:hover { - cursor: pointer; -} - -.homepage-tile .tile-search:hover, -.homepage-tile.flyout-expanded .tile-search { - background: #26639c url("/StaticWebResources/static/gov3/images/inlinesearch-button-on.png") no-repeat left center; -} - -.homepage-tile .tile-search-flyout { - position: absolute; - left: 1000px; - width: 100%; - max-width: 770px; - top: 0; - height: 100%; -} - -.homepage-tile .tile-search-flyout form { - height: 100%; -} - -.homepage-tile .tile-search-flyout input { - height: 99%; - width: 100%; - padding: 5px 50px 5px 15px; - border: 1px solid #26639c; - font-size: 16px; - background: #fff; -} - -.homepage-tile .tile-search-flyout input.placeholder { - background: #fff url("/StaticWebResources/static/gov3/images/tile_searchbox_placeholder.png") no-repeat left center; -} - -.homepage-tile table.ss-gac-m { - left: 85px; - width: 85%; - top: 68px; -} - -.blue-heading-bar.sortable { - position: relative; -} - -.blue-heading-bar.sortable .heading-title { - display: inline-block; - padding-right: 25px; -} - -.blue-heading-bar.sortable .tile-sort-button { - position: absolute; - top: 5px; - right: 5px; - cursor: pointer; -} - -.themeHeader { - color: #494949; - font-weight: 600; - width: 100%; - min-height: 54px; - position: relative; -} - -.themeHeader h1 { - font-size: 36px; -} - -.rightColumnBox { - background-color: #fff; /* for IE */ - background-color: rgba(255, 255, 255, 0.80); - padding: 15px; - margin-bottom: 15px; - word-wrap: break-word; -} - -.rightColumnBox p>img, .themePromoBox p>img { - display: inline; -} - -.rightColumnBox img, .themePromoBox img { - display: block; - margin: 0 auto 10px auto; - width: inherit !important; - max-width: 100% !important; - height: auto !important; -} - -/* .rightColumnBox a { */ -/* word-wrap: break-word; */ -/* } */ - -.homePageMainColumn { - padding-bottom: 15px; -} - -.contentPageMainColumn img, -.contentPageMainColumn table { - max-width: 100% !important; - height: auto !important; -} - -.tile.col-sm-6 img{ - width: 100% !important; -} - -.contentPageMainColumn ul, -.contentPageRightColumn ul, -.homePageRightColumn ul, -#footer ul.bulleted { - padding-left: 0; - list-style-type: none !important; -} - -.contentPageMainColumn ul { - padding-left: 17px; -} - -.contentPageMainColumn ol { - padding-left: 28px; -} - -.contentPageMainColumn ul>li, -.contentPageRightColumn ul>li, -.homePageRightColumn ul>li, -#footer ul.bulleted>li { - padding-left: 15px; - background: url("/StaticWebResources/static/gov3/images/bullet.png") no-repeat scroll 0 8px transparent; - margin-bottom: 3px; -} - -.contentPageMainColumn ol>li, -.contentPageRightColumn ol>li, -.homePageRightColumn ol>li { - padding-left: 2px; - background: none; - margin-left: 2px; -} - -.contentPageMainColumn > #pageIntro:after, -.contentPageMainColumn > #introduction:after { - content: ""; - display: table; - clear: both; -} - -.rightColumnBox.usefulContacts .contacts { - display: table; -} - -.rightColumnBox.usefulContacts .contacts .contactRow { - display: table-row; -} - -.rightColumnBox.usefulContacts .contacts .contactLabel { - display: table-cell; - padding-right: 15px; - padding-bottom: 10px; - font-weight: bold; -} - -.rightColumnBox.usefulContacts .contacts .contactValue { - display: table-cell; - padding-bottom: 10px; -} - -#subthemeTemplate .rightColumnBox, #topicTemplate .rightColumnBox { - background-color: #f1f1f2; -} - -#themeTemplate h1, -#subthemeTemplate h1, -#topicTemplate h1 { - margin-bottom: 0.67em; -} - -#topicTemplate h2 { - margin-top: 0.83em; - margin-bottom: 0.83em; -} - -#topicTemplate h2.blue-heading-bar { - margin: 0; -} - -#topicTemplate h3 { - margin-top: 1em; - margin-bottom: 1em; -} - -#topicTemplate h4 { - margin-top: 1.33em; - margin-bottom: 1.33em; -} - -#topicTemplate hr { - border-color: #dedede; -} - -.contentPageMainColumn p, -.contentPageRightColumn p { - margin-top: 1em; - margin-bottom: 1em; -} - -.contentPageRightColumn p:first-of-type { - margin-top: 0; -} - -#topicTemplate a.olrLinkSwitch{ - text-decoration: none; - float: right; - position: absolute; - right: 0; - bottom: 30px; -} - -div#breadcrumbContainer .olrPolicyPage{ - margin-right: 30px; -} - -.contentPageMainColumn a, -.homePageRightColumn a, -.contentPageRightColumn a, -#breadcrumbContainer a, -#search_result a h4, -#search_result #clustering a, -.contentPageMainColumn .explore a:hover, -#carousel .page .content .wrapper div a, -#carousel .page .content .wrapper div a.pull-left { - text-decoration: underline; -} - -#themeTemplate .contentPageMainColumn a, -#subthemeTemplate .contentPageMainColumn a { - text-decoration: none; -} - -.homePageMainColumn a:hover, -.homePageRightColumn a:hover, -.contentPageLeftNavigation a:hover, -.contentPageMainColumn a:hover, -.contentPageRightColumn a:hover, -#breadcrumbContainer a:hover, -#search_result a:hover h4, -#search_result #clustering a:hover { - color: #00F; -} - -.explore { - position: relative; -} - -.explore-within { - background-color: #f4f6f9; - border: 1px solid #e1e3e6; - color: #174f84; - font-size: 14px; - padding: 4px 10px; - width: 130px; - float: left; - cursor: pointer; -} - -.explore ul { - background-color: #f4f6f9; - border: 1px solid #e1e3e6; - box-shadow: 2px 2px 2px #ccc; - display: none; - left: 0; - padding: 0; - position: absolute; - top: 26px; - width: 100%; - z-index: 5; -} - -.explore ul li { - background-color: #f4f6f9; - background-image: none; - display: block; - float: none; - font-size: 13px; - padding: 6px 12px; - width: 100%; - margin: 0; -} - -.explore ul li+li { - border-top: 1px solid #e1e3e6; -} - -.explore ul li a { - color: #333; - display: block; - font-size: 13px; - text-decoration: none; -} - -.explore ul li a:hover { - text-decoration: underline; -} - -.themePromoBox { - /* float: left; - width: 49%; */ - padding-top: 15px; -} - -.themePromoBoxContent { - background-color: white; - padding: 15px; -} - -.feed+.feed { - /* margin-top: 30px; */ - -} - -.feed h4 { - line-height: inherit; -} - -span.zeroAnch { - display: none; -} - -img.back-to-top { - position: fixed; - right: 10px; - bottom: 10px; - opacity: 0.75; - filter: alpha(opacity=75); /* For IE8 and earlier */ - z-index: 1100; - cursor: pointer; - display: none; -} - -/* img.back-to-top.footer-overlap, */ -/* #footer.expanded img.back-to-top { */ -img.back-to-top.footer-overlap { - position: absolute; - top: -63px; -} - -img.back-to-top:hover { - opacity: 0.90; - filter: alpha(opacity=90); /* For IE8 and earlier */ -} - -@media ( min-width : 992px) { - .themePromoBox.left { - padding-right: 8px; - } - .themePromoBox.right { - padding-left: 8px; - } -} - -.arrow-link { - color: #1a5a96; - display: inline-block; - font-size: 14px; - font-weight: 600; - padding-left: 10px; - text-transform: uppercase; - background: - url("/StaticWebResources/static/gov3/images/bullet-arrow.png") - no-repeat scroll 0 4px transparent; - margin-top: 10px; -} - -.rightColumnBox .count { - background-color: #f1f1f1; - border: 1px solid #e3e3e3; - color: #1a5a96; - display: inline-block; - float: left; - font-size: 30px; - font-weight: 600; - margin: 2px 0 0 0; - padding: 0 4px; -} - -.rightColumnBox .caption { - color: #494949; - display: inline-block; - float: left; - font-size: 16px; - line-height: 18px; - margin-top: 8px; - padding-left: 7px; - width: 138px; -} - -.rightColumnBox .date { - font-size: 13px; - font-weight: bold; -} - - - -@media ( max-width: 750px) { - .homepage-tile .tile-text { - padding-right: 40px; - } - .homepage-tile .tile-search { - height: 40px; - line-height: normal; - display: block; - } - .homepage-tile .tile-search img { - padding: 5px 0; - } - .homepage-tile .tile-search-flyout .tile-searchbox { - height: 40px; - } - - .homepage-tile table.ss-gac-m { - left: 0; - width: 100%; - top: 39px; - } -} - -@media ( max-width : 767px) { - #header { - z-index: 2; - } - #header .container { - padding: 0; - } - #header .qa-banner .container .qa-banner-text { - font-size: 13px; - } - #header-main { - position: relative; - border-bottom: none; - margin-bottom: 0; - border-bottom: 2px solid #fcba19; - } - #header #logo img { - width: 95%; - height: 95%; - } - - #header-links>ul li { - width: 33.3%; - } - #header-links>ul li a { - text-align: left; - } - #header #header-main-row1 { - position: relative; - } - #header #header-main-row1 .header-main-left { - padding-top: 0; - padding-bottom: 0; - } - #header #header-main-row1 .header-main-right { - margin-left: -15px; - margin-right: -15px; - margin-top: 0; - padding: 10px; - position: static; - } - #header #header-main-row1 .navbar-header { - padding-bottom: 10px; - } - #header-main-row1 .search-boarder-arror::after { - border-right: 36px solid transparent; - border-top: 41px solid #c7c8ca; - content: ""; - position: absolute; - right: 95px; - top: 46px; - transform: rotate(45deg); - -ms-transform: rotate(45deg); /* IE 9 */ - -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */ - z-index: 10; - display: none; - } - #header-main-row1 .in .search-boarder-arror::after { - display: block; - } - #header #header-main-row1 .header-search { - border-top: none; - box-shadow: none; - background-color: #c7c8ca; - margin-bottom: -2px; - overflow-y: visible; - } - #header #header-main-row2 { - border: none; - max-height: none; - } - #header .search { - position: static; - } - #header .search .search-trigger { - margin-top: -30px; - } - #header .search, #header .search input { - height: 35px; - margin: 0; - bottom: 7px; - right: 20px; - font-size: 16px; - } - #header .menu-button.mini-menu-trigger, #header .search-button.mini-menu-trigger - { - background-image: url("../images/mini-menu/menu-open-mobile.png"); - background-repeat: no-repeat; - background-color: transparent; - border-radius: 0; - cursor: pointer; - height: 52px; - margin-top: 4px; - margin-bottom: 4px; - position: absolute; - right: 10px; - top: 0px; - width: 60px; - border: none; - background-position: center center; - } - #header .mini-menu-trigger+.mini-menu-trigger { - border-right: 2px solid #4b5e73; - } - #header .search-button.mini-menu-trigger { - background-image: url("../images/mini-menu/search-open-mobile.png"); - right: 70px; - } - #homeTemplate { - position: relative; - } - #breadcrumbContainer, #breadcrumbContainer>.breadcrumb, #breadcrumbContainer>a.olrLinkSwitch, .themeHeader, - .themeHeader>.themeHeaderTitle { - position: static; - } - #breadcrumbContainer { - height: auto; - padding: 10px 0; - } - .themeHeader { - height: auto; - } - #footer { - position: relative; - height: auto!important; - } - #footerThemeLinks ul { - margin: 0; - } - .homepage-tile .tile-text, - .homepage-tile - { - height: auto; - min-height: 70px; - } - #themeTemplate, #subthemeTemplate, #topicTemplate { - padding-top: 0 !important; - background-image: none !important; - } - .tiles-container-3col.level1 .tiles-row .tile+.tile, - .tiles-container-2col.level1 .tiles-row .tile+.tile { - border-left: none; - border-top: 1px solid #e3e3e3; - } - .tiles-container-2col.level2 .tiles-row:first-child .tile+.tile { - border-top: none; - } - .explore-within { - float: none; - } - .featureBoxes-3col>.featureBox, .tiles-row>.tile { - display: block; - } - .featureBoxes-3col .featureBox+.featureBox { - border-left: none; - border-top: 1px solid #e3e3e3; - } - .contentPageLeftNavigation ul.leftNav { - margin: 0; - padding: 0; - border: none; - top: 0; - } - .contentPageLeftNavigation>div { - padding-left: 0px; - } - .contentPageLeftNavigation ul.leftNav { - border-left: 1px solid #e2e2e2; - border-right: 1px solid #e2e2e2; - border-bottom: 1px solid #e2e2e2; - } - .contentPageLeftNavigation ul li { - border-top: 1px solid #e2e2e2; - margin: 0; - padding: 0; - background-image: none !important; - } - .contentPageLeftNavigation ul.leftNav>li:first-child { - border-top: none; - } - .contentPageLeftNavigation ul.leftNav li a { - padding: 15px 50px 15px 25px; - } - .contentPageLeftNavigation ul.leftNav li li a { - padding-left: 40px; - } - .contentPageLeftNavigation ul.leftNav li li li a { - padding-left: 55px; - } - .contentPageLeftNavigation ul.leftNav li li li li a { - padding-left: 70px; - } - .contentPageLeftNavigation ul.leftNav li li li li li a { - padding-left: 85px; - } - .contentPageLeftNavigation ul.leftNav li li li li li li a { - padding-left: 100px; - } - .topic-menu-trigger { - background-image: url("../images/mini-menu/section-nav-open.png"); - background-position: 97% center; - background-repeat: no-repeat; - color: #1a5a96; - cursor: pointer; - display: block; - font-size: 16px; - padding: 15px 10px; - width: 100%; - text-align: left; - border: 1px solid #e2e2e2; - border-radius: 0; - margin: 0; - } - .leftNav-item-wrapper { - position: relative; - } - #topicLeftNav .level-trigger { - background-position: center center; - background-repeat: no-repeat; - border-left: 1px solid #e2e2e2 !important; - cursor: pointer; - display: inline-block; - float: right; - height: 100%; - position: absolute; - right: 0; - top: 0; - width: 50px; - } - #topicLeftNav li.open>.leftNav-item-wrapper .level-trigger { - background-image: url("../images/mini-menu/section-nav-arrow-dn.png"); - } - #topicLeftNav li.closed>.leftNav-item-wrapper .level-trigger { - background-image: url("../images/mini-menu/section-nav-arrow-up.png"); - } - #shareIcons{ - display:none; - } -} - -@media ( max-width : 992px) { - .themePromoBox { - margin-bottom: 15px; - padding-top: 0; - } - .tiles-container { - margin-bottom: 15px; - } - .contentPageRightColumn{ - margin-top: 15px; - } -} - -.alert-success:before { - position: relative; - top: 1px; - margin-right: 10px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; - -moz-osx-font-smoothing: grayscale; - content: "\e013"; - font-size: larger; -} - -.alert-info:before { - position: relative; - top: 1px; - margin-right: 10px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; - -moz-osx-font-smoothing: grayscale; - content: "\e086"; - font-size: larger; -} - -.alert-warning:before { - position: relative; - top: 1px; - margin-right: 10px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; - -moz-osx-font-smoothing: grayscale; - content: "\e107"; - font-size: larger; -} - -.alert-danger:before { - position: relative; - top: 1px; - margin-right: 10px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; - -moz-osx-font-smoothing: grayscale; - content: "\e101"; - font-size: larger; -} - -.alert:before { - float: left; -} - -.alert p{ - margin: 0; - padding-left: 1.8em; -} - -.ss-gac-m tr:hover { - cursor: pointer; -} - -/* Collapsed header styles */ - -#header.collapsed-header #header-main { - border-bottom: 2px solid #fcba19; - margin-bottom: 0; -} - -#header.collapsed-header #logo img { - width: 95%; - height: 95%; -} - -#header.collapsed-header #header-main > .container { - position: relative; -} - -#header.collapsed-header .hidden-xs { - display: none !important; -} - -#header.collapsed-header #header-main-row1 { - position: relative; -} - -#header.collapsed-header #header-main-row1 .header-main-left { - float: none; - width: auto; -} - -#header.collapsed-header #header-main-row1 .navbar-header { - float: none; - padding-bottom: 10px; -} - -#header.collapsed-header .menu-button.mini-menu-trigger, -#header.collapsed-header .search-button.mini-menu-trigger { - background-color: transparent; - background-image: url("../images/mini-menu/menu-open-mobile.png"); - background-position: center center; - background-repeat: no-repeat; - border: medium none; - border-radius: 0; - cursor: pointer; - height: 52px; - margin-top: 4px; - margin-bottom: 4px; - position: absolute; - right: 10px; - top: 0; - width: 60px; - display: block; -} - -#header.collapsed-header .mini-menu-trigger + .mini-menu-trigger { - border-right: 2px solid #4b5e73; -} - -#header.collapsed-header .search-button.mini-menu-trigger { - background-image: url("../images/mini-menu/search-open-mobile.png"); - right: 70px; -} - -#header.collapsed-header .navbar-collapse.collapse { - display: none !important; -} - -#header.collapsed-header .navbar-collapse.collapse.in { - display: block !important; -} - -#header.collapsed-header #header-main-row1 .header-search { - background-color: #c7c8ca; - border-top: medium none; - box-shadow: none; - margin-bottom: -2px; - - height: 0; - position: absolute; - right: 50px; - width: 440px; -} - -#header.collapsed-header .visible-xs-block { - display: block !important; -} - -#header.collapsed-header #header-main-row1 .header-search .search-boarder-arror::after { - border-right: 36px solid transparent; - border-top: 41px solid #c7c8ca; - content: ""; - display: none; - position: absolute; - right: 61px; - top: -14px; - transform: rotate(45deg); - -ms-transform: rotate(45deg); /* IE 9 */ - -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */ - z-index: 10; -} - -#header.collapsed-header #header-main-row1 .header-search.in .search-boarder-arror::after { - display: block !important; -} - -#header.collapsed-header #header-main-row1 .header-search .header-main-right { - margin-left: -15px; - margin-right: -15px; - margin-top: 0; - padding: 10px; - position: static; -} - -#header.collapsed-header #header-main-row1 .header-search .header-main-right .search { - position: static; -} - -#header.collapsed-header #header-main-row1 .header-search .header-main-right .search, -#header.collapsed-header #header-main-row1 .header-search .header-main-right .search input { - bottom: 7px; - height: 35px; - margin: 0; - right: 20px; -} - -#header.collapsed-header #header-main-row1 .header-search .header-main-right .search .search-trigger { - margin-top: -30px; -} - -#header.collapsed-header #header-main-row2 { - border: medium none; - max-height: none; -} - -#header.collapsed-header #header-main-row2 { - position: absolute; - right: 0; - background-color: #036; - right: 65px; - width: 440px; - padding: 0; -} - -#header.collapsed-header #header-main-row2 .header-main-right { - margin: 0; -} - -#header.collapsed-header .navbar-fixed-top .navbar-collapse { - height: 10px; - margin-left: -15px; - margin-right: -15px; - padding-left: 15px; - padding-right: 15px; -} - -#header.collapsed-header .col-lg-6 { - width: auto; - float: none; - left: auto; - right: auto; -} - -#header.collapsed-header .header-main-left { - padding: 0; -} - -#header.collapsed-header .navbar-nav { - float: none; -} - -#header.collapsed-header #header-links { - margin: 0; -} - -#header.collapsed-header #header-links > ul { - padding: 6px 5px; - margin: 0; -} - -#header.collapsed-header #header-links > ul li { - width: 33.3%; - padding: 4px 10px; -} - -#header.collapsed-header #header-links > ul li a { - text-align: left; - padding: 0 10px; -} - -#header.collapsed-header #header-links ul.inline li + li { - border-left: 0; -} - -#header.collapsed-header #govNavMenu { - position: static; - z-index: auto; - top: auto; - width: auto; - float: none; - background-color: #036; -} - -/* .search-button.mini-menu-trigger{ */ -/* background-image: url("../images/mini-menu/search-open-mobile.png"); */ -/* background-repeat: no-repeat; */ -/* background-color: transparent; */ -/* border-radius: 0; */ -/* cursor: pointer; */ -/* height: 52px; */ -/* margin-top: 4px; */ -/* margin-bottom: 4px; */ -/* position: absolute; */ -/* left: 420px; */ -/* top: 0px; */ -/* width: 60px; */ -/* border: none; */ -/* background-position: center center; */ -/* } */ - - - -/* [RA-359] CS - homepage customizations for BC Gov Services Campaign */ -.popular-services-search .homepage-tile { - border-bottom: 0; - margin-bottom: 15px; - min-height: 0; -} - -.popular-services-search .homepage-tile .tile-content { - height: 100%; -} - -.popular-services-search .homepage-tile .tile-search { - display: block; - background: #26639c url("/StaticWebResources/static/gov3/images/inlinesearch-button-on.png") no-repeat scroll left center; - height: 100%; -} - -@media (max-width : 767px) { - .popular-services-search .homepage-tile .tile-search { - background: #fff url("/StaticWebResources/static/gov3/images/inlinesearch-button-off.png") no-repeat scroll left center; - } -} - -.popular-services-search .homepage-tile .tile-search-flyout { - position: static; - max-width: 815px; -} - -.popular-services-search .homepage-tile .tile-search-flyout form { - max-width: 815px; -} - -.popular-services-search .homepage-tile .tile-search-flyout form .tile-searchbox { - border: 0; - padding-right: 45px; -} - -.popular-services-search .homepage-tile .tile-search-flyout form .tile-searchbox.placeholder { - background: none; -} - -.popular-services-search .homepage-tile .ss-gac-m { - left: 0; -} - -.popular-services-text { - background-color: #fff; - margin-bottom: 15px; - padding: 10px 15px; - font-size: 16px; - color: #1a5a96; -} - -.popular-services-text p { - margin: 0; -} - -.campaign-service-buttons .blue-heading-bar { - display: none; -} - -.campaign-service-buttons .featureBoxes-3col h3.title { - display: none; -} - -.campaign-service-buttons .featureBoxes-3col p > a { - text-decoration: underline; -} - -.campaign-service-buttons .featureBoxes-3col p > a.btn { - text-decoration: none; -} - -.alert-content { - line-height: 1; - vertical-align: middle; -} -.alert-icon { - vertical-align: middle; -} - -table.alert-box { - margin: 5px; -} -td.alert-icon-col { - width: 20px; - vertical-align: middle; - padding: 0; -} -td.alert-content-col { - vertical-align: middle; - padding: 0; -} - -/* end changes for [RA-359] */ -.search-suggestion-full { - width: 100%; - visibility: hidden; -} -#suggestion_form { - position: relative; -} - -/* begin changes for [CLD-1454] */ -.panel-heading .collapseArrow{ - background-image: url("/StaticWebResources/static/gov3/images/accordion-chevron.png"); - background-size: 14px 14px; - background-repeat: no-repeat; - background-position: right 0px bottom 0px; - height: 14px; - width: 14px; - overflow:hidden; - float:right; - -} - -.panel-heading .open{ - /*Point arrow upwards*/ - webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); - -ms-transform: rotate(180deg); - -o-transform: rotate(180deg); - transform: rotate(180deg); -} - -.accordion-container{ - margin-top:6px; -} - -.panel-group .panel { - margin-top: 6px; - border-radius: 0px; -} - -.panel-body p.panel-text{ - margin: 0px; -} - -.panel-group .panel+.panel { - margin-top: 6px; -} - -.accordion-btn-container{ - width:170px; -} - -button.accordion-btn{ - background-color: #f1f1f3; - border:none; - padding:5px 8px; - color: #1c5a97; - text-decoration: none !important; -} - -a.accordion-btn{ - background-color: #f1f1f3; - border:none; - padding:5px 8px; - color: #1c5a97; - text-decoration: none !important; -} - -a.accordion-btn:hover{ - background-color: #f1f1f3; - border:none; - padding:5px 8px; - color: #1c5a97; - text-decoration: none !important; - cursor: pointer; -} - -.accordion-bar { - background-color: #f1f1f1; - padding: 5px 0px; - -} - -.panel>.panel-heading { - background-color: #f1f1f3; - border-color: #f1f1f3; - padding: 8px; - cursor: pointer; -} -.panel-heading{ - border-radius: 0; -} - -.panel{ - border-color: #f1f1f3; - border-radius: 0; -} - -.panel-text{ - margin-top: -1em; -} -.panel-text p{ - margin-bottom: 0em; -} -.panel>.panel-heading+.panel-collapse>.panel-body { - border: 2px #f1f1f3; -} - -#topicTemplate .panel-title{ - font-weight: bold; - color: #1c5a97; - max-width: 95%; - font-size: 16px; - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.panel-title p{ - margin-top: 0; - margin-bottom: 0; -} - -.show-btn{ - margin-right:-4px; -} - -.hide-btn{ - margin-left:-4px; -} - -#topicTemplate .contentPageMainColumn a.accordionA{ - text-decoration:none; -} - -#topicTemplate .contentPageMainColumn a.accordionA:hover{ - text-decoration: none; - color: #1c5a97; -} -/* end changes for [CLD-1454] */ - -/* RA-31, Twitter feed */ -h5.twitterUserName{ - margin-bottom: 5px; - font-weight: bold; - /*float: left;*/ -} - -h5.twitterUserName a{ - font-weight: normal; - color: #aaa; - /*float: left;*/ - margin-top: 5px; -} - -.twitter-follow{ - margin-bottom: 15px; - /*float: left;*/ - clear: left; - font-weight: bold; -} - -.feedEntry .createdAgo{ - font-size: .9em; - color: #aaa; - margin-bottom: 20px; -} - -.twitterHeader{ - width: 100%; - border-bottom: 1px solid #fff; - /*float: left;*/ - margin-bottom: 15px; - padding-bottom: 15px; -} - -.feed.rightColumnBox{ - float: left; -} -/* end of changes for RA-31, Twitter feed */ - -#main-content #body a.btn { - word-break: normal; -} - -/* break a link if the link text is too long for the page width, especially in mobile */ -#main-content #body a { - word-wrap: break-word; - /* RA-636 - Non standard for webkit */ - word-break: break-word; -} - -/* ALERT CUSTOMIZATIONS */ - -.alert-success { - color: #2d4821; -} - -.alert-warning { - color: #6c4a00; - background-color: #f9f1c6; -} - -.alert-danger { - color: #d2322d; -} -.printHeader { - display: none; -} -@media print { - /*Globals*/ - body { - font-family: Arial, Helvetica, sans-serif; - /* width:720px; */ - } - a { - text-decoration: underline !important; - } - a[href]:after { - content: none; - } - #breadcrumbContainer { - display: none; - } - .template { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - .container { - padding: 0; - } - .printHeader { - display: block; - } - .row { - /* height: 120px; */ - padding: 15px; - } - .featureBoxes-3col>.featureBox { - display: block; - width: 100% - } - .contentPageMainColumn ul>li, .contentPageRightColumn ul>li, ul.bulleted>li - { - list-style-type: disc; - margin-left: 20px; - } - .rightColumnBox { - padding: 0; - } - .contentPageRightColumn { - width: 100%; - } - .tiles-row { - width: 100%; - display: block; - } - - /*Homepage*/ - #main-content { - /* margin-top:50px; */ - width: 100%; - overflow: hidden; - } - .homePageMainColumn>.blue-heading-bar { - margin-top: 10px; - } - .homePageMainColumn>.sortable { - display: inline; - } - .featureBoxes-3col { - /* display:none; */ - - } - .blue-heading-bar { - padding: 0; - } - .tile-sort-button { - display: none; - } - .homepage-tile .tile-icon { - display: none; - } - - /*Theme Page*/ - .themeHeader h1 { - margin: 50px 0 0 0; - } - .themePromoBoxContent { - padding: 0; - } - - .themeHeader { - padding-left:10px; - } - - .tiles-container-2col .tiles-row .tile { - width: 100%; - height: 100%; - display: block; - border: 0 !important; - border-bottom: 1px solid black !important; - padding: 20px 0; - } - - .explore-within { - float: none; - border: 1px solid black !important; - } - - /*Topic Page*/ - .col-sm-3 { - width: 100%; - } - .col-sm-offset-3 { - margin: 0; - } - - /*Footer*/ - #footer { - display: none; - } - -} diff --git a/client/src/sass/header.scss b/client/src/sass/header.scss deleted file mode 100644 index c3ab015c1..000000000 --- a/client/src/sass/header.scss +++ /dev/null @@ -1,213 +0,0 @@ -@import "./mixins.scss"; - -$nav-background-color: #38598a; -$nav-background-color-test: #448a38; -$nav-background-color-dev: #8a3844; -$nav-background-color-trn: #744e91; -$nav-background-color-uat: #d98747; - -$nav-active-background-color: #5475a7; -$nav-active-background-color-test: #60a654; -$nav-active-background-color-dev: #a65460; -$nav-active-background-color-trn: #9b5ab5; -$nav-active-background-color-uat: #db976d; - -#header { - #working-indicator { - position: absolute; - top: 15px; - right: 15px; - background-color: #2e6da4; - border-radius: 3px; - font-size: 13px; - color: white; - padding: 1px 6px; - white-space: nowrap; - - .spinner { - border-color: white; - width: 11px; - height: 11px; - } - } - - #banner { - float: left; - margin-top: 20px; - margin-left: 35px; - color: #fff; - font-weight: 600; - } -} - -#top-nav { - margin-bottom: 0; - background-color: $nav-background-color; - border-radius: 0; - border: 0; - border-top: 2px solid #fcba19; - -webkit-box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); - -moz-box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); - box-shadow: 0 3px 3px 1px rgba(51, 51, 51, 0.5); - - > .container { - @include flex; - align-items: center; - } - - #rollover-notice-button { - span { - margin-left: 5px; - } - } - - #navbar-right { - margin: 0 0 0 auto; - - .dropdown-menu { - right: 0; - left: auto; - } - } - - #profile-menu + .dropdown-menu { - padding: 15px 15px 5px 15px; - - .form-group { - margin-top: 10px; - } - - .dropdown-control, - .dropdown-control .btn { - width: 100%; - } - - .btn-primary { - width: 100%; - margin-bottom: 10px; - } - } - - .navbar-nav > li > a { - color: #fff; - } - .navbar-nav > li > a:hover { - color: #fff; - text-decoration: underline; - } - .navbar-nav > li > a:focus { - color: #fff; - } - .navbar-nav > li > .dropdown-menu { - color: #fff; - background-color: $nav-background-color; - font-size: 13px; - } - .navbar-nav > li > .dropdown-menu > li > a { - color: #fff; - } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus { - color: #fff; - background-color: $nav-active-background-color; - text-decoration: underline; - } - .navbar-nav > .active > a { - color: #fff; - background-color: $nav-active-background-color; - text-decoration: underline; - } - .navbar-nav > .active > a:hover, - .navbar-nav > .active > a:focus { - color: #fff; - background-color: $nav-active-background-color; - } - .navbar-nav > .open > a { - color: #fff; - background-color: $nav-background-color; - text-decoration: underline; - } - .navbar-nav > .open > a:hover, - .navbar-nav > .open > a:focus { - color: #fff; - background-color: $nav-background-color; - } - - &.env-test { - background-color: $nav-background-color-test; - - .navbar-nav > li > .dropdown-menu, - .navbar-nav > .open > a, - .navbar-nav > .open > a:hover, - .navbar-nav > .open > a:focus { - background-color: $nav-background-color-test; - } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus, - .navbar-nav > .active > a, - .navbar-nav > .active > a:hover, - .navbar-nav > .active > a:focus { - background-color: $nav-active-background-color-test; - } - } - - &.env-dev { - background-color: $nav-background-color-dev; - - .navbar-nav > li > .dropdown-menu, - .navbar-nav > .open > a, - .navbar-nav > .open > a:hover, - .navbar-nav > .open > a:focus { - background-color: $nav-background-color-dev; - } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus, - .navbar-nav > .active > a, - .navbar-nav > .active > a:hover, - .navbar-nav > .active > a:focus { - background-color: $nav-active-background-color-dev; - } - } - - &.env-uat { - background-color: $nav-background-color-uat; - - .navbar-nav > li > .dropdown-menu, - .navbar-nav > .open > a, - .navbar-nav > .open > a:hover, - .navbar-nav > .open > a:focus { - background-color: $nav-background-color-uat; - } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus, - .navbar-nav > .active > a, - .navbar-nav > .active > a:hover, - .navbar-nav > .active > a:focus { - background-color: $nav-active-background-color-uat; - } - } - - &.env-trn { - background-color: $nav-background-color-trn; - - .navbar-nav > li > .dropdown-menu, - .navbar-nav > .open > a, - .navbar-nav > .open > a:hover, - .navbar-nav > .open > a:focus { - background-color: $nav-background-color-trn; - } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus, - .navbar-nav > .active > a, - .navbar-nav > .active > a:hover, - .navbar-nav > .active > a:focus { - background-color: $nav-active-background-color-trn; - } - } -} - -#rollover-notice { - .btn-primary { - width: 100%; - } -} diff --git a/client/src/sass/init.scss b/client/src/sass/init.scss deleted file mode 100644 index a6dfb6a70..000000000 --- a/client/src/sass/init.scss +++ /dev/null @@ -1,37 +0,0 @@ -#initialization { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 10% 15%; - background-color: white; - z-index: 9999; - transform-origin: 50%, 50%; - opacity: 1; - transition: transform 1s ease, opacity 400ms; - - &.done { - opacity: 0; - transform: scale(1.2); - } - - #init-message { - font-size: 20px; - font-family: Arial, 'sans serif'; - } - - .progress-bar { - width: 5%; - min-width: 30px; - } - - #loading-error-message { - margin-top: 50px; - text-align: center; - - p { - white-space: pre-line; - } - } -} diff --git a/client/src/sass/main.scss b/client/src/sass/main.scss deleted file mode 100644 index 23b70d223..000000000 --- a/client/src/sass/main.scss +++ /dev/null @@ -1,132 +0,0 @@ -@import 'gov3'; -@import 'init'; -@import 'header'; -@import 'views/all'; -@import 'components/all'; -@import 'print'; -@import 'mixins'; - -#app { - height: 100%; -} - -#main { - height: 100%; -} - -.page-header { - margin: 20px 0; -} - -.nowrap { - white-space: nowrap; -} - -.spinner-container { - text-align: center; - padding: .5rem 0; -} - -.spinner { - display: inline-block; - vertical-align: baseline; - width: 24px; - height: 24px; - animation: rotate .8s infinite linear; - border: 2px solid #2e6da4; - border-right-color: transparent !important; - border-radius: 50%; - margin-bottom: -2px; -} - -html { - font-size: 14px; -} - -button { - .spinner { - margin-left: 10px; - width: 14px; - height: 14px; - } - - &.btn-primary { - .spinner { - border-color: white; - } - } -} - -th { - text-align: left; -} - -@keyframes rotate { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -a.light { - color: grey; -} - -// Bootstrap overrides - -.alert-success { - @include flex; - align-items: center; - margin-top: 30px; - - &:before { - content: ''; - } - - .btn { - margin-left: auto; - } -} - -.alert-warning { - &:before { - content: ''; - } -} - -// Spacing - -.nopadding { - padding: 0 !important; -} - -.mr-5 { - margin-right: 5px; -} - -.ml-5 { - margin-left: 5px; -} - -// Spacing End - -.row.equal-height { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - flex-wrap: wrap; -} - -.text-label { - font-weight: bold; - margin: 5px 0; -} - -#confirm-dialog .timer { - margin-left: 3px; - font-weight: bold; -} - -// Fix for extra dark overlay when multiple modals are open -[aria-hidden="true"] .modal-backdrop.in { - opacity: 0; -} diff --git a/client/src/sass/mixins.scss b/client/src/sass/mixins.scss deleted file mode 100644 index 49fd76c8e..000000000 --- a/client/src/sass/mixins.scss +++ /dev/null @@ -1,7 +0,0 @@ -@mixin flex { - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; -} diff --git a/client/src/sass/print.scss b/client/src/sass/print.scss deleted file mode 100644 index 07ae5dddd..000000000 --- a/client/src/sass/print.scss +++ /dev/null @@ -1,155 +0,0 @@ -@page { - margin: 10mm 5mm; -} - -@media print { - .watermark { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - font-size: 72px; - font-weight: bold; - color: hsl(0, 0, 90%) !important; - -webkit-print-color-adjust: exact !important; - color-adjust: exact !important; - z-index: -1; - } - - .search-bar, - .history, - .btn-group, - .btn, - .checkbox, - .checkbox-control { - display: none; - } - - h1 { - font-size: 18px; - } - - h2 { - font-size: 16px; - } - - h3 { - font-size: 14px; - } - - h4 { - font-size: 12px; - } - - a { - text-decoration: none !important; - } - - .template { - margin: 0; - width: 100%; - font-size: 10px; - } - - @for $i from 1 through 12 { - .col-sm-#{$i} { - float: left; - width: #{percentage(round($i * 8.33) / 100)}; - } - } - - .row { - padding-top: 0.5em; - padding-bottom: 0.5em; - } - - .well { - padding: 10px; - } - - #rental-requests-detail { - .well { - padding: 0; - border: none; - } - - .request-information { - margin-top: 0; - } - - #rental-requests-data { - font-size: 8px; - line-height: 1; - - > div { - width: 35%; - } - - > div:nth-child(even) { - margin-left: 30%; - } - } - - #rotation-list { - font-size: 8px; - } - - @supports (size: landscape) { - #rotation-list { - font-size: 10px; - } - } - - /* override bootstrap's white background so watermark can be seen clearly */ - td, th { - background: transparent !important; - } - } - - div.row { - margin: 0 -15px; - } - - .col-md-6 { - float: initial; - } - - #rotation-list { - th, td { - padding: 2px; - } - - th span { - display: block; - } - - td { - word-break: break-all; - } - - th:first-child, td:first-child, th:nth-child(10), td:nth-child(10) { - display: none; - } - - th:nth-child(2), td:nth-child(2), th:last-child, td:last-child { - display: table-cell !important; - } - - th:last-child, td:last-child { - min-width: 150px; - } - } - - .row:after { - margin-bottom: -25px; - } - - [class*='col-']:last-child .row:after { - margin-bottom: 0; - } - - div#history-list { - max-height: none; - } -} diff --git a/client/src/sass/variables.scss b/client/src/sass/variables.scss deleted file mode 100644 index 9038ea3d3..000000000 --- a/client/src/sass/variables.scss +++ /dev/null @@ -1,13 +0,0 @@ -// Small tablets and large smartphones (landscape view) -$screen-sm: 576px; - -// Small tablets (portrait view) -$screen-md: 768px; - -// Tablets and small desktops -$screen-lg: 990px; - -// Large tablets and desktops -$screen-xl: 1200px; - -$footer-height: 45px; diff --git a/client/src/sass/views/all.scss b/client/src/sass/views/all.scss deleted file mode 100644 index e2dc1bbb7..000000000 --- a/client/src/sass/views/all.scss +++ /dev/null @@ -1,12 +0,0 @@ -@import './dialogs/all'; -@import './business-portal'; -@import './district-admin'; -@import './equipment-list'; -@import './home'; -@import './owners'; -@import './projects'; -@import './rental-agreements'; -@import './rental-requests'; -@import './roles'; -@import './rollover'; -@import './users'; diff --git a/client/src/sass/views/business-portal.scss b/client/src/sass/views/business-portal.scss deleted file mode 100644 index 3e050e3cc..000000000 --- a/client/src/sass/views/business-portal.scss +++ /dev/null @@ -1,32 +0,0 @@ -#business-portal { - #hets-logo { - float: left; - margin-right: 20px; - margin-bottom: 15px; - width: 218px; - height: 109px; - } - - #associate-owner { - a { - font-weight: 700; - } - - input#secretKey { - width: 250px; - } - - input#postalCode { - width: 120px; - } - - button { - vertical-align: top; - } - - .validation-error { - margin-top: 1em; - color: #a94442; - } - } -} diff --git a/client/src/sass/views/dialogs/all.scss b/client/src/sass/views/dialogs/all.scss deleted file mode 100644 index 60b72baa0..000000000 --- a/client/src/sass/views/dialogs/all.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import "./contacts-edit"; -@import "./documents-list"; -@import "./equipment-transfer"; -@import "./rental-rates-edit"; -@import "./notes"; -@import "./error-dialog"; diff --git a/client/src/sass/views/dialogs/contacts-edit.scss b/client/src/sass/views/dialogs/contacts-edit.scss deleted file mode 100644 index b21ebee12..000000000 --- a/client/src/sass/views/dialogs/contacts-edit.scss +++ /dev/null @@ -1,14 +0,0 @@ -#contacts-edit { - #notes { - height: 106px; - } - - .modal-title .label { - font-size: 100%; - margin-left: 20px; - } - - .modal-title .btn { - margin-left: 20px; - } -} diff --git a/client/src/sass/views/dialogs/documents-list.scss b/client/src/sass/views/dialogs/documents-list.scss deleted file mode 100644 index 8a8b1a59d..000000000 --- a/client/src/sass/views/dialogs/documents-list.scss +++ /dev/null @@ -1,19 +0,0 @@ -#documents-dialog { - .alert { - margin-top: 10px; - - .btn { - float: right; - margin-top: -7px; - } - } - - .file-picker-container { - text-align: center; - padding: 0 15px 15px 15px; - } - - .file-picker { - margin-bottom: 10px; - } -} diff --git a/client/src/sass/views/dialogs/equipment-transfer.scss b/client/src/sass/views/dialogs/equipment-transfer.scss deleted file mode 100644 index b23e3bb84..000000000 --- a/client/src/sass/views/dialogs/equipment-transfer.scss +++ /dev/null @@ -1,16 +0,0 @@ -#equipment-transfer { - #select-equipment { - .checkbox { - margin: 0; - text-align: center; - } - - tr th:first-child .checkbox { - margin-bottom: -2px; - - label { - font-weight: bold; - } - } - } -} diff --git a/client/src/sass/views/dialogs/error-dialog.scss b/client/src/sass/views/dialogs/error-dialog.scss deleted file mode 100644 index 725703957..000000000 --- a/client/src/sass/views/dialogs/error-dialog.scss +++ /dev/null @@ -1,28 +0,0 @@ -#error-dialog { - #error-message { - font-size: 200%; - } - - #api-error { - margin-top: 2em; - - p { - font-size: 110%; - } - - #api-url-path { - color: #286498; - } - - #api-http-status { - color: #A43737; - } - - #api-error-response { - p { - margin-bottom: 0; - font-weight: bold; - } - } - } -} diff --git a/client/src/sass/views/dialogs/notes.scss b/client/src/sass/views/dialogs/notes.scss deleted file mode 100644 index ce10d37e1..000000000 --- a/client/src/sass/views/dialogs/notes.scss +++ /dev/null @@ -1,9 +0,0 @@ -#notes-list { - max-height: 200px; - overflow: auto; - margin-bottom: 20px; - - table { - margin-top: 0; - } -} diff --git a/client/src/sass/views/dialogs/rental-rates-edit.scss b/client/src/sass/views/dialogs/rental-rates-edit.scss deleted file mode 100644 index a7ee111db..000000000 --- a/client/src/sass/views/dialogs/rental-rates-edit.scss +++ /dev/null @@ -1,30 +0,0 @@ -#rental-rates-edit, #rental-conditions-edit { - - #dollar-value { - padding-right: 10px; - overflow: hidden; - text-align: right; - text-overflow: ellipsis; - } - - .forms-container { - .form-item { - border-bottom: 1px solid #ccc; - padding-bottom: 15px; - margin-bottom: 30px; - - &:last-child { - border-bottom: none; - margin-bottom: 0; - } - } - } - - .align-right { - text-align: right; - } - - .remove-btn { - margin-right: 5px; - } -} diff --git a/client/src/sass/views/district-admin.scss b/client/src/sass/views/district-admin.scss deleted file mode 100644 index c0945e21a..000000000 --- a/client/src/sass/views/district-admin.scss +++ /dev/null @@ -1,2 +0,0 @@ -#district-admin { -} diff --git a/client/src/sass/views/equipment-list.scss b/client/src/sass/views/equipment-list.scss deleted file mode 100644 index b20b01be4..000000000 --- a/client/src/sass/views/equipment-list.scss +++ /dev/null @@ -1,69 +0,0 @@ -@import '../mixins'; -@import '../variables'; - -#equipment-list { - .search-bar #filters { - .btn-group { - width: calc(100% / 5); - min-width: 150px; - } - - .btn-group .btn { - width: 100%; - max-width: 100%; - } - } -} - -#equipment-detail { - .top-container { - margin: 0 5px; - } - - #equipment-bottom { - margin: 15px 0; - } - - .equipment-header { - margin-bottom: 15px; - } - - .well { - margin-left: 5px; - margin-right: 5px; - } - - .label { - font-size: 100%; - margin-right: 5px; - } - - .checkbox { - margin-top: 0; - margin-bottom: 0; - height: 16px; - } - - .btn-group > .btn + .btn { - margin-left: -1px; - } -} - -#equipment-add, -#equipment-edit { - h4 strong span { - margin-left: 20px; - } - - .form-group { - h4 { - margin: 0; - } - } -} - -#seniority-edit { - h4 strong span { - margin-left: 20px; - } -} diff --git a/client/src/sass/views/home.scss b/client/src/sass/views/home.scss deleted file mode 100644 index 886d51c56..000000000 --- a/client/src/sass/views/home.scss +++ /dev/null @@ -1,31 +0,0 @@ -@import 'variables'; - -#home_image { - height: 200px; -} - -#home { - .fixed-width { - &.small .dropdown-toggle { - width: 125px; - } - - .dropdown-toggle { - width: 150px; - } - } - - .btn { - margin-right: 5px; - } - - .rotation-list-form { - text-align: right; - } - - @media only screen and (max-width: $screen-lg) { - .rotation-list-form { - text-align: left; - } - } -} diff --git a/client/src/sass/views/owners.scss b/client/src/sass/views/owners.scss deleted file mode 100644 index aa7bbacd4..000000000 --- a/client/src/sass/views/owners.scss +++ /dev/null @@ -1,87 +0,0 @@ -#owners-detail { - #owners-top { - margin: 0 5px 10px 5px; - - #owner-notes-button, #owner-documents-button { - margin-left: 5px; - } - } - - #owners-header { - margin-left: 5px; - margin-right: 5px; - } - - #owners-data { - .checkbox { - margin-top: 0; - margin-bottom: 0; - height: 16px; - } - } - - #contact-list { - max-height: 150px; - width: 100%; - overflow-y: auto; - margin-bottom: 10px; - - table { - margin: 0; - } - - th, td { - max-width: 125px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - } - - #equipment-list { - td:nth-child(4) { - width: 350px; - } - - .attachment { - display: inline-block; - } - } - - .well { - margin-left: 5px; - margin-right: 5px; - } - - .label { - font-size: 100%; - margin: 6px 5px; - display: inline-block; - } - - .col-display-label { - width: 170px; - } - - .alert { - margin-top: 10px; - - .btn { - float: right; - } - } - - h1 { - small { - font-size: 85%; - } - } -} - -#owners-edit { - .form-group { - h4 { - margin: 0; - } - } -} diff --git a/client/src/sass/views/projects.scss b/client/src/sass/views/projects.scss deleted file mode 100644 index 16171d5a3..000000000 --- a/client/src/sass/views/projects.scss +++ /dev/null @@ -1,94 +0,0 @@ -#projects-detail { - .top-container { - margin: 0 5px; - } - - #projects-top { - margin-bottom: 10px; - } - - #equipment-list { - overflow-y: auto; - width: 100%; - max-height: 400px; - margin-top: 20px; - } - - .well { - margin-left: 5px; - margin-right: 5px; - } - - .label { - font-size: 100%; - margin-right: 5px; - } - - #add-request-button { - margin-left: 20px; - } -} - -#contact-list { - max-height: 150px; - width: 100%; - overflow-y: auto; - margin-bottom: 10px; - - table { - margin: 0; - } - - th, td { - max-width: 125px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .btn { - margin-left: 0; - } - -} - -#projects-edit { - textarea { - resize: vertical; - } -} - -#time-entry { - .remove-btn { - margin-left: 5px; - } - - .column-title { - margin-bottom: 5px; - font-weight: bold; - } - - .time-records-list { - padding: 0; - list-style: none; - max-height: 100px; - overflow: auto; - - .list-item { - margin: 5px 0; - } - } - - .time-entries-container { - margin: 30px 0 5px 0; - } - - .highlight { - font-weight: bold; - color: red; - } - - .small-text { - font-size: 10px; - } -} diff --git a/client/src/sass/views/rental-agreements.scss b/client/src/sass/views/rental-agreements.scss deleted file mode 100644 index 732dc4ca7..000000000 --- a/client/src/sass/views/rental-agreements.scss +++ /dev/null @@ -1,60 +0,0 @@ -#rental-agreements-detail { - #rental-agreements-top { - margin-bottom: 10px; - } - - #rental-agreements-top, #rental-agreements-footer { - .btn { - margin-left: 5px; - } - } - - #rental-agreement-header { - min-height: 169px; - } - - #rental-agreements-note { - margin: 10px 0; - } - - #overtime-rates { - .overtime-rate { - margin-right: 20px; - } - } - - .label { - font-size: 100%; - margin-right: 5px; - } - - .no-margin { - margin: 0; - } - - .rental-rates { - position: relative; - - .edit-rate-btn { - position: absolute; - right: 0; - top: 0; - } - } -} - -#rental-agreements-overtime-notes-edit { - #overtime-rate-edit { - padding-bottom: 10px; - border-bottom: 1px solid #e5e5e5; - - .checkbox-control { - display: inline-block; - margin-right: 20px; - } - } - - #note-edit { - margin-top: 20px; - } -} diff --git a/client/src/sass/views/rental-requests.scss b/client/src/sass/views/rental-requests.scss deleted file mode 100644 index 0b5643c11..000000000 --- a/client/src/sass/views/rental-requests.scss +++ /dev/null @@ -1,86 +0,0 @@ -#rental-requests-list { - #add-request-buttons { - margin-left: auto; - - .btn { - display: block; - width: 100%; - } - - .btn:first-child { - margin-bottom: 10px; - } - } -} - -#rental-requests-detail { - #rental-requests-top { - margin-bottom: 10px; - - .btn { - margin-left: 5px; - } - } - - #rental-request-status { - float: left; - min-width: 100px; - padding-top: 7px; - } - - #rotation-list { - width: 100%; - overflow-y: auto; - } - - .request-information { - margin-top: 20px; - } - - .label { - font-size: 100%; - margin-right: 5px; - } - - .btn, .checkbox-control { - margin-left: 20px; - } - - #rotation-list { - .btn-link { - padding: 0; - margin: 0; - } - - th:nth-child(2), td:nth-child(2), th:nth-child(11), td:nth-child(11) { - display: none; - } - - td:nth-child(5) { - width: 250px; - } - - // tr.blank-row {} - - .attachment { - display: inline-block; - } - } -} - -#hire-offer-edit { - input[type='number'] { - width: auto; - min-width: 175px; - } - - .spinner-container { - height: 24px; - } -} - -#confirm-dialog, #hire-offer-edit { - &.modal { - z-index: 1040; - } -} diff --git a/client/src/sass/views/roles.scss b/client/src/sass/views/roles.scss deleted file mode 100644 index c6c739ac3..000000000 --- a/client/src/sass/views/roles.scss +++ /dev/null @@ -1,42 +0,0 @@ -#roles-list { - #roles-filters { - .search-control { - width: 350px; - margin-left: 5px; - } - } - - .alert .btn { - float: right; - } -} - -#roles-detail { - #roles-top { - margin-bottom: 10px; - text-align: right; - } - - #roles-permissions { - table { - font-size: 92%; - - tr { - cursor: pointer; - - &.selected { - background-color: #217AFF; - color: white; - } - } - } - } -} - -#roles-edit { - .container-fluid { - padding-left: 0; - padding-right: 0; - margin-left: -7px; - } -} diff --git a/client/src/sass/views/rollover.scss b/client/src/sass/views/rollover.scss deleted file mode 100644 index c5c763c7e..000000000 --- a/client/src/sass/views/rollover.scss +++ /dev/null @@ -1,13 +0,0 @@ -#roll-over { - .progress { - margin: 10px 0; - } - - #checklist { - margin: 20px 0; - } - - #description { - margin: 20px 0; - } -} diff --git a/client/src/sass/views/users.scss b/client/src/sass/views/users.scss deleted file mode 100644 index 5459c5d62..000000000 --- a/client/src/sass/views/users.scss +++ /dev/null @@ -1,48 +0,0 @@ -#users-detail { - #users-top { - margin-bottom: 10px; - } - - #users-access { - .checkbox-control { - float: right; - font-size: 14px; - } - - input { - margin-top: 0; - } - } - - .well { - margin-left: 5px; - margin-right: 5px; - } - - .label { - font-size: 100%; - margin-right: 5px; - } - - .checkbox { - margin-top: 0; - margin-bottom: 0; - height: 16px; - } - - .col-display-label { - width: 100px; - } - - .alert { - .btn { - float: right; - } - } -} - -#users-role-popover { - .date-control { - margin-right: 10px; - } -} diff --git a/client/test/index.html b/client/test/index.html deleted file mode 100644 index b301c393c..000000000 --- a/client/test/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - -Hired Equipment Tracking System | BC Governemnt - - - - - - - - - - - - - - - - - -
- - - - - - - diff --git a/client/test/spec/load.js b/client/test/spec/load.js deleted file mode 100644 index 976d2077e..000000000 --- a/client/test/spec/load.js +++ /dev/null @@ -1,13 +0,0 @@ -/* global describe, before, it, expect */ - -describe('Initialization', function () { - var frameWindow; - - before(function() { - frameWindow = document.getElementById('app-frame').contentWindow; - }); - - it('should load', function () { - expect(frameWindow.document.getElementById('content-container')).to.be.ok(); - }); -}); diff --git a/client/typings/node/node.d.ts b/client/typings/node/node.d.ts deleted file mode 100644 index 14b577986..000000000 --- a/client/typings/node/node.d.ts +++ /dev/null @@ -1,2161 +0,0 @@ -// Type definitions for Node.js v4.x -// Project: http://nodejs.org/ -// Definitions by: Microsoft TypeScript , DefinitelyTyped -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/************************************************ -* * -* Node.js v4.x API * -* * -************************************************/ - -interface Error { - stack?: string; -} - - -// compat for TypeScript 1.5.3 -// if you use with --target es3 or --target es5 and use below definitions, -// use the lib.es6.d.ts that is bundled with TypeScript 1.5.3. -interface MapConstructor {} -interface WeakMapConstructor {} -interface SetConstructor {} -interface WeakSetConstructor {} - -/************************************************ -* * -* GLOBAL * -* * -************************************************/ -declare var process: NodeJS.Process; -declare var global: NodeJS.Global; - -declare var __filename: string; -declare var __dirname: string; - -declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearTimeout(timeoutId: NodeJS.Timer): void; -declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearInterval(intervalId: NodeJS.Timer): void; -declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; -declare function clearImmediate(immediateId: any): void; - -interface NodeRequireFunction { - (id: string): any; -} - -interface NodeRequire extends NodeRequireFunction { - resolve(id:string): string; - cache: any; - extensions: any; - main: any; -} - -declare var require: NodeRequire; - -interface NodeModule { - exports: any; - require: NodeRequireFunction; - id: string; - filename: string; - loaded: boolean; - parent: any; - children: any[]; -} - -declare var module: NodeModule; - -// Same as module.exports -declare var exports: any; -declare var SlowBuffer: { - new (str: string, encoding?: string): Buffer; - new (size: number): Buffer; - new (size: Uint8Array): Buffer; - new (array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; -}; - - -// Buffer class -interface Buffer extends NodeBuffer {} - -/** - * Raw data is stored in instances of the Buffer class. - * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. - * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - */ -declare var Buffer: { - /** - * Allocates a new buffer containing the given {str}. - * - * @param str String to store in buffer. - * @param encoding encoding to use, optional. Default is 'utf8' - */ - new (str: string, encoding?: string): Buffer; - /** - * Allocates a new buffer of {size} octets. - * - * @param size count of octets to allocate. - */ - new (size: number): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: Uint8Array): Buffer; - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - new (array: any[]): Buffer; - prototype: Buffer; - /** - * Returns true if {obj} is a Buffer - * - * @param obj object to test. - */ - isBuffer(obj: any): obj is Buffer; - /** - * Returns true if {encoding} is a valid encoding argument. - * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - * - * @param encoding string to test. - */ - isEncoding(encoding: string): boolean; - /** - * Gives the actual byte length of a string. encoding defaults to 'utf8'. - * This is not the same as String.prototype.length since that returns the number of characters in a string. - * - * @param string string to test. - * @param encoding encoding used to evaluate (defaults to 'utf8') - */ - byteLength(string: string, encoding?: string): number; - /** - * Returns a buffer which is the result of concatenating all the buffers in the list together. - * - * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. - * If the list has exactly one item, then the first item of the list is returned. - * If the list has more than one item, then a new Buffer is created. - * - * @param list An array of Buffer objects to concatenate - * @param totalLength Total length of the buffers when concatenated. - * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. - */ - concat(list: Buffer[], totalLength?: number): Buffer; - /** - * The same as buf1.compare(buf2). - */ - compare(buf1: Buffer, buf2: Buffer): number; -}; - -/************************************************ -* * -* GLOBAL INTERFACES * -* * -************************************************/ -declare module NodeJS { - export interface ErrnoException extends Error { - errno?: number; - code?: string; - path?: string; - syscall?: string; - stack?: string; - } - - export interface EventEmitter { - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): EventEmitter; - getMaxListeners(): number; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - listenerCount(type: string): number; - } - - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): string|Buffer; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): ReadableStream; - } - - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer|string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface ReadWriteStream extends ReadableStream, WritableStream {} - - export interface Process extends EventEmitter { - stdout: WritableStream; - stderr: WritableStream; - stdin: ReadableStream; - argv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - env: any; - exit(code?: number): void; - getgid(): number; - setgid(id: number): void; - setgid(id: string): void; - getuid(): number; - setuid(id: number): void; - setuid(id: string): void; - version: string; - versions: { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - openssl: string; - }; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid:number, signal?: string|number): void; - pid: number; - title: string; - arch: string; - platform: string; - memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; - nextTick(callback: Function): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?:number[]): number[]; - - // Worker - send?(message: any, sendHandle?: any): void; - } - - export interface Global { - Array: typeof Array; - ArrayBuffer: typeof ArrayBuffer; - Boolean: typeof Boolean; - Buffer: typeof Buffer; - DataView: typeof DataView; - Date: typeof Date; - Error: typeof Error; - EvalError: typeof EvalError; - Float32Array: typeof Float32Array; - Float64Array: typeof Float64Array; - Function: typeof Function; - GLOBAL: Global; - Infinity: typeof Infinity; - Int16Array: typeof Int16Array; - Int32Array: typeof Int32Array; - Int8Array: typeof Int8Array; - Intl: typeof Intl; - JSON: typeof JSON; - Map: MapConstructor; - Math: typeof Math; - NaN: typeof NaN; - Number: typeof Number; - Object: typeof Object; - Promise: Function; - RangeError: typeof RangeError; - ReferenceError: typeof ReferenceError; - RegExp: typeof RegExp; - Set: SetConstructor; - String: typeof String; - Symbol: Function; - SyntaxError: typeof SyntaxError; - TypeError: typeof TypeError; - URIError: typeof URIError; - Uint16Array: typeof Uint16Array; - Uint32Array: typeof Uint32Array; - Uint8Array: typeof Uint8Array; - Uint8ClampedArray: Function; - WeakMap: WeakMapConstructor; - WeakSet: WeakSetConstructor; - clearImmediate: (immediateId: any) => void; - clearInterval: (intervalId: NodeJS.Timer) => void; - clearTimeout: (timeoutId: NodeJS.Timer) => void; - console: typeof console; - decodeURI: typeof decodeURI; - decodeURIComponent: typeof decodeURIComponent; - encodeURI: typeof encodeURI; - encodeURIComponent: typeof encodeURIComponent; - escape: (str: string) => string; - eval: typeof eval; - global: Global; - isFinite: typeof isFinite; - isNaN: typeof isNaN; - parseFloat: typeof parseFloat; - parseInt: typeof parseInt; - process: Process; - root: Global; - setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; - setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; - undefined: typeof undefined; - unescape: (str: string) => string; - gc: () => void; - v8debug?: any; - } - - export interface Timer { - ref() : void; - unref() : void; - } -} - -/** - * @deprecated - */ -interface NodeBuffer { - [index: number]: number; - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): any; - length: number; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAsset?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - writeUInt8(value: number, offset: number, noAssert?: boolean): number; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeInt8(value: number, offset: number, noAssert?: boolean): number; - writeInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeFloatLE(value: number, offset: number, noAssert?: boolean): number; - writeFloatBE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; - fill(value: any, offset?: number, end?: number): Buffer; -} - -/************************************************ -* * -* MODULES * -* * -************************************************/ -declare module "buffer" { - export var INSPECT_MAX_BYTES: number; -} - -declare module "querystring" { - export interface StringifyOptions { - encodeURIComponent?: Function; - } - - export interface ParseOptions { - maxKeys?: number; - decodeURIComponent?: Function; - } - - export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; - export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; - export function escape(str: string): string; - export function unescape(str: string): string; -} - -declare module "events" { - export class EventEmitter implements NodeJS.EventEmitter { - static EventEmitter: EventEmitter; - static listenerCount(emitter: EventEmitter, event: string): number; // deprecated - static defaultMaxListeners: number; - - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): EventEmitter; - getMaxListeners(): number; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - listenerCount(type: string): number; - } -} - -declare module "http" { - import * as events from "events"; - import * as net from "net"; - import * as stream from "stream"; - - export interface RequestOptions { - protocol?: string; - host?: string; - hostname?: string; - family?: number; - port?: number - localAddress?: string; - socketPath?: string; - method?: string; - path?: string; - headers?: { [key: string]: any }; - auth?: string; - agent?: Agent|boolean; - } - - export interface Server extends events.EventEmitter { - listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; - listen(port: number, hostname?: string, callback?: Function): Server; - listen(path: string, callback?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(cb?: any): Server; - address(): { port: number; family: string; address: string; }; - maxHeadersCount: number; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ServerRequest extends IncomingMessage { - connection: net.Socket; - } - export interface ServerResponse extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - writeContinue(): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; - writeHead(statusCode: number, headers?: any): void; - statusCode: number; - statusMessage: string; - setHeader(name: string, value: string): void; - sendDate: boolean; - getHeader(name: string): string; - removeHeader(name: string): void; - write(chunk: any, encoding?: string): any; - addTrailers(headers: any): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientRequest extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - write(chunk: any, encoding?: string): void; - abort(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface IncomingMessage extends events.EventEmitter, stream.Readable { - httpVersion: string; - headers: any; - rawHeaders: string[]; - trailers: any; - rawTrailers: any; - setTimeout(msecs: number, callback: Function): NodeJS.Timer; - /** - * Only valid for request obtained from http.Server. - */ - method?: string; - /** - * Only valid for request obtained from http.Server. - */ - url?: string; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusCode?: number; - /** - * Only valid for response obtained from http.ClientRequest. - */ - statusMessage?: string; - socket: net.Socket; - } - /** - * @deprecated Use IncomingMessage - */ - export interface ClientResponse extends IncomingMessage { } - - export interface AgentOptions { - /** - * Keep sockets around in a pool to be used by other requests in the future. Default = false - */ - keepAlive?: boolean; - /** - * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. - * Only relevant if keepAlive is set to true. - */ - keepAliveMsecs?: number; - /** - * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity - */ - maxSockets?: number; - /** - * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. - */ - maxFreeSockets?: number; - } - - export class Agent { - maxSockets: number; - sockets: any; - requests: any; - - constructor(opts?: AgentOptions); - - /** - * Destroy any sockets that are currently in use by the agent. - * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, - * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, - * sockets may hang open for quite a long time before the server terminates them. - */ - destroy(): void; - } - - export var METHODS: string[]; - - export var STATUS_CODES: { - [errorCode: number]: string; - [errorCode: string]: string; - }; - export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; - export function createClient(port?: number, host?: string): any; - export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; - export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; - export var globalAgent: Agent; -} - -declare module "cluster" { - import * as child from "child_process"; - import * as events from "events"; - - export interface ClusterSettings { - exec?: string; - args?: string[]; - silent?: boolean; - } - - export class Worker extends events.EventEmitter { - id: string; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any): void; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - } - - export var settings: ClusterSettings; - export var isMaster: boolean; - export var isWorker: boolean; - export function setupMaster(settings?: ClusterSettings): void; - export function fork(env?: any): Worker; - export function disconnect(callback?: Function): void; - export var worker: Worker; - export var workers: Worker[]; - - // Event emitter - export function addListener(event: string, listener: Function): void; - export function on(event: string, listener: Function): any; - export function once(event: string, listener: Function): void; - export function removeListener(event: string, listener: Function): void; - export function removeAllListeners(event?: string): void; - export function setMaxListeners(n: number): void; - export function listeners(event: string): Function[]; - export function emit(event: string, ...args: any[]): boolean; -} - -declare module "zlib" { - import * as stream from "stream"; - export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } - - export interface Gzip extends stream.Transform { } - export interface Gunzip extends stream.Transform { } - export interface Deflate extends stream.Transform { } - export interface Inflate extends stream.Transform { } - export interface DeflateRaw extends stream.Transform { } - export interface InflateRaw extends stream.Transform { } - export interface Unzip extends stream.Transform { } - - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; - - export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function deflateSync(buf: Buffer, options?: ZlibOptions): any; - export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gzipSync(buf: Buffer, options?: ZlibOptions): any; - export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; - export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflateSync(buf: Buffer, options?: ZlibOptions): any; - export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; - export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function unzipSync(buf: Buffer, options?: ZlibOptions): any; - - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; - export var Z_NULL: number; -} - -declare module "os" { - export interface CpuInfo { - model: string; - speed: number; - times: { - user: number; - nice: number; - sys: number; - idle: number; - irq: number; - } - } - - export interface NetworkInterfaceInfo { - address: string; - netmask: string; - family: string; - mac: string; - internal: boolean; - } - - export function tmpdir(): string; - export function homedir(): string; - export function endianness(): string; - export function hostname(): string; - export function type(): string; - export function platform(): string; - export function arch(): string; - export function release(): string; - export function uptime(): number; - export function loadavg(): number[]; - export function totalmem(): number; - export function freemem(): number; - export function cpus(): CpuInfo[]; - export function networkInterfaces(): {[index: string]: NetworkInterfaceInfo[]}; - export var EOL: string; -} - -declare module "https" { - import * as tls from "tls"; - import * as events from "events"; - import * as http from "http"; - - export interface ServerOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - crl?: any; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; - SNICallback?: (servername: string) => any; - } - - export interface RequestOptions extends http.RequestOptions{ - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - secureProtocol?: string; - } - - export interface Agent { - maxSockets: number; - sockets: any; - requests: any; - } - export var Agent: { - new (options?: RequestOptions): Agent; - }; - export interface Server extends tls.Server { } - export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; - export var globalAgent: Agent; -} - -declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): number[]; - encode(codePoints: number[]): string; - } - export var version: any; -} - -declare module "repl" { - import * as stream from "stream"; - import * as events from "events"; - - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - } - export function start(options: ReplOptions): events.EventEmitter; -} - -declare module "readline" { - import * as events from "events"; - import * as stream from "stream"; - - export interface Key { - sequence?: string; - name?: string; - ctrl?: boolean; - meta?: boolean; - shift?: boolean; - } - - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: (answer: string) => void): void; - pause(): ReadLine; - resume(): ReadLine; - close(): void; - write(data: string|Buffer, key?: Key): void; - } - - export interface Completer { - (line: string): CompleterResult; - (line: string, callback: (err: any, result: CompleterResult) => void): any; - } - - export interface CompleterResult { - completions: string[]; - line: string; - } - - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - completer?: Completer; - terminal?: boolean; - historySize?: number; - } - - export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; - export function createInterface(options: ReadLineOptions): ReadLine; - - export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; - export function moveCursor(stream: NodeJS.WritableStream, dx: number|string, dy: number|string): void; - export function clearLine(stream: NodeJS.WritableStream, dir: number): void; - export function clearScreenDown(stream: NodeJS.WritableStream): void; -} - -declare module "vm" { - export interface Context { } - export interface Script { - runInThisContext(): void; - runInNewContext(sandbox?: Context): void; - } - export function runInThisContext(code: string, filename?: string): void; - export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; - export function runInContext(code: string, context: Context, filename?: string): void; - export function createContext(initSandbox?: Context): Context; - export function createScript(code: string, filename?: string): Script; -} - -declare module "child_process" { - import * as events from "events"; - import * as stream from "stream"; - - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - pid: number; - kill(signal?: string): void; - send(message: any, sendHandle?: any): void; - disconnect(): void; - unref(): void; - } - - export function spawn(command: string, args?: string[], options?: { - cwd?: string; - stdio?: any; - custom?: any; - env?: any; - detached?: boolean; - }): ChildProcess; - export function exec(command: string, options: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, - callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, args?: string[], - callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, args?: string[], options?: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function fork(modulePath: string, args?: string[], options?: { - cwd?: string; - env?: any; - execPath?: string; - execArgv?: string[]; - silent?: boolean; - uid?: number; - gid?: number; - }): ChildProcess; - export function spawnSync(command: string, args?: string[], options?: { - cwd?: string; - input?: string | Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - encoding?: string; - }): { - pid: number; - output: string[]; - stdout: string | Buffer; - stderr: string | Buffer; - status: number; - signal: string; - error: Error; - }; - export function execSync(command: string, options?: { - cwd?: string; - input?: string|Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - encoding?: string; - }): string | Buffer; - export function execFileSync(command: string, args?: string[], options?: { - cwd?: string; - input?: string|Buffer; - stdio?: any; - env?: any; - uid?: number; - gid?: number; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - encoding?: string; - }): string | Buffer; -} - -declare module "url" { - export interface Url { - href?: string; - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: any; // string | Object - slashes?: boolean; - hash?: string; - path?: string; - } - - export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; - export function format(url: Url): string; - export function resolve(from: string, to: string): string; -} - -declare module "dns" { - export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; - export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; - export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; -} - -declare module "net" { - import * as stream from "stream"; - - export interface Socket extends stream.Duplex { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - connect(port: number, host?: string, connectionListener?: Function): void; - connect(path: string, connectionListener?: Function): void; - bufferSize: number; - setEncoding(encoding?: string): void; - write(data: any, encoding?: string, callback?: Function): void; - destroy(): void; - pause(): void; - resume(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setKeepAlive(enable?: boolean, initialDelay?: number): void; - address(): { port: number; family: string; address: string; }; - unref(): void; - ref(): void; - - remoteAddress: string; - remoteFamily: string; - remotePort: number; - localAddress: string; - localPort: number; - bytesRead: number; - bytesWritten: number; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - - export var Socket: { - new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; - }; - - export interface Server extends Socket { - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - maxConnections: number; - connections: number; - } - export function createServer(connectionListener?: (socket: Socket) =>void ): Server; - export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; - export function connect(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; -} - -declare module "dgram" { - import * as events from "events"; - - interface RemoteInfo { - address: string; - port: number; - size: number; - } - - interface AddressInfo { - address: string; - family: string; - port: number; - } - - export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; - - interface Socket extends events.EventEmitter { - send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; - bind(port: number, address?: string, callback?: () => void): void; - close(): void; - address(): AddressInfo; - setBroadcast(flag: boolean): void; - setMulticastTTL(ttl: number): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - } -} - -declare module "fs" { - import * as stream from "stream"; - import * as events from "events"; - - interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; - } - - interface FSWatcher extends events.EventEmitter { - close(): void; - } - - export interface ReadStream extends stream.Readable { - close(): void; - } - export interface WriteStream extends stream.Writable { - close(): void; - bytesWritten: number; - } - - /** - * Asynchronous rename. - * @param oldPath - * @param newPath - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /** - * Synchronous rename - * @param oldPath - * @param newPath - */ - export function renameSync(oldPath: string, newPath: string): void; - export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncateSync(path: string, len?: number): void; - export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncateSync(fd: number, len?: number): void; - export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chownSync(path: string, uid: number, gid: number): void; - export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchownSync(fd: number, uid: number, gid: number): void; - export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchownSync(path: string, uid: number, gid: number): void; - export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmodSync(path: string, mode: number): void; - export function chmodSync(path: string, mode: string): void; - export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmodSync(fd: number, mode: number): void; - export function fchmodSync(fd: number, mode: string): void; - export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmodSync(path: string, mode: number): void; - export function lchmodSync(path: string, mode: string): void; - export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function statSync(path: string): Stats; - export function lstatSync(path: string): Stats; - export function fstatSync(fd: number): Stats; - export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function linkSync(srcpath: string, dstpath: string): void; - export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; - export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; - export function readlinkSync(path: string): string; - export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; - export function realpathSync(path: string, cache?: { [path: string]: string }): string; - /* - * Asynchronous unlink - deletes the file specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous unlink - deletes the file specified in {path} - * - * @param path - */ - export function unlinkSync(path: string): void; - /* - * Asynchronous rmdir - removes the directory specified in {path} - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous rmdir - removes the directory specified in {path} - * - * @param path - */ - export function rmdirSync(path: string): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: number): void; - /* - * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. - * - * @param path - * @param mode - * @param callback No arguments other than a possible exception are given to the completion callback. - */ - export function mkdirSync(path: string, mode?: string): void; - export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdirSync(path: string): string[]; - export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function closeSync(fd: number): void; - export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function openSync(path: string, flags: string, mode?: number): number; - export function openSync(path: string, flags: string, mode?: string): number; - export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimesSync(path: string, atime: number, mtime: number): void; - export function utimesSync(path: string, atime: Date, mtime: Date): void; - export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimesSync(fd: number, atime: number, mtime: number): void; - export function futimesSync(fd: number, atime: Date, mtime: Date): void; - export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fsyncSync(fd: number): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; - export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; - export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * - * @param fileName - * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. - */ - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param encoding - */ - export function readFileSync(filename: string, encoding: string): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; - /* - * Synchronous readFile - Synchronously reads the entire contents of a file. - * - * @param fileName - * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. - */ - export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; - export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; - export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; - export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; - export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; - export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; - export function exists(path: string, callback?: (exists: boolean) => void): void; - export function existsSync(path: string): boolean; - /** Constant for fs.access(). File is visible to the calling process. */ - export var F_OK: number; - /** Constant for fs.access(). File can be read by the calling process. */ - export var R_OK: number; - /** Constant for fs.access(). File can be written by the calling process. */ - export var W_OK: number; - /** Constant for fs.access(). File can be executed by the calling process. */ - export var X_OK: number; - /** Tests a user's permissions for the file specified by path. */ - export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; - export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; - /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ - export function accessSync(path: string, mode ?: number): void; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - autoClose?: boolean; - }): ReadStream; - export function createWriteStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: number; - mode?: number; - }): WriteStream; -} - -declare module "path" { - - /** - * A parsed path object generated by path.parse() or consumed by path.format(). - */ - export interface ParsedPath { - /** - * The root of the path such as '/' or 'c:\' - */ - root: string; - /** - * The full directory path such as '/home/user/dir' or 'c:\path\dir' - */ - dir: string; - /** - * The file name including extension (if any) such as 'index.html' - */ - base: string; - /** - * The file extension (if any) such as '.html' - */ - ext: string; - /** - * The file name without extension (if any) such as 'index' - */ - name: string; - } - - /** - * Normalize a string path, reducing '..' and '.' parts. - * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. - * - * @param p string path to normalize. - */ - export function normalize(p: string): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: any[]): string; - /** - * Join all arguments together and normalize the resulting path. - * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. - * - * @param paths string paths to join. - */ - export function join(...paths: string[]): string; - /** - * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. - * - * Starting from leftmost {from} paramter, resolves {to} to an absolute path. - * - * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. - * - * @param pathSegments string paths to join. Non-string arguments are ignored. - */ - export function resolve(...pathSegments: any[]): string; - /** - * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. - * - * @param path path to test. - */ - export function isAbsolute(path: string): boolean; - /** - * Solve the relative path from {from} to {to}. - * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. - * - * @param from - * @param to - */ - export function relative(from: string, to: string): string; - /** - * Return the directory name of a path. Similar to the Unix dirname command. - * - * @param p the path to evaluate. - */ - export function dirname(p: string): string; - /** - * Return the last portion of a path. Similar to the Unix basename command. - * Often used to extract the file name from a fully qualified path. - * - * @param p the path to evaluate. - * @param ext optionally, an extension to remove from the result. - */ - export function basename(p: string, ext?: string): string; - /** - * Return the extension of the path, from the last '.' to end of string in the last portion of the path. - * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string - * - * @param p the path to evaluate. - */ - export function extname(p: string): string; - /** - * The platform-specific file separator. '\\' or '/'. - */ - export var sep: string; - /** - * The platform-specific file delimiter. ';' or ':'. - */ - export var delimiter: string; - /** - * Returns an object from a path string - the opposite of format(). - * - * @param pathString path to evaluate. - */ - export function parse(pathString: string): ParsedPath; - /** - * Returns a path string from an object - the opposite of parse(). - * - * @param pathString path to evaluate. - */ - export function format(pathObject: ParsedPath): string; - - export module posix { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } - - export module win32 { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function isAbsolute(p: string): boolean; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; - export var delimiter: string; - export function parse(p: string): ParsedPath; - export function format(pP: ParsedPath): string; - } -} - -declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - detectIncompleteChar(buffer: Buffer): number; - } - export var StringDecoder: { - new (encoding: string): NodeStringDecoder; - }; -} - -declare module "tls" { - import * as crypto from "crypto"; - import * as net from "net"; - import * as stream from "stream"; - - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; - - export interface TlsOptions { - host?: string; - port?: number; - pfx?: any; //string or buffer - key?: any; //string or buffer - passphrase?: string; - cert?: any; - ca?: any; //string or buffer - crl?: any; //string or string array - ciphers?: string; - honorCipherOrder?: any; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; //array or Buffer; - SNICallback?: (servername: string) => any; - } - - export interface ConnectionOptions { - host?: string; - port?: number; - socket?: net.Socket; - pfx?: any; //string | Buffer - key?: any; //string | Buffer - passphrase?: string; - cert?: any; //string | Buffer - ca?: any; //Array of string | Buffer - rejectUnauthorized?: boolean; - NPNProtocols?: any; //Array of string | Buffer - servername?: string; - } - - export interface Server extends net.Server { - // Extended base methods - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - - listen(port: number, host?: string, callback?: Function): Server; - close(): Server; - address(): { port: number; family: string; address: string; }; - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; - maxConnections: number; - connections: number; - } - - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } - - export interface SecurePair { - encrypted: any; - cleartext: any; - } - - export interface SecureContextOptions { - pfx?: any; //string | buffer - key?: any; //string | buffer - passphrase?: string; - cert?: any; // string | buffer - ca?: any; // string | buffer - crl?: any; // string | string[] - ciphers?: string; - honorCipherOrder?: boolean; - } - - export interface SecureContext { - context: any; - } - - export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; - export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; - export function createSecureContext(details: SecureContextOptions): SecureContext; -} - -declare module "crypto" { - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: any; //string | string array - crl: any; //string | string array - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string): Hmac; - export function createHmac(algorithm: string, key: Buffer): Hmac; - interface Hash { - update(data: any, input_encoding?: string): Hash; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - interface Hmac { - update(data: any, input_encoding?: string): Hmac; - digest(encoding: 'buffer'): Buffer; - digest(encoding: string): any; - digest(): Buffer; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - interface Cipher { - update(data: Buffer): Buffer; - update(data: string, input_encoding?: string, output_encoding?: string): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - } - export function createDecipher(algorithm: string, password: any): Decipher; - export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - interface Decipher { - update(data: Buffer): Buffer; - update(data: string, input_encoding?: string, output_encoding?: string): string; - final(): Buffer; - final(output_encoding: string): string; - setAutoPadding(auto_padding: boolean): void; - } - export function createSign(algorithm: string): Signer; - interface Signer extends NodeJS.WritableStream { - update(data: any): void; - sign(private_key: string, output_format: string): string; - } - export function createVerify(algorith: string): Verify; - interface Verify extends NodeJS.WritableStream { - update(data: any): void; - verify(object: string, signature: string, signature_format?: string): boolean; - } - export function createDiffieHellman(prime_length: number): DiffieHellman; - export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; - interface DiffieHellman { - generateKeys(encoding?: string): string; - computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; - getPrime(encoding?: string): string; - getGenerator(encoding: string): string; - getPublicKey(encoding?: string): string; - getPrivateKey(encoding?: string): string; - setPublicKey(public_key: string, encoding?: string): void; - setPrivateKey(public_key: string, encoding?: string): void; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number) : Buffer; - export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string) : Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; -} - -declare module "stream" { - import * as events from "events"; - - export class Stream extends events.EventEmitter { - pipe(destination: T, options?: { end?: boolean; }): T; - } - - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - } - - export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - } - - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - objectMode?: boolean; - } - - export class Writable extends events.EventEmitter implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - } - - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements NodeJS.ReadWriteStream { - writable: boolean; - constructor(opts?: DuplexOptions); - _write(chunk: any, encoding: string, callback: Function): void; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export interface TransformOptions extends ReadableOptions, WritableOptions {} - - // Note: Transform lacks the _read and _write methods of Readable/Writable. - export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { - readable: boolean; - writable: boolean; - constructor(opts?: TransformOptions); - _transform(chunk: any, encoding: string, callback: Function): void; - _flush(callback: Function): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: any): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - write(chunk: any, cb?: Function): boolean; - write(chunk: any, encoding?: string, cb?: Function): boolean; - end(): void; - end(chunk: any, cb?: Function): void; - end(chunk: any, encoding?: string, cb?: Function): void; - } - - export class PassThrough extends Transform {} -} - -declare module "util" { - export interface InspectOptions { - showHidden?: boolean; - depth?: number; - colors?: boolean; - customInspect?: boolean; - } - - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; - export function inspect(object: any, options: InspectOptions): string; - export function isArray(object: any): boolean; - export function isRegExp(object: any): boolean; - export function isDate(object: any): boolean; - export function isError(object: any): boolean; - export function inherits(constructor: any, superConstructor: any): void; - export function debuglog(key:string): (msg:string,...param: any[])=>void; -} - -declare module "assert" { - function internal (value: any, message?: string): void; - module internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; - - constructor(options?: {message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function}); - } - - export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export function deepStrictEqual(actual: any, expected: any, message?: string): void; - export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; - export var throws: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export var doesNotThrow: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export function ifError(value: any): void; - } - - export = internal; -} - -declare module "tty" { - import * as net from "net"; - - export function isatty(fd: number): boolean; - export interface ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - } - export interface WriteStream extends net.Socket { - columns: number; - rows: number; - } -} - -declare module "domain" { - import * as events from "events"; - - export class Domain extends events.EventEmitter { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - - addListener(event: string, listener: Function): Domain; - on(event: string, listener: Function): Domain; - once(event: string, listener: Function): Domain; - removeListener(event: string, listener: Function): Domain; - removeAllListeners(event?: string): Domain; - } - - export function create(): Domain; -} - -declare module "constants" { - export var E2BIG: number; - export var EACCES: number; - export var EADDRINUSE: number; - export var EADDRNOTAVAIL: number; - export var EAFNOSUPPORT: number; - export var EAGAIN: number; - export var EALREADY: number; - export var EBADF: number; - export var EBADMSG: number; - export var EBUSY: number; - export var ECANCELED: number; - export var ECHILD: number; - export var ECONNABORTED: number; - export var ECONNREFUSED: number; - export var ECONNRESET: number; - export var EDEADLK: number; - export var EDESTADDRREQ: number; - export var EDOM: number; - export var EEXIST: number; - export var EFAULT: number; - export var EFBIG: number; - export var EHOSTUNREACH: number; - export var EIDRM: number; - export var EILSEQ: number; - export var EINPROGRESS: number; - export var EINTR: number; - export var EINVAL: number; - export var EIO: number; - export var EISCONN: number; - export var EISDIR: number; - export var ELOOP: number; - export var EMFILE: number; - export var EMLINK: number; - export var EMSGSIZE: number; - export var ENAMETOOLONG: number; - export var ENETDOWN: number; - export var ENETRESET: number; - export var ENETUNREACH: number; - export var ENFILE: number; - export var ENOBUFS: number; - export var ENODATA: number; - export var ENODEV: number; - export var ENOENT: number; - export var ENOEXEC: number; - export var ENOLCK: number; - export var ENOLINK: number; - export var ENOMEM: number; - export var ENOMSG: number; - export var ENOPROTOOPT: number; - export var ENOSPC: number; - export var ENOSR: number; - export var ENOSTR: number; - export var ENOSYS: number; - export var ENOTCONN: number; - export var ENOTDIR: number; - export var ENOTEMPTY: number; - export var ENOTSOCK: number; - export var ENOTSUP: number; - export var ENOTTY: number; - export var ENXIO: number; - export var EOPNOTSUPP: number; - export var EOVERFLOW: number; - export var EPERM: number; - export var EPIPE: number; - export var EPROTO: number; - export var EPROTONOSUPPORT: number; - export var EPROTOTYPE: number; - export var ERANGE: number; - export var EROFS: number; - export var ESPIPE: number; - export var ESRCH: number; - export var ETIME: number; - export var ETIMEDOUT: number; - export var ETXTBSY: number; - export var EWOULDBLOCK: number; - export var EXDEV: number; - export var WSAEINTR: number; - export var WSAEBADF: number; - export var WSAEACCES: number; - export var WSAEFAULT: number; - export var WSAEINVAL: number; - export var WSAEMFILE: number; - export var WSAEWOULDBLOCK: number; - export var WSAEINPROGRESS: number; - export var WSAEALREADY: number; - export var WSAENOTSOCK: number; - export var WSAEDESTADDRREQ: number; - export var WSAEMSGSIZE: number; - export var WSAEPROTOTYPE: number; - export var WSAENOPROTOOPT: number; - export var WSAEPROTONOSUPPORT: number; - export var WSAESOCKTNOSUPPORT: number; - export var WSAEOPNOTSUPP: number; - export var WSAEPFNOSUPPORT: number; - export var WSAEAFNOSUPPORT: number; - export var WSAEADDRINUSE: number; - export var WSAEADDRNOTAVAIL: number; - export var WSAENETDOWN: number; - export var WSAENETUNREACH: number; - export var WSAENETRESET: number; - export var WSAECONNABORTED: number; - export var WSAECONNRESET: number; - export var WSAENOBUFS: number; - export var WSAEISCONN: number; - export var WSAENOTCONN: number; - export var WSAESHUTDOWN: number; - export var WSAETOOMANYREFS: number; - export var WSAETIMEDOUT: number; - export var WSAECONNREFUSED: number; - export var WSAELOOP: number; - export var WSAENAMETOOLONG: number; - export var WSAEHOSTDOWN: number; - export var WSAEHOSTUNREACH: number; - export var WSAENOTEMPTY: number; - export var WSAEPROCLIM: number; - export var WSAEUSERS: number; - export var WSAEDQUOT: number; - export var WSAESTALE: number; - export var WSAEREMOTE: number; - export var WSASYSNOTREADY: number; - export var WSAVERNOTSUPPORTED: number; - export var WSANOTINITIALISED: number; - export var WSAEDISCON: number; - export var WSAENOMORE: number; - export var WSAECANCELLED: number; - export var WSAEINVALIDPROCTABLE: number; - export var WSAEINVALIDPROVIDER: number; - export var WSAEPROVIDERFAILEDINIT: number; - export var WSASYSCALLFAILURE: number; - export var WSASERVICE_NOT_FOUND: number; - export var WSATYPE_NOT_FOUND: number; - export var WSA_E_NO_MORE: number; - export var WSA_E_CANCELLED: number; - export var WSAEREFUSED: number; - export var SIGHUP: number; - export var SIGINT: number; - export var SIGILL: number; - export var SIGABRT: number; - export var SIGFPE: number; - export var SIGKILL: number; - export var SIGSEGV: number; - export var SIGTERM: number; - export var SIGBREAK: number; - export var SIGWINCH: number; - export var SSL_OP_ALL: number; - export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; - export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; - export var SSL_OP_CISCO_ANYCONNECT: number; - export var SSL_OP_COOKIE_EXCHANGE: number; - export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; - export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; - export var SSL_OP_EPHEMERAL_RSA: number; - export var SSL_OP_LEGACY_SERVER_CONNECT: number; - export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; - export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; - export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; - export var SSL_OP_NETSCAPE_CA_DN_BUG: number; - export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; - export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; - export var SSL_OP_NO_COMPRESSION: number; - export var SSL_OP_NO_QUERY_MTU: number; - export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; - export var SSL_OP_NO_SSLv2: number; - export var SSL_OP_NO_SSLv3: number; - export var SSL_OP_NO_TICKET: number; - export var SSL_OP_NO_TLSv1: number; - export var SSL_OP_NO_TLSv1_1: number; - export var SSL_OP_NO_TLSv1_2: number; - export var SSL_OP_PKCS1_CHECK_1: number; - export var SSL_OP_PKCS1_CHECK_2: number; - export var SSL_OP_SINGLE_DH_USE: number; - export var SSL_OP_SINGLE_ECDH_USE: number; - export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; - export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; - export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; - export var SSL_OP_TLS_D5_BUG: number; - export var SSL_OP_TLS_ROLLBACK_BUG: number; - export var ENGINE_METHOD_DSA: number; - export var ENGINE_METHOD_DH: number; - export var ENGINE_METHOD_RAND: number; - export var ENGINE_METHOD_ECDH: number; - export var ENGINE_METHOD_ECDSA: number; - export var ENGINE_METHOD_CIPHERS: number; - export var ENGINE_METHOD_DIGESTS: number; - export var ENGINE_METHOD_STORE: number; - export var ENGINE_METHOD_PKEY_METHS: number; - export var ENGINE_METHOD_PKEY_ASN1_METHS: number; - export var ENGINE_METHOD_ALL: number; - export var ENGINE_METHOD_NONE: number; - export var DH_CHECK_P_NOT_SAFE_PRIME: number; - export var DH_CHECK_P_NOT_PRIME: number; - export var DH_UNABLE_TO_CHECK_GENERATOR: number; - export var DH_NOT_SUITABLE_GENERATOR: number; - export var NPN_ENABLED: number; - export var RSA_PKCS1_PADDING: number; - export var RSA_SSLV23_PADDING: number; - export var RSA_NO_PADDING: number; - export var RSA_PKCS1_OAEP_PADDING: number; - export var RSA_X931_PADDING: number; - export var RSA_PKCS1_PSS_PADDING: number; - export var POINT_CONVERSION_COMPRESSED: number; - export var POINT_CONVERSION_UNCOMPRESSED: number; - export var POINT_CONVERSION_HYBRID: number; - export var O_RDONLY: number; - export var O_WRONLY: number; - export var O_RDWR: number; - export var S_IFMT: number; - export var S_IFREG: number; - export var S_IFDIR: number; - export var S_IFCHR: number; - export var S_IFLNK: number; - export var O_CREAT: number; - export var O_EXCL: number; - export var O_TRUNC: number; - export var O_APPEND: number; - export var F_OK: number; - export var R_OK: number; - export var W_OK: number; - export var X_OK: number; - export var UV_UDP_REUSEADDR: number; -} diff --git a/client/webpack.config.js b/client/webpack.config.js deleted file mode 100644 index 5e5bcab06..000000000 --- a/client/webpack.config.js +++ /dev/null @@ -1,100 +0,0 @@ -/*eslint-env node*/ - -const path = require('path'); -const webpack = require('webpack'); -const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); - -const IS_PRODUCTION = process.env.NODE_ENV === 'production'; - -// Include your SmUserId on the command line. -const DEV_USER = process.env.HETS_DEV_USER || ''; - -var webpackPlugins = [ - new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/), -]; -var eslintDevRule = {}; - -const entrypoints = { - app: [ - '@babel/polyfill', - './src/js/init.js', - ], -}; - -if(!IS_PRODUCTION) { - webpackPlugins.push(new webpack.DefinePlugin({ - 'process.env':{ - 'DEV_USER': JSON.stringify(DEV_USER), - }, - })); - - webpackPlugins.push(new webpack.HotModuleReplacementPlugin()); - entrypoints.app = [ - entrypoints.app[0], - 'react-hot-loader/patch', // has to be after @babel/polyfill - 'webpack-hot-middleware/client', - entrypoints.app[1], - ]; - - eslintDevRule = { - enforce: 'pre', - test: /\.jsx?$/, - loader: 'eslint-loader', - exclude: /node_modules/, - }; -} - - -module.exports = { - mode: IS_PRODUCTION ? 'production' : 'development', - bail: IS_PRODUCTION, - devtool: IS_PRODUCTION ? 'source-map' : 'source-map', - entry: entrypoints, - output: { - path: path.resolve(__dirname, 'dist'), - filename: '[name].js', - chunkFilename: '[name].js', - sourceMapFilename: 'maps/[file].map', - publicPath: '/', - }, - resolve: { - alias: { - 'react-dom': IS_PRODUCTION ? 'react-dom' : '@hot-loader/react-dom', - }, - }, - plugins: webpackPlugins, - module: { - rules: [ - eslintDevRule, - { - test: /\.jsx?$/, - exclude: /node_modules/, - loader: 'babel-loader', - }, - ], - }, - optimization: { - noEmitOnErrors: IS_PRODUCTION, - concatenateModules: true, - splitChunks: { - cacheGroups: { - vendor: { - test: /node_modules/, - chunks: 'initial', - name: 'vendor', - enforce: true, - }, - }, - } , - minimizer: [ - new UglifyJsPlugin({ - sourceMap: true, - }), - ], - }, - performance: { - hints: IS_PRODUCTION ? 'warning' : false, - maxAssetSize: 1 * 1024 * 1024, - maxEntrypointSize: 2 * 1024 * 1024, - }, -}; From c626c29c348f578a2517fb33c790d64181aee318 Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Thu, 3 Jun 2021 15:58:10 -0700 Subject: [PATCH 013/352] renaming client2 to client folder --- {client2 => client}/.dockerignore | 0 {client2 => client}/.gitignore | 0 {client2 => client}/Dockerfile | 0 {client2 => client}/README.md | 0 {client2 => client}/nginx-start/start.sh | 0 {client2 => client}/nginx.conf.tmpl | 0 {client2 => client}/package-lock.json | 0 {client2 => client}/package.json | 0 {client2 => client}/public/favicon.ico | Bin {client2 => client}/public/images/blueline.png | Bin .../public/images/gov/bceid_logo.png | Bin {client2 => client}/public/images/gov/favicon.png | Bin .../public/images/gov/gov3_bc_logo.png | Bin {client2 => client}/public/images/gov/hets.jpg | Bin {client2 => client}/public/images/greyline.png | Bin {client2 => client}/public/index.html | 0 {client2 => client}/public/manifest.json | 0 {client2 => client}/public/robots.txt | 0 {client2 => client}/src/App.test.js | 0 {client2 => client}/src/images/blueline.png | Bin {client2 => client}/src/images/gov/bceid_logo.png | Bin {client2 => client}/src/images/gov/favicon.png | Bin {client2 => client}/src/images/gov/gov3_bc_logo.png | Bin {client2 => client}/src/images/gov/hets.jpg | Bin {client2 => client}/src/images/greyline.png | Bin {client2 => client}/src/index.js | 0 {client2 => client}/src/js/App.jsx | 0 {client2 => client}/src/js/actionTypes.js | 0 {client2 => client}/src/js/actions.js | 0 {client2 => client}/src/js/api.js | 0 {client2 => client}/src/js/components/Authorize.jsx | 0 .../src/js/components/BadgeLabel.jsx | 0 .../src/js/components/CheckboxControl.jsx | 0 .../src/js/components/ColDisplay.jsx | 0 {client2 => client}/src/js/components/Confirm.jsx | 0 {client2 => client}/src/js/components/Countdown.jsx | 0 .../src/js/components/DateControl.jsx | 0 .../src/js/components/DeleteButton.jsx | 0 .../src/js/components/DropdownControl.jsx | 0 .../src/js/components/EditButton.jsx | 0 .../src/js/components/Favourites.jsx | 0 .../src/js/components/FileAttachDialog.jsx | 0 .../src/js/components/FilePicker.jsx | 0 .../src/js/components/FileUpload.jsx | 0 .../src/js/components/FilterDropdown.jsx | 0 {client2 => client}/src/js/components/Form.jsx | 0 .../src/js/components/FormDialog.jsx | 0 .../src/js/components/FormInputControl.jsx | 0 {client2 => client}/src/js/components/History.jsx | 0 .../src/js/components/LinkControl.jsx | 0 {client2 => client}/src/js/components/Mailto.jsx | 0 .../src/js/components/ModalDialog.jsx | 0 .../src/js/components/MultiDropdown.jsx | 0 .../src/js/components/OverlayTrigger.jsx | 0 .../src/js/components/PageOrientation.jsx | 0 .../src/js/components/PrintButton.jsx | 0 .../src/js/components/ReturnButton.jsx | 0 .../src/js/components/RootCloseMenu.jsx | 0 .../src/js/components/SearchControl.jsx | 0 {client2 => client}/src/js/components/SortTable.jsx | 0 {client2 => client}/src/js/components/Spinner.jsx | 0 .../src/js/components/StatusDropdown.jsx | 0 .../src/js/components/TableControl.jsx | 0 .../src/js/components/TooltipButton.jsx | 0 .../src/js/components/Unimplemented.jsx | 0 {client2 => client}/src/js/components/Watermark.jsx | 0 .../src/js/components/ui/AddButtonContainer.jsx | 0 .../src/js/components/ui/PageHeader.jsx | 0 .../src/js/components/ui/SearchBar.jsx | 0 .../src/js/components/ui/SubHeader.jsx | 0 {client2 => client}/src/js/constants.js | 0 {client2 => client}/src/js/history.js | 0 {client2 => client}/src/js/init.js | 0 {client2 => client}/src/js/reducers/all.js | 0 {client2 => client}/src/js/reducers/lookups.js | 0 {client2 => client}/src/js/reducers/models.js | 0 {client2 => client}/src/js/reducers/search.js | 0 {client2 => client}/src/js/reducers/ui.js | 0 {client2 => client}/src/js/reducers/user.js | 0 {client2 => client}/src/js/reducers/version.js | 0 .../src/js/selectors/history-selectors.js | 0 .../src/js/selectors/ui-selectors.js | 0 {client2 => client}/src/js/store.js | 0 {client2 => client}/src/js/utils/array.js | 0 {client2 => client}/src/js/utils/date.js | 0 {client2 => client}/src/js/utils/http.js | 0 {client2 => client}/src/js/utils/routes.js | 0 {client2 => client}/src/js/utils/string.js | 0 {client2 => client}/src/js/utils/string_test.js | 0 {client2 => client}/src/js/views/404.jsx | 0 {client2 => client}/src/js/views/AitReport.jsx | 0 {client2 => client}/src/js/views/BusinessOwner.jsx | 0 {client2 => client}/src/js/views/BusinessPortal.jsx | 0 {client2 => client}/src/js/views/DistrictAdmin.jsx | 0 {client2 => client}/src/js/views/Equipment.jsx | 0 .../src/js/views/EquipmentDetail.jsx | 0 {client2 => client}/src/js/views/EquipmentTable.jsx | 0 {client2 => client}/src/js/views/Footer.jsx | 0 {client2 => client}/src/js/views/HiringReport.jsx | 0 {client2 => client}/src/js/views/Home.jsx | 0 {client2 => client}/src/js/views/Main.jsx | 0 {client2 => client}/src/js/views/OvertimeRates.jsx | 0 {client2 => client}/src/js/views/Owners.jsx | 0 {client2 => client}/src/js/views/OwnersDetail.jsx | 0 {client2 => client}/src/js/views/Projects.jsx | 0 {client2 => client}/src/js/views/ProjectsDetail.jsx | 0 .../src/js/views/RentalAgreementsDetail.jsx | 0 {client2 => client}/src/js/views/RentalRequests.jsx | 0 .../src/js/views/RentalRequestsDetail.jsx | 0 {client2 => client}/src/js/views/Roles.jsx | 0 {client2 => client}/src/js/views/RolesDetail.jsx | 0 {client2 => client}/src/js/views/Rollover.jsx | 0 {client2 => client}/src/js/views/SeniorityList.jsx | 0 {client2 => client}/src/js/views/StatusLetters.jsx | 0 {client2 => client}/src/js/views/TimeEntry.jsx | 0 {client2 => client}/src/js/views/TopNav.jsx | 0 {client2 => client}/src/js/views/Users.jsx | 0 {client2 => client}/src/js/views/UsersDetail.jsx | 0 {client2 => client}/src/js/views/Version.jsx | 0 {client2 => client}/src/js/views/WcbCglCoverage.jsx | 0 .../src/js/views/dialogs/AttachmentAddDialog.jsx | 0 .../src/js/views/dialogs/AttachmentEditDialog.jsx | 0 .../src/js/views/dialogs/CloneDialog.jsx | 0 .../src/js/views/dialogs/ConditionAddEditDialog.jsx | 0 .../src/js/views/dialogs/ConfirmDialog.jsx | 0 .../src/js/views/dialogs/ConfirmForceHireDialog.jsx | 0 .../src/js/views/dialogs/ContactsEditDialog.jsx | 0 .../src/js/views/dialogs/DistrictEditDialog.jsx | 0 .../dialogs/DistrictEquipmentTypeAddEditDialog.jsx | 0 .../src/js/views/dialogs/DocumentsListDialog.jsx | 0 .../src/js/views/dialogs/EquipmentAddDialog.jsx | 0 .../views/dialogs/EquipmentChangeStatusDialog.jsx | 0 .../src/js/views/dialogs/EquipmentEditDialog.jsx | 0 .../dialogs/EquipmentRentalRatesEditDialog.jsx | 0 .../js/views/dialogs/EquipmentTransferDialog.jsx | 0 .../src/js/views/dialogs/ErrorDialog.jsx | 0 .../src/js/views/dialogs/HireOfferEditDialog.jsx | 0 .../src/js/views/dialogs/NotesAddDialog.jsx | 0 .../src/js/views/dialogs/NotesDialog.jsx | 0 .../src/js/views/dialogs/OvertimeRateEditDialog.jsx | 0 .../js/views/dialogs/OwnerChangeStatusDialog.jsx | 0 .../src/js/views/dialogs/OwnersAddDialog.jsx | 0 .../src/js/views/dialogs/OwnersEditDialog.jsx | 0 .../src/js/views/dialogs/OwnersPolicyEditDialog.jsx | 0 .../src/js/views/dialogs/ProjectsAddDialog.jsx | 0 .../src/js/views/dialogs/ProjectsEditDialog.jsx | 0 .../dialogs/RentalAgreementOvertimeNotesDialog.jsx | 0 .../js/views/dialogs/RentalAgreementsEditDialog.jsx | 0 .../js/views/dialogs/RentalConditionsEditDialog.jsx | 0 .../src/js/views/dialogs/RentalRatesEditDialog.jsx | 0 .../js/views/dialogs/RentalRequestsAddDialog.jsx | 0 .../js/views/dialogs/RentalRequestsEditDialog.jsx | 0 .../src/js/views/dialogs/SeniorityEditDialog.jsx | 0 .../src/js/views/dialogs/TimeEntryDialog.jsx | 0 .../src/js/views/dialogs/UserRoleAddDialog.jsx | 0 .../src/js/views/dialogs/UsersEditDialog.jsx | 0 {client2 => client}/src/logo.svg | 0 {client2 => client}/src/reportWebVitals.js | 0 {client2 => client}/src/sass/components/all.scss | 0 .../src/sass/components/badge-label.scss | 0 .../src/sass/components/clone-dialog.scss | 0 .../src/sass/components/date-control.scss | 0 .../src/sass/components/dropdown-control.scss | 0 .../src/sass/components/favourites.scss | 0 .../src/sass/components/file-upload.scss | 0 .../src/sass/components/filter-dropdown.scss | 0 .../src/sass/components/form-dialog.scss | 0 .../src/sass/components/form-input-control.scss | 0 .../src/sass/components/history.scss | 0 .../src/sass/components/link-control.scss | 0 .../src/sass/components/multi-dropdown.scss | 0 .../src/sass/components/print-button.scss | 0 .../src/sass/components/return-button.scss | 0 .../src/sass/components/search-control.scss | 0 .../src/sass/components/sort-table.scss | 0 .../sass/components/ui/add-button-container.scss | 0 .../src/sass/components/ui/page-header.scss | 0 .../src/sass/components/ui/search-bar.scss | 0 .../src/sass/components/ui/subheader.scss | 0 {client2 => client}/src/sass/gov3.scss | 0 {client2 => client}/src/sass/header.scss | 0 {client2 => client}/src/sass/init.scss | 0 {client2 => client}/src/sass/main.scss | 0 {client2 => client}/src/sass/mixins.scss | 0 {client2 => client}/src/sass/print.scss | 0 {client2 => client}/src/sass/variables.scss | 0 {client2 => client}/src/sass/views/all.scss | 0 .../src/sass/views/business-portal.scss | 0 {client2 => client}/src/sass/views/dialogs/all.scss | 0 .../src/sass/views/dialogs/contacts-edit.scss | 0 .../src/sass/views/dialogs/documents-list.scss | 0 .../src/sass/views/dialogs/equipment-transfer.scss | 0 .../src/sass/views/dialogs/error-dialog.scss | 0 .../src/sass/views/dialogs/notes.scss | 0 .../src/sass/views/dialogs/rental-rates-edit.scss | 0 .../src/sass/views/district-admin.scss | 0 .../src/sass/views/equipment-list.scss | 0 {client2 => client}/src/sass/views/home.scss | 0 {client2 => client}/src/sass/views/owners.scss | 0 {client2 => client}/src/sass/views/projects.scss | 0 .../src/sass/views/rental-agreements.scss | 0 .../src/sass/views/rental-requests.scss | 0 {client2 => client}/src/sass/views/roles.scss | 0 {client2 => client}/src/sass/views/rollover.scss | 0 {client2 => client}/src/sass/views/users.scss | 0 {client2 => client}/src/setupProxy.js | 0 {client2 => client}/src/setupTests.js | 0 207 files changed, 0 insertions(+), 0 deletions(-) rename {client2 => client}/.dockerignore (100%) rename {client2 => client}/.gitignore (100%) rename {client2 => client}/Dockerfile (100%) rename {client2 => client}/README.md (100%) rename {client2 => client}/nginx-start/start.sh (100%) rename {client2 => client}/nginx.conf.tmpl (100%) rename {client2 => client}/package-lock.json (100%) rename {client2 => client}/package.json (100%) rename {client2 => client}/public/favicon.ico (100%) rename {client2 => client}/public/images/blueline.png (100%) rename {client2 => client}/public/images/gov/bceid_logo.png (100%) rename {client2 => client}/public/images/gov/favicon.png (100%) rename {client2 => client}/public/images/gov/gov3_bc_logo.png (100%) rename {client2 => client}/public/images/gov/hets.jpg (100%) rename {client2 => client}/public/images/greyline.png (100%) rename {client2 => client}/public/index.html (100%) rename {client2 => client}/public/manifest.json (100%) rename {client2 => client}/public/robots.txt (100%) rename {client2 => client}/src/App.test.js (100%) rename {client2 => client}/src/images/blueline.png (100%) rename {client2 => client}/src/images/gov/bceid_logo.png (100%) rename {client2 => client}/src/images/gov/favicon.png (100%) rename {client2 => client}/src/images/gov/gov3_bc_logo.png (100%) rename {client2 => client}/src/images/gov/hets.jpg (100%) rename {client2 => client}/src/images/greyline.png (100%) rename {client2 => client}/src/index.js (100%) rename {client2 => client}/src/js/App.jsx (100%) rename {client2 => client}/src/js/actionTypes.js (100%) rename {client2 => client}/src/js/actions.js (100%) rename {client2 => client}/src/js/api.js (100%) rename {client2 => client}/src/js/components/Authorize.jsx (100%) rename {client2 => client}/src/js/components/BadgeLabel.jsx (100%) rename {client2 => client}/src/js/components/CheckboxControl.jsx (100%) rename {client2 => client}/src/js/components/ColDisplay.jsx (100%) rename {client2 => client}/src/js/components/Confirm.jsx (100%) rename {client2 => client}/src/js/components/Countdown.jsx (100%) rename {client2 => client}/src/js/components/DateControl.jsx (100%) rename {client2 => client}/src/js/components/DeleteButton.jsx (100%) rename {client2 => client}/src/js/components/DropdownControl.jsx (100%) rename {client2 => client}/src/js/components/EditButton.jsx (100%) rename {client2 => client}/src/js/components/Favourites.jsx (100%) rename {client2 => client}/src/js/components/FileAttachDialog.jsx (100%) rename {client2 => client}/src/js/components/FilePicker.jsx (100%) rename {client2 => client}/src/js/components/FileUpload.jsx (100%) rename {client2 => client}/src/js/components/FilterDropdown.jsx (100%) rename {client2 => client}/src/js/components/Form.jsx (100%) rename {client2 => client}/src/js/components/FormDialog.jsx (100%) rename {client2 => client}/src/js/components/FormInputControl.jsx (100%) rename {client2 => client}/src/js/components/History.jsx (100%) rename {client2 => client}/src/js/components/LinkControl.jsx (100%) rename {client2 => client}/src/js/components/Mailto.jsx (100%) rename {client2 => client}/src/js/components/ModalDialog.jsx (100%) rename {client2 => client}/src/js/components/MultiDropdown.jsx (100%) rename {client2 => client}/src/js/components/OverlayTrigger.jsx (100%) rename {client2 => client}/src/js/components/PageOrientation.jsx (100%) rename {client2 => client}/src/js/components/PrintButton.jsx (100%) rename {client2 => client}/src/js/components/ReturnButton.jsx (100%) rename {client2 => client}/src/js/components/RootCloseMenu.jsx (100%) rename {client2 => client}/src/js/components/SearchControl.jsx (100%) rename {client2 => client}/src/js/components/SortTable.jsx (100%) rename {client2 => client}/src/js/components/Spinner.jsx (100%) rename {client2 => client}/src/js/components/StatusDropdown.jsx (100%) rename {client2 => client}/src/js/components/TableControl.jsx (100%) rename {client2 => client}/src/js/components/TooltipButton.jsx (100%) rename {client2 => client}/src/js/components/Unimplemented.jsx (100%) rename {client2 => client}/src/js/components/Watermark.jsx (100%) rename {client2 => client}/src/js/components/ui/AddButtonContainer.jsx (100%) rename {client2 => client}/src/js/components/ui/PageHeader.jsx (100%) rename {client2 => client}/src/js/components/ui/SearchBar.jsx (100%) rename {client2 => client}/src/js/components/ui/SubHeader.jsx (100%) rename {client2 => client}/src/js/constants.js (100%) rename {client2 => client}/src/js/history.js (100%) rename {client2 => client}/src/js/init.js (100%) rename {client2 => client}/src/js/reducers/all.js (100%) rename {client2 => client}/src/js/reducers/lookups.js (100%) rename {client2 => client}/src/js/reducers/models.js (100%) rename {client2 => client}/src/js/reducers/search.js (100%) rename {client2 => client}/src/js/reducers/ui.js (100%) rename {client2 => client}/src/js/reducers/user.js (100%) rename {client2 => client}/src/js/reducers/version.js (100%) rename {client2 => client}/src/js/selectors/history-selectors.js (100%) rename {client2 => client}/src/js/selectors/ui-selectors.js (100%) rename {client2 => client}/src/js/store.js (100%) rename {client2 => client}/src/js/utils/array.js (100%) rename {client2 => client}/src/js/utils/date.js (100%) rename {client2 => client}/src/js/utils/http.js (100%) rename {client2 => client}/src/js/utils/routes.js (100%) rename {client2 => client}/src/js/utils/string.js (100%) rename {client2 => client}/src/js/utils/string_test.js (100%) rename {client2 => client}/src/js/views/404.jsx (100%) rename {client2 => client}/src/js/views/AitReport.jsx (100%) rename {client2 => client}/src/js/views/BusinessOwner.jsx (100%) rename {client2 => client}/src/js/views/BusinessPortal.jsx (100%) rename {client2 => client}/src/js/views/DistrictAdmin.jsx (100%) rename {client2 => client}/src/js/views/Equipment.jsx (100%) rename {client2 => client}/src/js/views/EquipmentDetail.jsx (100%) rename {client2 => client}/src/js/views/EquipmentTable.jsx (100%) rename {client2 => client}/src/js/views/Footer.jsx (100%) rename {client2 => client}/src/js/views/HiringReport.jsx (100%) rename {client2 => client}/src/js/views/Home.jsx (100%) rename {client2 => client}/src/js/views/Main.jsx (100%) rename {client2 => client}/src/js/views/OvertimeRates.jsx (100%) rename {client2 => client}/src/js/views/Owners.jsx (100%) rename {client2 => client}/src/js/views/OwnersDetail.jsx (100%) rename {client2 => client}/src/js/views/Projects.jsx (100%) rename {client2 => client}/src/js/views/ProjectsDetail.jsx (100%) rename {client2 => client}/src/js/views/RentalAgreementsDetail.jsx (100%) rename {client2 => client}/src/js/views/RentalRequests.jsx (100%) rename {client2 => client}/src/js/views/RentalRequestsDetail.jsx (100%) rename {client2 => client}/src/js/views/Roles.jsx (100%) rename {client2 => client}/src/js/views/RolesDetail.jsx (100%) rename {client2 => client}/src/js/views/Rollover.jsx (100%) rename {client2 => client}/src/js/views/SeniorityList.jsx (100%) rename {client2 => client}/src/js/views/StatusLetters.jsx (100%) rename {client2 => client}/src/js/views/TimeEntry.jsx (100%) rename {client2 => client}/src/js/views/TopNav.jsx (100%) rename {client2 => client}/src/js/views/Users.jsx (100%) rename {client2 => client}/src/js/views/UsersDetail.jsx (100%) rename {client2 => client}/src/js/views/Version.jsx (100%) rename {client2 => client}/src/js/views/WcbCglCoverage.jsx (100%) rename {client2 => client}/src/js/views/dialogs/AttachmentAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/AttachmentEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/CloneDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ConditionAddEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ConfirmDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ConfirmForceHireDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ContactsEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/DistrictEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/DocumentsListDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/EquipmentAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/EquipmentEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/EquipmentTransferDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ErrorDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/HireOfferEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/NotesAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/NotesDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/OvertimeRateEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/OwnerChangeStatusDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/OwnersAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/OwnersEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/OwnersPolicyEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ProjectsAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/ProjectsEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalAgreementsEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalConditionsEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalRatesEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalRequestsAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/RentalRequestsEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/SeniorityEditDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/TimeEntryDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/UserRoleAddDialog.jsx (100%) rename {client2 => client}/src/js/views/dialogs/UsersEditDialog.jsx (100%) rename {client2 => client}/src/logo.svg (100%) rename {client2 => client}/src/reportWebVitals.js (100%) rename {client2 => client}/src/sass/components/all.scss (100%) rename {client2 => client}/src/sass/components/badge-label.scss (100%) rename {client2 => client}/src/sass/components/clone-dialog.scss (100%) rename {client2 => client}/src/sass/components/date-control.scss (100%) rename {client2 => client}/src/sass/components/dropdown-control.scss (100%) rename {client2 => client}/src/sass/components/favourites.scss (100%) rename {client2 => client}/src/sass/components/file-upload.scss (100%) rename {client2 => client}/src/sass/components/filter-dropdown.scss (100%) rename {client2 => client}/src/sass/components/form-dialog.scss (100%) rename {client2 => client}/src/sass/components/form-input-control.scss (100%) rename {client2 => client}/src/sass/components/history.scss (100%) rename {client2 => client}/src/sass/components/link-control.scss (100%) rename {client2 => client}/src/sass/components/multi-dropdown.scss (100%) rename {client2 => client}/src/sass/components/print-button.scss (100%) rename {client2 => client}/src/sass/components/return-button.scss (100%) rename {client2 => client}/src/sass/components/search-control.scss (100%) rename {client2 => client}/src/sass/components/sort-table.scss (100%) rename {client2 => client}/src/sass/components/ui/add-button-container.scss (100%) rename {client2 => client}/src/sass/components/ui/page-header.scss (100%) rename {client2 => client}/src/sass/components/ui/search-bar.scss (100%) rename {client2 => client}/src/sass/components/ui/subheader.scss (100%) rename {client2 => client}/src/sass/gov3.scss (100%) rename {client2 => client}/src/sass/header.scss (100%) rename {client2 => client}/src/sass/init.scss (100%) rename {client2 => client}/src/sass/main.scss (100%) rename {client2 => client}/src/sass/mixins.scss (100%) rename {client2 => client}/src/sass/print.scss (100%) rename {client2 => client}/src/sass/variables.scss (100%) rename {client2 => client}/src/sass/views/all.scss (100%) rename {client2 => client}/src/sass/views/business-portal.scss (100%) rename {client2 => client}/src/sass/views/dialogs/all.scss (100%) rename {client2 => client}/src/sass/views/dialogs/contacts-edit.scss (100%) rename {client2 => client}/src/sass/views/dialogs/documents-list.scss (100%) rename {client2 => client}/src/sass/views/dialogs/equipment-transfer.scss (100%) rename {client2 => client}/src/sass/views/dialogs/error-dialog.scss (100%) rename {client2 => client}/src/sass/views/dialogs/notes.scss (100%) rename {client2 => client}/src/sass/views/dialogs/rental-rates-edit.scss (100%) rename {client2 => client}/src/sass/views/district-admin.scss (100%) rename {client2 => client}/src/sass/views/equipment-list.scss (100%) rename {client2 => client}/src/sass/views/home.scss (100%) rename {client2 => client}/src/sass/views/owners.scss (100%) rename {client2 => client}/src/sass/views/projects.scss (100%) rename {client2 => client}/src/sass/views/rental-agreements.scss (100%) rename {client2 => client}/src/sass/views/rental-requests.scss (100%) rename {client2 => client}/src/sass/views/roles.scss (100%) rename {client2 => client}/src/sass/views/rollover.scss (100%) rename {client2 => client}/src/sass/views/users.scss (100%) rename {client2 => client}/src/setupProxy.js (100%) rename {client2 => client}/src/setupTests.js (100%) diff --git a/client2/.dockerignore b/client/.dockerignore similarity index 100% rename from client2/.dockerignore rename to client/.dockerignore diff --git a/client2/.gitignore b/client/.gitignore similarity index 100% rename from client2/.gitignore rename to client/.gitignore diff --git a/client2/Dockerfile b/client/Dockerfile similarity index 100% rename from client2/Dockerfile rename to client/Dockerfile diff --git a/client2/README.md b/client/README.md similarity index 100% rename from client2/README.md rename to client/README.md diff --git a/client2/nginx-start/start.sh b/client/nginx-start/start.sh similarity index 100% rename from client2/nginx-start/start.sh rename to client/nginx-start/start.sh diff --git a/client2/nginx.conf.tmpl b/client/nginx.conf.tmpl similarity index 100% rename from client2/nginx.conf.tmpl rename to client/nginx.conf.tmpl diff --git a/client2/package-lock.json b/client/package-lock.json similarity index 100% rename from client2/package-lock.json rename to client/package-lock.json diff --git a/client2/package.json b/client/package.json similarity index 100% rename from client2/package.json rename to client/package.json diff --git a/client2/public/favicon.ico b/client/public/favicon.ico similarity index 100% rename from client2/public/favicon.ico rename to client/public/favicon.ico diff --git a/client2/public/images/blueline.png b/client/public/images/blueline.png similarity index 100% rename from client2/public/images/blueline.png rename to client/public/images/blueline.png diff --git a/client2/public/images/gov/bceid_logo.png b/client/public/images/gov/bceid_logo.png similarity index 100% rename from client2/public/images/gov/bceid_logo.png rename to client/public/images/gov/bceid_logo.png diff --git a/client2/public/images/gov/favicon.png b/client/public/images/gov/favicon.png similarity index 100% rename from client2/public/images/gov/favicon.png rename to client/public/images/gov/favicon.png diff --git a/client2/public/images/gov/gov3_bc_logo.png b/client/public/images/gov/gov3_bc_logo.png similarity index 100% rename from client2/public/images/gov/gov3_bc_logo.png rename to client/public/images/gov/gov3_bc_logo.png diff --git a/client2/public/images/gov/hets.jpg b/client/public/images/gov/hets.jpg similarity index 100% rename from client2/public/images/gov/hets.jpg rename to client/public/images/gov/hets.jpg diff --git a/client2/public/images/greyline.png b/client/public/images/greyline.png similarity index 100% rename from client2/public/images/greyline.png rename to client/public/images/greyline.png diff --git a/client2/public/index.html b/client/public/index.html similarity index 100% rename from client2/public/index.html rename to client/public/index.html diff --git a/client2/public/manifest.json b/client/public/manifest.json similarity index 100% rename from client2/public/manifest.json rename to client/public/manifest.json diff --git a/client2/public/robots.txt b/client/public/robots.txt similarity index 100% rename from client2/public/robots.txt rename to client/public/robots.txt diff --git a/client2/src/App.test.js b/client/src/App.test.js similarity index 100% rename from client2/src/App.test.js rename to client/src/App.test.js diff --git a/client2/src/images/blueline.png b/client/src/images/blueline.png similarity index 100% rename from client2/src/images/blueline.png rename to client/src/images/blueline.png diff --git a/client2/src/images/gov/bceid_logo.png b/client/src/images/gov/bceid_logo.png similarity index 100% rename from client2/src/images/gov/bceid_logo.png rename to client/src/images/gov/bceid_logo.png diff --git a/client2/src/images/gov/favicon.png b/client/src/images/gov/favicon.png similarity index 100% rename from client2/src/images/gov/favicon.png rename to client/src/images/gov/favicon.png diff --git a/client2/src/images/gov/gov3_bc_logo.png b/client/src/images/gov/gov3_bc_logo.png similarity index 100% rename from client2/src/images/gov/gov3_bc_logo.png rename to client/src/images/gov/gov3_bc_logo.png diff --git a/client2/src/images/gov/hets.jpg b/client/src/images/gov/hets.jpg similarity index 100% rename from client2/src/images/gov/hets.jpg rename to client/src/images/gov/hets.jpg diff --git a/client2/src/images/greyline.png b/client/src/images/greyline.png similarity index 100% rename from client2/src/images/greyline.png rename to client/src/images/greyline.png diff --git a/client2/src/index.js b/client/src/index.js similarity index 100% rename from client2/src/index.js rename to client/src/index.js diff --git a/client2/src/js/App.jsx b/client/src/js/App.jsx similarity index 100% rename from client2/src/js/App.jsx rename to client/src/js/App.jsx diff --git a/client2/src/js/actionTypes.js b/client/src/js/actionTypes.js similarity index 100% rename from client2/src/js/actionTypes.js rename to client/src/js/actionTypes.js diff --git a/client2/src/js/actions.js b/client/src/js/actions.js similarity index 100% rename from client2/src/js/actions.js rename to client/src/js/actions.js diff --git a/client2/src/js/api.js b/client/src/js/api.js similarity index 100% rename from client2/src/js/api.js rename to client/src/js/api.js diff --git a/client2/src/js/components/Authorize.jsx b/client/src/js/components/Authorize.jsx similarity index 100% rename from client2/src/js/components/Authorize.jsx rename to client/src/js/components/Authorize.jsx diff --git a/client2/src/js/components/BadgeLabel.jsx b/client/src/js/components/BadgeLabel.jsx similarity index 100% rename from client2/src/js/components/BadgeLabel.jsx rename to client/src/js/components/BadgeLabel.jsx diff --git a/client2/src/js/components/CheckboxControl.jsx b/client/src/js/components/CheckboxControl.jsx similarity index 100% rename from client2/src/js/components/CheckboxControl.jsx rename to client/src/js/components/CheckboxControl.jsx diff --git a/client2/src/js/components/ColDisplay.jsx b/client/src/js/components/ColDisplay.jsx similarity index 100% rename from client2/src/js/components/ColDisplay.jsx rename to client/src/js/components/ColDisplay.jsx diff --git a/client2/src/js/components/Confirm.jsx b/client/src/js/components/Confirm.jsx similarity index 100% rename from client2/src/js/components/Confirm.jsx rename to client/src/js/components/Confirm.jsx diff --git a/client2/src/js/components/Countdown.jsx b/client/src/js/components/Countdown.jsx similarity index 100% rename from client2/src/js/components/Countdown.jsx rename to client/src/js/components/Countdown.jsx diff --git a/client2/src/js/components/DateControl.jsx b/client/src/js/components/DateControl.jsx similarity index 100% rename from client2/src/js/components/DateControl.jsx rename to client/src/js/components/DateControl.jsx diff --git a/client2/src/js/components/DeleteButton.jsx b/client/src/js/components/DeleteButton.jsx similarity index 100% rename from client2/src/js/components/DeleteButton.jsx rename to client/src/js/components/DeleteButton.jsx diff --git a/client2/src/js/components/DropdownControl.jsx b/client/src/js/components/DropdownControl.jsx similarity index 100% rename from client2/src/js/components/DropdownControl.jsx rename to client/src/js/components/DropdownControl.jsx diff --git a/client2/src/js/components/EditButton.jsx b/client/src/js/components/EditButton.jsx similarity index 100% rename from client2/src/js/components/EditButton.jsx rename to client/src/js/components/EditButton.jsx diff --git a/client2/src/js/components/Favourites.jsx b/client/src/js/components/Favourites.jsx similarity index 100% rename from client2/src/js/components/Favourites.jsx rename to client/src/js/components/Favourites.jsx diff --git a/client2/src/js/components/FileAttachDialog.jsx b/client/src/js/components/FileAttachDialog.jsx similarity index 100% rename from client2/src/js/components/FileAttachDialog.jsx rename to client/src/js/components/FileAttachDialog.jsx diff --git a/client2/src/js/components/FilePicker.jsx b/client/src/js/components/FilePicker.jsx similarity index 100% rename from client2/src/js/components/FilePicker.jsx rename to client/src/js/components/FilePicker.jsx diff --git a/client2/src/js/components/FileUpload.jsx b/client/src/js/components/FileUpload.jsx similarity index 100% rename from client2/src/js/components/FileUpload.jsx rename to client/src/js/components/FileUpload.jsx diff --git a/client2/src/js/components/FilterDropdown.jsx b/client/src/js/components/FilterDropdown.jsx similarity index 100% rename from client2/src/js/components/FilterDropdown.jsx rename to client/src/js/components/FilterDropdown.jsx diff --git a/client2/src/js/components/Form.jsx b/client/src/js/components/Form.jsx similarity index 100% rename from client2/src/js/components/Form.jsx rename to client/src/js/components/Form.jsx diff --git a/client2/src/js/components/FormDialog.jsx b/client/src/js/components/FormDialog.jsx similarity index 100% rename from client2/src/js/components/FormDialog.jsx rename to client/src/js/components/FormDialog.jsx diff --git a/client2/src/js/components/FormInputControl.jsx b/client/src/js/components/FormInputControl.jsx similarity index 100% rename from client2/src/js/components/FormInputControl.jsx rename to client/src/js/components/FormInputControl.jsx diff --git a/client2/src/js/components/History.jsx b/client/src/js/components/History.jsx similarity index 100% rename from client2/src/js/components/History.jsx rename to client/src/js/components/History.jsx diff --git a/client2/src/js/components/LinkControl.jsx b/client/src/js/components/LinkControl.jsx similarity index 100% rename from client2/src/js/components/LinkControl.jsx rename to client/src/js/components/LinkControl.jsx diff --git a/client2/src/js/components/Mailto.jsx b/client/src/js/components/Mailto.jsx similarity index 100% rename from client2/src/js/components/Mailto.jsx rename to client/src/js/components/Mailto.jsx diff --git a/client2/src/js/components/ModalDialog.jsx b/client/src/js/components/ModalDialog.jsx similarity index 100% rename from client2/src/js/components/ModalDialog.jsx rename to client/src/js/components/ModalDialog.jsx diff --git a/client2/src/js/components/MultiDropdown.jsx b/client/src/js/components/MultiDropdown.jsx similarity index 100% rename from client2/src/js/components/MultiDropdown.jsx rename to client/src/js/components/MultiDropdown.jsx diff --git a/client2/src/js/components/OverlayTrigger.jsx b/client/src/js/components/OverlayTrigger.jsx similarity index 100% rename from client2/src/js/components/OverlayTrigger.jsx rename to client/src/js/components/OverlayTrigger.jsx diff --git a/client2/src/js/components/PageOrientation.jsx b/client/src/js/components/PageOrientation.jsx similarity index 100% rename from client2/src/js/components/PageOrientation.jsx rename to client/src/js/components/PageOrientation.jsx diff --git a/client2/src/js/components/PrintButton.jsx b/client/src/js/components/PrintButton.jsx similarity index 100% rename from client2/src/js/components/PrintButton.jsx rename to client/src/js/components/PrintButton.jsx diff --git a/client2/src/js/components/ReturnButton.jsx b/client/src/js/components/ReturnButton.jsx similarity index 100% rename from client2/src/js/components/ReturnButton.jsx rename to client/src/js/components/ReturnButton.jsx diff --git a/client2/src/js/components/RootCloseMenu.jsx b/client/src/js/components/RootCloseMenu.jsx similarity index 100% rename from client2/src/js/components/RootCloseMenu.jsx rename to client/src/js/components/RootCloseMenu.jsx diff --git a/client2/src/js/components/SearchControl.jsx b/client/src/js/components/SearchControl.jsx similarity index 100% rename from client2/src/js/components/SearchControl.jsx rename to client/src/js/components/SearchControl.jsx diff --git a/client2/src/js/components/SortTable.jsx b/client/src/js/components/SortTable.jsx similarity index 100% rename from client2/src/js/components/SortTable.jsx rename to client/src/js/components/SortTable.jsx diff --git a/client2/src/js/components/Spinner.jsx b/client/src/js/components/Spinner.jsx similarity index 100% rename from client2/src/js/components/Spinner.jsx rename to client/src/js/components/Spinner.jsx diff --git a/client2/src/js/components/StatusDropdown.jsx b/client/src/js/components/StatusDropdown.jsx similarity index 100% rename from client2/src/js/components/StatusDropdown.jsx rename to client/src/js/components/StatusDropdown.jsx diff --git a/client2/src/js/components/TableControl.jsx b/client/src/js/components/TableControl.jsx similarity index 100% rename from client2/src/js/components/TableControl.jsx rename to client/src/js/components/TableControl.jsx diff --git a/client2/src/js/components/TooltipButton.jsx b/client/src/js/components/TooltipButton.jsx similarity index 100% rename from client2/src/js/components/TooltipButton.jsx rename to client/src/js/components/TooltipButton.jsx diff --git a/client2/src/js/components/Unimplemented.jsx b/client/src/js/components/Unimplemented.jsx similarity index 100% rename from client2/src/js/components/Unimplemented.jsx rename to client/src/js/components/Unimplemented.jsx diff --git a/client2/src/js/components/Watermark.jsx b/client/src/js/components/Watermark.jsx similarity index 100% rename from client2/src/js/components/Watermark.jsx rename to client/src/js/components/Watermark.jsx diff --git a/client2/src/js/components/ui/AddButtonContainer.jsx b/client/src/js/components/ui/AddButtonContainer.jsx similarity index 100% rename from client2/src/js/components/ui/AddButtonContainer.jsx rename to client/src/js/components/ui/AddButtonContainer.jsx diff --git a/client2/src/js/components/ui/PageHeader.jsx b/client/src/js/components/ui/PageHeader.jsx similarity index 100% rename from client2/src/js/components/ui/PageHeader.jsx rename to client/src/js/components/ui/PageHeader.jsx diff --git a/client2/src/js/components/ui/SearchBar.jsx b/client/src/js/components/ui/SearchBar.jsx similarity index 100% rename from client2/src/js/components/ui/SearchBar.jsx rename to client/src/js/components/ui/SearchBar.jsx diff --git a/client2/src/js/components/ui/SubHeader.jsx b/client/src/js/components/ui/SubHeader.jsx similarity index 100% rename from client2/src/js/components/ui/SubHeader.jsx rename to client/src/js/components/ui/SubHeader.jsx diff --git a/client2/src/js/constants.js b/client/src/js/constants.js similarity index 100% rename from client2/src/js/constants.js rename to client/src/js/constants.js diff --git a/client2/src/js/history.js b/client/src/js/history.js similarity index 100% rename from client2/src/js/history.js rename to client/src/js/history.js diff --git a/client2/src/js/init.js b/client/src/js/init.js similarity index 100% rename from client2/src/js/init.js rename to client/src/js/init.js diff --git a/client2/src/js/reducers/all.js b/client/src/js/reducers/all.js similarity index 100% rename from client2/src/js/reducers/all.js rename to client/src/js/reducers/all.js diff --git a/client2/src/js/reducers/lookups.js b/client/src/js/reducers/lookups.js similarity index 100% rename from client2/src/js/reducers/lookups.js rename to client/src/js/reducers/lookups.js diff --git a/client2/src/js/reducers/models.js b/client/src/js/reducers/models.js similarity index 100% rename from client2/src/js/reducers/models.js rename to client/src/js/reducers/models.js diff --git a/client2/src/js/reducers/search.js b/client/src/js/reducers/search.js similarity index 100% rename from client2/src/js/reducers/search.js rename to client/src/js/reducers/search.js diff --git a/client2/src/js/reducers/ui.js b/client/src/js/reducers/ui.js similarity index 100% rename from client2/src/js/reducers/ui.js rename to client/src/js/reducers/ui.js diff --git a/client2/src/js/reducers/user.js b/client/src/js/reducers/user.js similarity index 100% rename from client2/src/js/reducers/user.js rename to client/src/js/reducers/user.js diff --git a/client2/src/js/reducers/version.js b/client/src/js/reducers/version.js similarity index 100% rename from client2/src/js/reducers/version.js rename to client/src/js/reducers/version.js diff --git a/client2/src/js/selectors/history-selectors.js b/client/src/js/selectors/history-selectors.js similarity index 100% rename from client2/src/js/selectors/history-selectors.js rename to client/src/js/selectors/history-selectors.js diff --git a/client2/src/js/selectors/ui-selectors.js b/client/src/js/selectors/ui-selectors.js similarity index 100% rename from client2/src/js/selectors/ui-selectors.js rename to client/src/js/selectors/ui-selectors.js diff --git a/client2/src/js/store.js b/client/src/js/store.js similarity index 100% rename from client2/src/js/store.js rename to client/src/js/store.js diff --git a/client2/src/js/utils/array.js b/client/src/js/utils/array.js similarity index 100% rename from client2/src/js/utils/array.js rename to client/src/js/utils/array.js diff --git a/client2/src/js/utils/date.js b/client/src/js/utils/date.js similarity index 100% rename from client2/src/js/utils/date.js rename to client/src/js/utils/date.js diff --git a/client2/src/js/utils/http.js b/client/src/js/utils/http.js similarity index 100% rename from client2/src/js/utils/http.js rename to client/src/js/utils/http.js diff --git a/client2/src/js/utils/routes.js b/client/src/js/utils/routes.js similarity index 100% rename from client2/src/js/utils/routes.js rename to client/src/js/utils/routes.js diff --git a/client2/src/js/utils/string.js b/client/src/js/utils/string.js similarity index 100% rename from client2/src/js/utils/string.js rename to client/src/js/utils/string.js diff --git a/client2/src/js/utils/string_test.js b/client/src/js/utils/string_test.js similarity index 100% rename from client2/src/js/utils/string_test.js rename to client/src/js/utils/string_test.js diff --git a/client2/src/js/views/404.jsx b/client/src/js/views/404.jsx similarity index 100% rename from client2/src/js/views/404.jsx rename to client/src/js/views/404.jsx diff --git a/client2/src/js/views/AitReport.jsx b/client/src/js/views/AitReport.jsx similarity index 100% rename from client2/src/js/views/AitReport.jsx rename to client/src/js/views/AitReport.jsx diff --git a/client2/src/js/views/BusinessOwner.jsx b/client/src/js/views/BusinessOwner.jsx similarity index 100% rename from client2/src/js/views/BusinessOwner.jsx rename to client/src/js/views/BusinessOwner.jsx diff --git a/client2/src/js/views/BusinessPortal.jsx b/client/src/js/views/BusinessPortal.jsx similarity index 100% rename from client2/src/js/views/BusinessPortal.jsx rename to client/src/js/views/BusinessPortal.jsx diff --git a/client2/src/js/views/DistrictAdmin.jsx b/client/src/js/views/DistrictAdmin.jsx similarity index 100% rename from client2/src/js/views/DistrictAdmin.jsx rename to client/src/js/views/DistrictAdmin.jsx diff --git a/client2/src/js/views/Equipment.jsx b/client/src/js/views/Equipment.jsx similarity index 100% rename from client2/src/js/views/Equipment.jsx rename to client/src/js/views/Equipment.jsx diff --git a/client2/src/js/views/EquipmentDetail.jsx b/client/src/js/views/EquipmentDetail.jsx similarity index 100% rename from client2/src/js/views/EquipmentDetail.jsx rename to client/src/js/views/EquipmentDetail.jsx diff --git a/client2/src/js/views/EquipmentTable.jsx b/client/src/js/views/EquipmentTable.jsx similarity index 100% rename from client2/src/js/views/EquipmentTable.jsx rename to client/src/js/views/EquipmentTable.jsx diff --git a/client2/src/js/views/Footer.jsx b/client/src/js/views/Footer.jsx similarity index 100% rename from client2/src/js/views/Footer.jsx rename to client/src/js/views/Footer.jsx diff --git a/client2/src/js/views/HiringReport.jsx b/client/src/js/views/HiringReport.jsx similarity index 100% rename from client2/src/js/views/HiringReport.jsx rename to client/src/js/views/HiringReport.jsx diff --git a/client2/src/js/views/Home.jsx b/client/src/js/views/Home.jsx similarity index 100% rename from client2/src/js/views/Home.jsx rename to client/src/js/views/Home.jsx diff --git a/client2/src/js/views/Main.jsx b/client/src/js/views/Main.jsx similarity index 100% rename from client2/src/js/views/Main.jsx rename to client/src/js/views/Main.jsx diff --git a/client2/src/js/views/OvertimeRates.jsx b/client/src/js/views/OvertimeRates.jsx similarity index 100% rename from client2/src/js/views/OvertimeRates.jsx rename to client/src/js/views/OvertimeRates.jsx diff --git a/client2/src/js/views/Owners.jsx b/client/src/js/views/Owners.jsx similarity index 100% rename from client2/src/js/views/Owners.jsx rename to client/src/js/views/Owners.jsx diff --git a/client2/src/js/views/OwnersDetail.jsx b/client/src/js/views/OwnersDetail.jsx similarity index 100% rename from client2/src/js/views/OwnersDetail.jsx rename to client/src/js/views/OwnersDetail.jsx diff --git a/client2/src/js/views/Projects.jsx b/client/src/js/views/Projects.jsx similarity index 100% rename from client2/src/js/views/Projects.jsx rename to client/src/js/views/Projects.jsx diff --git a/client2/src/js/views/ProjectsDetail.jsx b/client/src/js/views/ProjectsDetail.jsx similarity index 100% rename from client2/src/js/views/ProjectsDetail.jsx rename to client/src/js/views/ProjectsDetail.jsx diff --git a/client2/src/js/views/RentalAgreementsDetail.jsx b/client/src/js/views/RentalAgreementsDetail.jsx similarity index 100% rename from client2/src/js/views/RentalAgreementsDetail.jsx rename to client/src/js/views/RentalAgreementsDetail.jsx diff --git a/client2/src/js/views/RentalRequests.jsx b/client/src/js/views/RentalRequests.jsx similarity index 100% rename from client2/src/js/views/RentalRequests.jsx rename to client/src/js/views/RentalRequests.jsx diff --git a/client2/src/js/views/RentalRequestsDetail.jsx b/client/src/js/views/RentalRequestsDetail.jsx similarity index 100% rename from client2/src/js/views/RentalRequestsDetail.jsx rename to client/src/js/views/RentalRequestsDetail.jsx diff --git a/client2/src/js/views/Roles.jsx b/client/src/js/views/Roles.jsx similarity index 100% rename from client2/src/js/views/Roles.jsx rename to client/src/js/views/Roles.jsx diff --git a/client2/src/js/views/RolesDetail.jsx b/client/src/js/views/RolesDetail.jsx similarity index 100% rename from client2/src/js/views/RolesDetail.jsx rename to client/src/js/views/RolesDetail.jsx diff --git a/client2/src/js/views/Rollover.jsx b/client/src/js/views/Rollover.jsx similarity index 100% rename from client2/src/js/views/Rollover.jsx rename to client/src/js/views/Rollover.jsx diff --git a/client2/src/js/views/SeniorityList.jsx b/client/src/js/views/SeniorityList.jsx similarity index 100% rename from client2/src/js/views/SeniorityList.jsx rename to client/src/js/views/SeniorityList.jsx diff --git a/client2/src/js/views/StatusLetters.jsx b/client/src/js/views/StatusLetters.jsx similarity index 100% rename from client2/src/js/views/StatusLetters.jsx rename to client/src/js/views/StatusLetters.jsx diff --git a/client2/src/js/views/TimeEntry.jsx b/client/src/js/views/TimeEntry.jsx similarity index 100% rename from client2/src/js/views/TimeEntry.jsx rename to client/src/js/views/TimeEntry.jsx diff --git a/client2/src/js/views/TopNav.jsx b/client/src/js/views/TopNav.jsx similarity index 100% rename from client2/src/js/views/TopNav.jsx rename to client/src/js/views/TopNav.jsx diff --git a/client2/src/js/views/Users.jsx b/client/src/js/views/Users.jsx similarity index 100% rename from client2/src/js/views/Users.jsx rename to client/src/js/views/Users.jsx diff --git a/client2/src/js/views/UsersDetail.jsx b/client/src/js/views/UsersDetail.jsx similarity index 100% rename from client2/src/js/views/UsersDetail.jsx rename to client/src/js/views/UsersDetail.jsx diff --git a/client2/src/js/views/Version.jsx b/client/src/js/views/Version.jsx similarity index 100% rename from client2/src/js/views/Version.jsx rename to client/src/js/views/Version.jsx diff --git a/client2/src/js/views/WcbCglCoverage.jsx b/client/src/js/views/WcbCglCoverage.jsx similarity index 100% rename from client2/src/js/views/WcbCglCoverage.jsx rename to client/src/js/views/WcbCglCoverage.jsx diff --git a/client2/src/js/views/dialogs/AttachmentAddDialog.jsx b/client/src/js/views/dialogs/AttachmentAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/AttachmentAddDialog.jsx rename to client/src/js/views/dialogs/AttachmentAddDialog.jsx diff --git a/client2/src/js/views/dialogs/AttachmentEditDialog.jsx b/client/src/js/views/dialogs/AttachmentEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/AttachmentEditDialog.jsx rename to client/src/js/views/dialogs/AttachmentEditDialog.jsx diff --git a/client2/src/js/views/dialogs/CloneDialog.jsx b/client/src/js/views/dialogs/CloneDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/CloneDialog.jsx rename to client/src/js/views/dialogs/CloneDialog.jsx diff --git a/client2/src/js/views/dialogs/ConditionAddEditDialog.jsx b/client/src/js/views/dialogs/ConditionAddEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ConditionAddEditDialog.jsx rename to client/src/js/views/dialogs/ConditionAddEditDialog.jsx diff --git a/client2/src/js/views/dialogs/ConfirmDialog.jsx b/client/src/js/views/dialogs/ConfirmDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ConfirmDialog.jsx rename to client/src/js/views/dialogs/ConfirmDialog.jsx diff --git a/client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx b/client/src/js/views/dialogs/ConfirmForceHireDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ConfirmForceHireDialog.jsx rename to client/src/js/views/dialogs/ConfirmForceHireDialog.jsx diff --git a/client2/src/js/views/dialogs/ContactsEditDialog.jsx b/client/src/js/views/dialogs/ContactsEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ContactsEditDialog.jsx rename to client/src/js/views/dialogs/ContactsEditDialog.jsx diff --git a/client2/src/js/views/dialogs/DistrictEditDialog.jsx b/client/src/js/views/dialogs/DistrictEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/DistrictEditDialog.jsx rename to client/src/js/views/dialogs/DistrictEditDialog.jsx diff --git a/client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx b/client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx rename to client/src/js/views/dialogs/DistrictEquipmentTypeAddEditDialog.jsx diff --git a/client2/src/js/views/dialogs/DocumentsListDialog.jsx b/client/src/js/views/dialogs/DocumentsListDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/DocumentsListDialog.jsx rename to client/src/js/views/dialogs/DocumentsListDialog.jsx diff --git a/client2/src/js/views/dialogs/EquipmentAddDialog.jsx b/client/src/js/views/dialogs/EquipmentAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/EquipmentAddDialog.jsx rename to client/src/js/views/dialogs/EquipmentAddDialog.jsx diff --git a/client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx b/client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx rename to client/src/js/views/dialogs/EquipmentChangeStatusDialog.jsx diff --git a/client2/src/js/views/dialogs/EquipmentEditDialog.jsx b/client/src/js/views/dialogs/EquipmentEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/EquipmentEditDialog.jsx rename to client/src/js/views/dialogs/EquipmentEditDialog.jsx diff --git a/client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx b/client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx rename to client/src/js/views/dialogs/EquipmentRentalRatesEditDialog.jsx diff --git a/client2/src/js/views/dialogs/EquipmentTransferDialog.jsx b/client/src/js/views/dialogs/EquipmentTransferDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/EquipmentTransferDialog.jsx rename to client/src/js/views/dialogs/EquipmentTransferDialog.jsx diff --git a/client2/src/js/views/dialogs/ErrorDialog.jsx b/client/src/js/views/dialogs/ErrorDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ErrorDialog.jsx rename to client/src/js/views/dialogs/ErrorDialog.jsx diff --git a/client2/src/js/views/dialogs/HireOfferEditDialog.jsx b/client/src/js/views/dialogs/HireOfferEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/HireOfferEditDialog.jsx rename to client/src/js/views/dialogs/HireOfferEditDialog.jsx diff --git a/client2/src/js/views/dialogs/NotesAddDialog.jsx b/client/src/js/views/dialogs/NotesAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/NotesAddDialog.jsx rename to client/src/js/views/dialogs/NotesAddDialog.jsx diff --git a/client2/src/js/views/dialogs/NotesDialog.jsx b/client/src/js/views/dialogs/NotesDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/NotesDialog.jsx rename to client/src/js/views/dialogs/NotesDialog.jsx diff --git a/client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx b/client/src/js/views/dialogs/OvertimeRateEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/OvertimeRateEditDialog.jsx rename to client/src/js/views/dialogs/OvertimeRateEditDialog.jsx diff --git a/client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx b/client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/OwnerChangeStatusDialog.jsx rename to client/src/js/views/dialogs/OwnerChangeStatusDialog.jsx diff --git a/client2/src/js/views/dialogs/OwnersAddDialog.jsx b/client/src/js/views/dialogs/OwnersAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/OwnersAddDialog.jsx rename to client/src/js/views/dialogs/OwnersAddDialog.jsx diff --git a/client2/src/js/views/dialogs/OwnersEditDialog.jsx b/client/src/js/views/dialogs/OwnersEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/OwnersEditDialog.jsx rename to client/src/js/views/dialogs/OwnersEditDialog.jsx diff --git a/client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx b/client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/OwnersPolicyEditDialog.jsx rename to client/src/js/views/dialogs/OwnersPolicyEditDialog.jsx diff --git a/client2/src/js/views/dialogs/ProjectsAddDialog.jsx b/client/src/js/views/dialogs/ProjectsAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ProjectsAddDialog.jsx rename to client/src/js/views/dialogs/ProjectsAddDialog.jsx diff --git a/client2/src/js/views/dialogs/ProjectsEditDialog.jsx b/client/src/js/views/dialogs/ProjectsEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/ProjectsEditDialog.jsx rename to client/src/js/views/dialogs/ProjectsEditDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx b/client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx rename to client/src/js/views/dialogs/RentalAgreementOvertimeNotesDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx b/client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalAgreementsEditDialog.jsx rename to client/src/js/views/dialogs/RentalAgreementsEditDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx b/client/src/js/views/dialogs/RentalConditionsEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalConditionsEditDialog.jsx rename to client/src/js/views/dialogs/RentalConditionsEditDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalRatesEditDialog.jsx b/client/src/js/views/dialogs/RentalRatesEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalRatesEditDialog.jsx rename to client/src/js/views/dialogs/RentalRatesEditDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx b/client/src/js/views/dialogs/RentalRequestsAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalRequestsAddDialog.jsx rename to client/src/js/views/dialogs/RentalRequestsAddDialog.jsx diff --git a/client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx b/client/src/js/views/dialogs/RentalRequestsEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/RentalRequestsEditDialog.jsx rename to client/src/js/views/dialogs/RentalRequestsEditDialog.jsx diff --git a/client2/src/js/views/dialogs/SeniorityEditDialog.jsx b/client/src/js/views/dialogs/SeniorityEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/SeniorityEditDialog.jsx rename to client/src/js/views/dialogs/SeniorityEditDialog.jsx diff --git a/client2/src/js/views/dialogs/TimeEntryDialog.jsx b/client/src/js/views/dialogs/TimeEntryDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/TimeEntryDialog.jsx rename to client/src/js/views/dialogs/TimeEntryDialog.jsx diff --git a/client2/src/js/views/dialogs/UserRoleAddDialog.jsx b/client/src/js/views/dialogs/UserRoleAddDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/UserRoleAddDialog.jsx rename to client/src/js/views/dialogs/UserRoleAddDialog.jsx diff --git a/client2/src/js/views/dialogs/UsersEditDialog.jsx b/client/src/js/views/dialogs/UsersEditDialog.jsx similarity index 100% rename from client2/src/js/views/dialogs/UsersEditDialog.jsx rename to client/src/js/views/dialogs/UsersEditDialog.jsx diff --git a/client2/src/logo.svg b/client/src/logo.svg similarity index 100% rename from client2/src/logo.svg rename to client/src/logo.svg diff --git a/client2/src/reportWebVitals.js b/client/src/reportWebVitals.js similarity index 100% rename from client2/src/reportWebVitals.js rename to client/src/reportWebVitals.js diff --git a/client2/src/sass/components/all.scss b/client/src/sass/components/all.scss similarity index 100% rename from client2/src/sass/components/all.scss rename to client/src/sass/components/all.scss diff --git a/client2/src/sass/components/badge-label.scss b/client/src/sass/components/badge-label.scss similarity index 100% rename from client2/src/sass/components/badge-label.scss rename to client/src/sass/components/badge-label.scss diff --git a/client2/src/sass/components/clone-dialog.scss b/client/src/sass/components/clone-dialog.scss similarity index 100% rename from client2/src/sass/components/clone-dialog.scss rename to client/src/sass/components/clone-dialog.scss diff --git a/client2/src/sass/components/date-control.scss b/client/src/sass/components/date-control.scss similarity index 100% rename from client2/src/sass/components/date-control.scss rename to client/src/sass/components/date-control.scss diff --git a/client2/src/sass/components/dropdown-control.scss b/client/src/sass/components/dropdown-control.scss similarity index 100% rename from client2/src/sass/components/dropdown-control.scss rename to client/src/sass/components/dropdown-control.scss diff --git a/client2/src/sass/components/favourites.scss b/client/src/sass/components/favourites.scss similarity index 100% rename from client2/src/sass/components/favourites.scss rename to client/src/sass/components/favourites.scss diff --git a/client2/src/sass/components/file-upload.scss b/client/src/sass/components/file-upload.scss similarity index 100% rename from client2/src/sass/components/file-upload.scss rename to client/src/sass/components/file-upload.scss diff --git a/client2/src/sass/components/filter-dropdown.scss b/client/src/sass/components/filter-dropdown.scss similarity index 100% rename from client2/src/sass/components/filter-dropdown.scss rename to client/src/sass/components/filter-dropdown.scss diff --git a/client2/src/sass/components/form-dialog.scss b/client/src/sass/components/form-dialog.scss similarity index 100% rename from client2/src/sass/components/form-dialog.scss rename to client/src/sass/components/form-dialog.scss diff --git a/client2/src/sass/components/form-input-control.scss b/client/src/sass/components/form-input-control.scss similarity index 100% rename from client2/src/sass/components/form-input-control.scss rename to client/src/sass/components/form-input-control.scss diff --git a/client2/src/sass/components/history.scss b/client/src/sass/components/history.scss similarity index 100% rename from client2/src/sass/components/history.scss rename to client/src/sass/components/history.scss diff --git a/client2/src/sass/components/link-control.scss b/client/src/sass/components/link-control.scss similarity index 100% rename from client2/src/sass/components/link-control.scss rename to client/src/sass/components/link-control.scss diff --git a/client2/src/sass/components/multi-dropdown.scss b/client/src/sass/components/multi-dropdown.scss similarity index 100% rename from client2/src/sass/components/multi-dropdown.scss rename to client/src/sass/components/multi-dropdown.scss diff --git a/client2/src/sass/components/print-button.scss b/client/src/sass/components/print-button.scss similarity index 100% rename from client2/src/sass/components/print-button.scss rename to client/src/sass/components/print-button.scss diff --git a/client2/src/sass/components/return-button.scss b/client/src/sass/components/return-button.scss similarity index 100% rename from client2/src/sass/components/return-button.scss rename to client/src/sass/components/return-button.scss diff --git a/client2/src/sass/components/search-control.scss b/client/src/sass/components/search-control.scss similarity index 100% rename from client2/src/sass/components/search-control.scss rename to client/src/sass/components/search-control.scss diff --git a/client2/src/sass/components/sort-table.scss b/client/src/sass/components/sort-table.scss similarity index 100% rename from client2/src/sass/components/sort-table.scss rename to client/src/sass/components/sort-table.scss diff --git a/client2/src/sass/components/ui/add-button-container.scss b/client/src/sass/components/ui/add-button-container.scss similarity index 100% rename from client2/src/sass/components/ui/add-button-container.scss rename to client/src/sass/components/ui/add-button-container.scss diff --git a/client2/src/sass/components/ui/page-header.scss b/client/src/sass/components/ui/page-header.scss similarity index 100% rename from client2/src/sass/components/ui/page-header.scss rename to client/src/sass/components/ui/page-header.scss diff --git a/client2/src/sass/components/ui/search-bar.scss b/client/src/sass/components/ui/search-bar.scss similarity index 100% rename from client2/src/sass/components/ui/search-bar.scss rename to client/src/sass/components/ui/search-bar.scss diff --git a/client2/src/sass/components/ui/subheader.scss b/client/src/sass/components/ui/subheader.scss similarity index 100% rename from client2/src/sass/components/ui/subheader.scss rename to client/src/sass/components/ui/subheader.scss diff --git a/client2/src/sass/gov3.scss b/client/src/sass/gov3.scss similarity index 100% rename from client2/src/sass/gov3.scss rename to client/src/sass/gov3.scss diff --git a/client2/src/sass/header.scss b/client/src/sass/header.scss similarity index 100% rename from client2/src/sass/header.scss rename to client/src/sass/header.scss diff --git a/client2/src/sass/init.scss b/client/src/sass/init.scss similarity index 100% rename from client2/src/sass/init.scss rename to client/src/sass/init.scss diff --git a/client2/src/sass/main.scss b/client/src/sass/main.scss similarity index 100% rename from client2/src/sass/main.scss rename to client/src/sass/main.scss diff --git a/client2/src/sass/mixins.scss b/client/src/sass/mixins.scss similarity index 100% rename from client2/src/sass/mixins.scss rename to client/src/sass/mixins.scss diff --git a/client2/src/sass/print.scss b/client/src/sass/print.scss similarity index 100% rename from client2/src/sass/print.scss rename to client/src/sass/print.scss diff --git a/client2/src/sass/variables.scss b/client/src/sass/variables.scss similarity index 100% rename from client2/src/sass/variables.scss rename to client/src/sass/variables.scss diff --git a/client2/src/sass/views/all.scss b/client/src/sass/views/all.scss similarity index 100% rename from client2/src/sass/views/all.scss rename to client/src/sass/views/all.scss diff --git a/client2/src/sass/views/business-portal.scss b/client/src/sass/views/business-portal.scss similarity index 100% rename from client2/src/sass/views/business-portal.scss rename to client/src/sass/views/business-portal.scss diff --git a/client2/src/sass/views/dialogs/all.scss b/client/src/sass/views/dialogs/all.scss similarity index 100% rename from client2/src/sass/views/dialogs/all.scss rename to client/src/sass/views/dialogs/all.scss diff --git a/client2/src/sass/views/dialogs/contacts-edit.scss b/client/src/sass/views/dialogs/contacts-edit.scss similarity index 100% rename from client2/src/sass/views/dialogs/contacts-edit.scss rename to client/src/sass/views/dialogs/contacts-edit.scss diff --git a/client2/src/sass/views/dialogs/documents-list.scss b/client/src/sass/views/dialogs/documents-list.scss similarity index 100% rename from client2/src/sass/views/dialogs/documents-list.scss rename to client/src/sass/views/dialogs/documents-list.scss diff --git a/client2/src/sass/views/dialogs/equipment-transfer.scss b/client/src/sass/views/dialogs/equipment-transfer.scss similarity index 100% rename from client2/src/sass/views/dialogs/equipment-transfer.scss rename to client/src/sass/views/dialogs/equipment-transfer.scss diff --git a/client2/src/sass/views/dialogs/error-dialog.scss b/client/src/sass/views/dialogs/error-dialog.scss similarity index 100% rename from client2/src/sass/views/dialogs/error-dialog.scss rename to client/src/sass/views/dialogs/error-dialog.scss diff --git a/client2/src/sass/views/dialogs/notes.scss b/client/src/sass/views/dialogs/notes.scss similarity index 100% rename from client2/src/sass/views/dialogs/notes.scss rename to client/src/sass/views/dialogs/notes.scss diff --git a/client2/src/sass/views/dialogs/rental-rates-edit.scss b/client/src/sass/views/dialogs/rental-rates-edit.scss similarity index 100% rename from client2/src/sass/views/dialogs/rental-rates-edit.scss rename to client/src/sass/views/dialogs/rental-rates-edit.scss diff --git a/client2/src/sass/views/district-admin.scss b/client/src/sass/views/district-admin.scss similarity index 100% rename from client2/src/sass/views/district-admin.scss rename to client/src/sass/views/district-admin.scss diff --git a/client2/src/sass/views/equipment-list.scss b/client/src/sass/views/equipment-list.scss similarity index 100% rename from client2/src/sass/views/equipment-list.scss rename to client/src/sass/views/equipment-list.scss diff --git a/client2/src/sass/views/home.scss b/client/src/sass/views/home.scss similarity index 100% rename from client2/src/sass/views/home.scss rename to client/src/sass/views/home.scss diff --git a/client2/src/sass/views/owners.scss b/client/src/sass/views/owners.scss similarity index 100% rename from client2/src/sass/views/owners.scss rename to client/src/sass/views/owners.scss diff --git a/client2/src/sass/views/projects.scss b/client/src/sass/views/projects.scss similarity index 100% rename from client2/src/sass/views/projects.scss rename to client/src/sass/views/projects.scss diff --git a/client2/src/sass/views/rental-agreements.scss b/client/src/sass/views/rental-agreements.scss similarity index 100% rename from client2/src/sass/views/rental-agreements.scss rename to client/src/sass/views/rental-agreements.scss diff --git a/client2/src/sass/views/rental-requests.scss b/client/src/sass/views/rental-requests.scss similarity index 100% rename from client2/src/sass/views/rental-requests.scss rename to client/src/sass/views/rental-requests.scss diff --git a/client2/src/sass/views/roles.scss b/client/src/sass/views/roles.scss similarity index 100% rename from client2/src/sass/views/roles.scss rename to client/src/sass/views/roles.scss diff --git a/client2/src/sass/views/rollover.scss b/client/src/sass/views/rollover.scss similarity index 100% rename from client2/src/sass/views/rollover.scss rename to client/src/sass/views/rollover.scss diff --git a/client2/src/sass/views/users.scss b/client/src/sass/views/users.scss similarity index 100% rename from client2/src/sass/views/users.scss rename to client/src/sass/views/users.scss diff --git a/client2/src/setupProxy.js b/client/src/setupProxy.js similarity index 100% rename from client2/src/setupProxy.js rename to client/src/setupProxy.js diff --git a/client2/src/setupTests.js b/client/src/setupTests.js similarity index 100% rename from client2/src/setupTests.js rename to client/src/setupTests.js From 67cd1564b34238fb7c55de5594cfd590f4e5090f Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Thu, 3 Jun 2021 16:08:13 -0700 Subject: [PATCH 014/352] updated immer to v9.0.2 to fix high vulnerability --- client/package-lock.json | 6 +++--- client/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index c0d232a29..f6d9df9a8 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -7801,9 +7801,9 @@ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "immer": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/immer/-/immer-2.1.5.tgz", - "integrity": "sha512-xyjQyTBYIeiz6jd02Hg12jV+9QISwF1crLcwTlzHpWH4e0ryNWj1kacpTwimK3bJV5NKKXw458G2vpqoB/inFA==" + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.2.tgz", + "integrity": "sha512-mkcmzLtIfSp40vAqteRr1MbWNSoI7JE+/PB36FNPoSfJ9RQRmNKuTYCjKkyXyuq3Dgn07HuJBrwJd4ZSk2yUbw==" }, "import-cwd": { "version": "2.1.0", diff --git a/client/package.json b/client/package.json index a9a73b827..cb10ca48f 100644 --- a/client/package.json +++ b/client/package.json @@ -10,7 +10,7 @@ "bootstrap": "^3.4.1", "classnames": "^2.2.6", "http-proxy-middleware": "^2.0.0", - "immer": "^2.1.3", + "immer": "^9.0.2", "lodash": "^4.17.21", "moment": "^2.22.2", "node-sass": "^4.14.1", From 704092a0aca797afc654e051d6a610f93a489946 Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Thu, 3 Jun 2021 16:19:55 -0700 Subject: [PATCH 015/352] removed comment --- client/src/sass/main.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/sass/main.scss b/client/src/sass/main.scss index 4b67f2fc7..40a9cae71 100644 --- a/client/src/sass/main.scss +++ b/client/src/sass/main.scss @@ -1,4 +1,3 @@ -//temporary fix to remove conlficts with unknown pngs. @import "gov3"; @import "init"; @import "header"; From 0048ac9c9a97c41eea4b6aea3e00982cc9f01023 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 3 Jun 2021 14:55:03 -0700 Subject: [PATCH 016/352] .net 2.1 to .net 3.1 (has issues with Hangfire and EF query) --- Server/HetsApi.sln | 8 +- .../SiteminderAuthenticationHandler.cs | 3 +- .../Authorization/PermissionHandler.cs | 61 ++++---- .../Controllers/AuthenticationController.cs | 5 +- .../HetsApi/Controllers/BusinessController.cs | 4 +- .../Controllers/CurrentUserController.cs | 5 +- Server/HetsApi/Controllers/ErrorController.cs | 5 +- Server/HetsApi/Controllers/HomeController.cs | 5 +- .../HetsApi/Controllers/VersionController.cs | 5 +- Server/HetsApi/Helpers/UserAccountHelper.cs | 3 +- Server/HetsApi/HetsApi.csproj | 67 ++++----- Server/HetsApi/Program.cs | 33 +++-- Server/HetsApi/Startup.cs | 135 ++++++++++-------- Server/HetsApi/web.config | 18 --- Server/HetsCommon/HetsCommon.csproj | 8 +- Server/HetsData/Helpers/OwnerHelper.cs | 6 +- Server/HetsData/HetsData.csproj | 11 +- Server/HetsReport/HetsReport.csproj | 2 +- 18 files changed, 189 insertions(+), 195 deletions(-) delete mode 100644 Server/HetsApi/web.config diff --git a/Server/HetsApi.sln b/Server/HetsApi.sln index 0616a2f33..03f8f1b31 100644 --- a/Server/HetsApi.sln +++ b/Server/HetsApi.sln @@ -36,11 +36,9 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {FF1DB058-3D10-4065-A42B-E9EB5BEB0982} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {E88FFF3D-CE15-43E9-B1BE-4111E5862E2B} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {292B510E-6283-4616-AD2A-D8A994FD4285} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} - {7DFA1859-E5B0-4460-A5A5-5E5288A4AC94} = {A9D01C84-816F-449E-B0B3-CA5CE4DB13A4} + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BAABCEB5-DF1F-44BB-92B9-01FF124FABA6} diff --git a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs index 51394e541..e53c3e921 100644 --- a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs +++ b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs @@ -13,6 +13,7 @@ using Microsoft.EntityFrameworkCore; using HetsData.Model; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Hosting; namespace HetsApi.Authentication { @@ -200,7 +201,7 @@ protected override Task HandleAuthenticateAsync() { HttpContext context = Request.HttpContext; DbAppContext dbAppContext = (DbAppContext)context.RequestServices.GetService(typeof(DbAppContext)); - IHostingEnvironment hostingEnv = (IHostingEnvironment)context.RequestServices.GetService(typeof(IHostingEnvironment)); + IWebHostEnvironment hostingEnv = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment)); UserSettings userSettings = new UserSettings(); string userId = ""; diff --git a/Server/HetsApi/Authorization/PermissionHandler.cs b/Server/HetsApi/Authorization/PermissionHandler.cs index 77ab2ab02..7c9932140 100644 --- a/Server/HetsApi/Authorization/PermissionHandler.cs +++ b/Server/HetsApi/Authorization/PermissionHandler.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; namespace HetsApi.Authorization { @@ -32,9 +33,9 @@ public static IServiceCollection RegisterPermissionHandler(this IServiceCollecti public class PermissionHandler : AuthorizationHandler { private readonly HttpContext _httpContext; - private readonly IHostingEnvironment _hostingEnv; + private readonly IWebHostEnvironment _hostingEnv; - public PermissionHandler(IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnv) + public PermissionHandler(IHttpContextAccessor httpContextAccessor, IWebHostEnvironment hostingEnv) { _httpContext = httpContextAccessor.HttpContext; _hostingEnv = hostingEnv; @@ -48,39 +49,39 @@ public PermissionHandler(IHttpContextAccessor httpContextAccessor, IHostingEnvir /// protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { - // ************************************************** - // check if we have a Dev Environment Cookie - // ************************************************** - if (_hostingEnv.IsDevelopment()) - { - string temp = _httpContext.Request.Cookies["DEV-USER"]; + //// ************************************************** + //// check if we have a Dev Environment Cookie + //// ************************************************** + //if (_hostingEnv.IsDevelopment()) + //{ + // string temp = _httpContext.Request.Cookies["DEV-USER"]; - if (!string.IsNullOrEmpty(temp)) - { - // access granted - context.Succeed(requirement); + // if (!string.IsNullOrEmpty(temp)) + // { + // // access granted + // context.Succeed(requirement); - await Task.CompletedTask; - return; - } - } + // await Task.CompletedTask; + // return; + // } + //} - // ************************************************** - // check if we have a Business Dev Environment Cookie - // ************************************************** - if (_hostingEnv.IsDevelopment()) - { - string temp = _httpContext.Request.Cookies["BUS-USER"]; + //// ************************************************** + //// check if we have a Business Dev Environment Cookie + //// ************************************************** + //if (_hostingEnv.IsDevelopment()) + //{ + // string temp = _httpContext.Request.Cookies["BUS-USER"]; - if (!string.IsNullOrEmpty(temp)) - { - // access granted - context.Succeed(requirement); + // if (!string.IsNullOrEmpty(temp)) + // { + // // access granted + // context.Succeed(requirement); - await Task.CompletedTask; - return; - } - } + // await Task.CompletedTask; + // return; + // } + //} // ************************************************** // if not - check the users permissions diff --git a/Server/HetsApi/Controllers/AuthenticationController.cs b/Server/HetsApi/Controllers/AuthenticationController.cs index c60dfc5be..6ce100d9c 100644 --- a/Server/HetsApi/Controllers/AuthenticationController.cs +++ b/Server/HetsApi/Controllers/AuthenticationController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using HetsApi.Authentication; using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -17,7 +18,7 @@ namespace HetsApi.Controllers public class AuthenticationController : Controller { private readonly SiteMinderAuthOptions _options = new SiteMinderAuthOptions(); - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; private readonly HttpContext _httpContext; /// @@ -25,7 +26,7 @@ public class AuthenticationController : Controller /// /// /// - public AuthenticationController(IHostingEnvironment env, IHttpContextAccessor httpContextAccessor) + public AuthenticationController(IWebHostEnvironment env, IHttpContextAccessor httpContextAccessor) { _env = env; _httpContext = httpContextAccessor.HttpContext; diff --git a/Server/HetsApi/Controllers/BusinessController.cs b/Server/HetsApi/Controllers/BusinessController.cs index b36465878..680f8b2fa 100644 --- a/Server/HetsApi/Controllers/BusinessController.cs +++ b/Server/HetsApi/Controllers/BusinessController.cs @@ -25,9 +25,9 @@ public class BusinessController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly HttpContext _httpContext; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; - public BusinessController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnv) + public BusinessController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment hostingEnv) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Controllers/CurrentUserController.cs b/Server/HetsApi/Controllers/CurrentUserController.cs index 381d94fe4..5aa7ed792 100644 --- a/Server/HetsApi/Controllers/CurrentUserController.cs +++ b/Server/HetsApi/Controllers/CurrentUserController.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -27,10 +28,10 @@ public class CurrentUserController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly ILogger _logger; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; private readonly HttpContext _httpContext; - public CurrentUserController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, ILoggerFactory loggerFactory, IHostingEnvironment env) + public CurrentUserController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, ILoggerFactory loggerFactory, IWebHostEnvironment env) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Controllers/ErrorController.cs b/Server/HetsApi/Controllers/ErrorController.cs index 33a3940fb..d66b9f5d8 100644 --- a/Server/HetsApi/Controllers/ErrorController.cs +++ b/Server/HetsApi/Controllers/ErrorController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http.Features; using HetsApi.Model; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -16,13 +17,13 @@ namespace HetsApi.Controllers [ApiExplorerSettings(IgnoreApi = true)] public class ErrorController : Controller { - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; /// /// Error Controller Constructor /// /// - public ErrorController(IHostingEnvironment env) + public ErrorController(IWebHostEnvironment env) { _env = env; } diff --git a/Server/HetsApi/Controllers/HomeController.cs b/Server/HetsApi/Controllers/HomeController.cs index 602c9c1a4..66878e057 100644 --- a/Server/HetsApi/Controllers/HomeController.cs +++ b/Server/HetsApi/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Hosting; using HetsApi.Model; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -11,13 +12,13 @@ namespace HetsApi.Controllers [ApiExplorerSettings(IgnoreApi = true)] public class HomeController : Controller { - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; /// /// Authentication Controller Constructor /// /// - public HomeController(IHostingEnvironment env) + public HomeController(IWebHostEnvironment env) { _env = env; } diff --git a/Server/HetsApi/Controllers/VersionController.cs b/Server/HetsApi/Controllers/VersionController.cs index 9109c3b1b..70064be18 100644 --- a/Server/HetsApi/Controllers/VersionController.cs +++ b/Server/HetsApi/Controllers/VersionController.cs @@ -8,6 +8,7 @@ using HetsApi.Model; using HetsData.Model; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; namespace HetsApi.Controllers { @@ -22,9 +23,9 @@ public class VersionController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; - private readonly IHostingEnvironment _env; + private readonly IWebHostEnvironment _env; - public VersionController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IHostingEnvironment env) + public VersionController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment env) { _context = context; _configuration = configuration; diff --git a/Server/HetsApi/Helpers/UserAccountHelper.cs b/Server/HetsApi/Helpers/UserAccountHelper.cs index 691e2bc06..3accd34eb 100644 --- a/Server/HetsApi/Helpers/UserAccountHelper.cs +++ b/Server/HetsApi/Helpers/UserAccountHelper.cs @@ -8,6 +8,7 @@ using HetsData.Model; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Hosting; namespace HetsApi.Helpers { @@ -49,7 +50,7 @@ public static bool IsBusiness(HttpContext httpContext) /// /// /// - public static string GetBusinessGuid(HttpContext httpContext, IHostingEnvironment hostingEnv) + public static string GetBusinessGuid(HttpContext httpContext, IWebHostEnvironment hostingEnv) { string guid = ""; diff --git a/Server/HetsApi/HetsApi.csproj b/Server/HetsApi/HetsApi.csproj index c5446837a..a79bb01c4 100644 --- a/Server/HetsApi/HetsApi.csproj +++ b/Server/HetsApi/HetsApi.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 The Api server for the Hired Equipment Tracking System Copyright© 2017, Province of British Columbia. Hets Api Server @@ -36,45 +36,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + diff --git a/Server/HetsApi/Program.cs b/Server/HetsApi/Program.cs index 48195b78e..12c6a641b 100644 --- a/Server/HetsApi/Program.cs +++ b/Server/HetsApi/Program.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; namespace HetsApi { @@ -8,23 +10,24 @@ namespace HetsApi ///
public static class Program { - /// - /// Main - /// - /// public static void Main(string[] args) { - BuildWebHost(args).Run(); + CreateHostBuilder(args).Build().Run(); } - /// - /// Build Web Host - /// - /// - /// - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup() - .Build(); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + //.UseSerilog((hostingContext, loggerConfiguration) => { + // loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration); + //} + //) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddEnvironmentVariables(); + }); } } diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 0b43a5aa7..90a61db93 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -13,6 +13,12 @@ using HetsApi.Authorization; using HetsApi.Authentication; using HetsData.Model; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.OpenApi.Models; +using Microsoft.Extensions.Hosting; +using Swashbuckle.AspNetCore.SwaggerUI; namespace HetsApi { @@ -21,21 +27,14 @@ namespace HetsApi /// public class Startup { - private readonly IHostingEnvironment _hostingEnv; + private readonly IWebHostEnvironment _hostingEnv; - public IConfigurationRoot Configuration { get; } + public IConfiguration Configuration { get; } - public Startup(IHostingEnvironment env) + public Startup(IConfiguration configuration, IWebHostEnvironment env) { _hostingEnv = env; - - IConfigurationBuilder builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); - - Configuration = builder.Build(); + Configuration = configuration; } public void ConfigureServices(IServiceCollection services) @@ -48,6 +47,24 @@ public void ConfigureServices(IServiceCollection services) // add database context services.AddDbContext(options => options.UseNpgsql(connectionString)); + services + .AddControllers(options => + { + var policy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); + options.Filters.Add(new AuthorizeFilter(policy)); + }) + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; + options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; + options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; + options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); + // setup SiteMinder authentication (core 2.0+) services.AddAuthentication(options => { @@ -55,7 +72,6 @@ public void ConfigureServices(IServiceCollection services) options.DefaultChallengeScheme = SiteMinderAuthOptions.AuthenticationSchemeName; }).AddSiteMinderAuth(options => { - }); // setup authorization @@ -68,18 +84,6 @@ public void ConfigureServices(IServiceCollection services) options.MultipartBodyLengthLimit = 1073741824; // 1 GB }); - services.AddMvc(options => options.AddDefaultAuthorizationPolicyFilter()) - .AddJsonOptions( - opts => { - opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - opts.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; - opts.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; - opts.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; - - // ReferenceLoopHandling is set to Ignore to prevent JSON parser issues with the user / roles model. - opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; - }); - // enable Hangfire PostgreSqlStorageOptions postgreSqlStorageOptions = new PostgreSqlStorageOptions { SchemaName = "public" @@ -99,14 +103,12 @@ public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new Info + options.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "HETS REST API", Description = "Hired Equipment Tracking System" }); - - options.DescribeAllEnumsAsStrings(); }); } } @@ -117,28 +119,55 @@ public void ConfigureServices(IServiceCollection services) /// /// /// - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger logger) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - - // web site error handler (Testing: app.UseDeveloperExceptionPage();) - app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder => + if (env.IsDevelopment()) + app.UseDeveloperExceptionPage(); + + //app.UseMiddleware(); + + //TryMigrateDatabase(app, logger); + + //var healthCheckOptions = new HealthCheckOptions + //{ + // ResponseWriter = async (c, r) => + // { + // c.Response.ContentType = MediaTypeNames.Application.Json; + // var result = JsonSerializer.Serialize( + // new + // { + // checks = r.Entries.Select(e => + // new { + // description = e.Key, + // status = e.Value.Status.ToString(), + // tags = e.Value.Tags, + // responseTime = e.Value.Duration.TotalMilliseconds + // }), + // totalResponseTime = r.TotalDuration.TotalMilliseconds + // }); + // await c.Response.WriteAsync(result); + // } + //}; + + //app.UseHealthChecks("/healthz", healthCheckOptions); + + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + app.UseAuthorization(); + app.UseEndpoints(endpoints => { - builder.UseExceptionHandler(Configuration.GetSection("Constants:ErrorUrl").Value); + endpoints.MapControllers(); }); - // authenticate users - app.UseAuthentication(); - - // enable Hangfire - BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions + app.UseSwagger(); + app.UseSwaggerUI(options => { - WorkerCount = 1 - }; - - app.UseHangfireServer(jsOptions); + options.SwaggerEndpoint(Configuration.GetSection("Constants:SwaggerApiUrl").Value, "HETS REST API v1"); + options.DocExpansion(DocExpansion.None); + }); + // enable Hangfire Dashboard // disable the back to site link DashboardOptions dashboardOptions = new DashboardOptions { @@ -149,24 +178,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF // enable the hangfire dashboard app.UseHangfireDashboard(Configuration.GetSection("Constants:HangfireUrl").Value, dashboardOptions); - // setup mvc routes - app.UseMvc(routes => + BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}"); - }); + WorkerCount = 1 + }; - if (_hostingEnv.IsDevelopment()) - { - string swaggerApi = Configuration.GetSection("Constants:SwaggerApiUrl").Value; - app.UseSwagger(); - app.UseSwaggerUI(options => - { - options.SwaggerEndpoint(swaggerApi, "HETS REST API v1"); - options.DocExpansion(DocExpansion.None); - }); - } + app.UseHangfireServer(jsOptions); } /// diff --git a/Server/HetsApi/web.config b/Server/HetsApi/web.config deleted file mode 100644 index 92f64ac04..000000000 --- a/Server/HetsApi/web.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Server/HetsCommon/HetsCommon.csproj b/Server/HetsCommon/HetsCommon.csproj index e3626d0d1..3e767fea8 100644 --- a/Server/HetsCommon/HetsCommon.csproj +++ b/Server/HetsCommon/HetsCommon.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 Common code for the HETS application Copyright© 2017, Province of British Columbia Hets Common @@ -11,9 +11,9 @@ - - - + + + diff --git a/Server/HetsData/Helpers/OwnerHelper.cs b/Server/HetsData/Helpers/OwnerHelper.cs index c80225282..159c301a5 100644 --- a/Server/HetsData/Helpers/OwnerHelper.cs +++ b/Server/HetsData/Helpers/OwnerHelper.cs @@ -118,9 +118,9 @@ public static HetOwner GetRecord(int id, DbAppContext context, IConfiguration co .Include(x => x.HetEquipment) .ThenInclude(y => y.DistrictEquipmentType) .ThenInclude(z => z.EquipmentType) - .Include(x => x.HetEquipment) - .ThenInclude(y => y.Owner) - .ThenInclude(c => c.PrimaryContact) + //.Include(x => x.HetEquipment) + // .ThenInclude(y => y.Owner) + // .ThenInclude(c => c.PrimaryContact) .Include(x => x.HetEquipment) .ThenInclude(y => y.EquipmentStatusType) .Include(x => x.HetEquipment) diff --git a/Server/HetsData/HetsData.csproj b/Server/HetsData/HetsData.csproj index d9c02098e..b75e55f4b 100644 --- a/Server/HetsData/HetsData.csproj +++ b/Server/HetsData/HetsData.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 Common data code for the HETS application Copyright© 2017, Province of British Columbia Hets Data @@ -12,18 +12,15 @@ - - - + + + ..\..\..\..\..\Users\paulm\.nuget\packages\hangfire.core\1.6.20\lib\netstandard1.3\Hangfire.Core.dll - - ..\..\..\..\..\Users\paulm\.nuget\packages\microsoft.aspnetcore.mvc.core\1.0.4\lib\netstandard1.6\Microsoft.AspNetCore.Mvc.Core.dll - diff --git a/Server/HetsReport/HetsReport.csproj b/Server/HetsReport/HetsReport.csproj index 4142355b0..c1a21c053 100644 --- a/Server/HetsReport/HetsReport.csproj +++ b/Server/HetsReport/HetsReport.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 1.9.2.0 From 7e828562f66dadc4cf33916185d4348ac9c624a8 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Fri, 4 Jun 2021 14:37:35 -0700 Subject: [PATCH 017/352] Annual Rollover rewrite --- .../HetsApi/Controllers/DistrictController.cs | 16 +- .../Controllers/EquipmentController.cs | 11 +- Server/HetsApi/Startup.cs | 65 +- Server/HetsApi/appsettings.json | 2 +- Server/HetsCommon/FiscalHelper.cs | 19 + Server/HetsData/Hangfire/AnnualRollover.cs | 277 +++++++ .../Hangfire/DistrictEquipmentTypesMerger.cs | 302 +++++++ .../HetsData/Hangfire/SeniorityCalculator.cs | 62 ++ .../HetsData/Hangfire/SkipSameJobAttribute.cs | 77 ++ .../HetsData/Helpers/AnnualRolloverHelper.cs | 766 +++++++++--------- Server/HetsData/Helpers/EquipmentHelper.cs | 19 +- .../HetsData/Helpers/SeniorityListHelper.cs | 10 +- Server/HetsData/HetsData.csproj | 4 + client/.gitignore | 1 + client/package-lock.json | 25 + client/package.json | 1 + client/src/sass/components/date-control.scss | 6 +- 17 files changed, 1216 insertions(+), 447 deletions(-) create mode 100644 Server/HetsCommon/FiscalHelper.cs create mode 100644 Server/HetsData/Hangfire/AnnualRollover.cs create mode 100644 Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs create mode 100644 Server/HetsData/Hangfire/SeniorityCalculator.cs create mode 100644 Server/HetsData/Hangfire/SkipSameJobAttribute.cs diff --git a/Server/HetsApi/Controllers/DistrictController.cs b/Server/HetsApi/Controllers/DistrictController.cs index 3e10e2285..c1178c742 100644 --- a/Server/HetsApi/Controllers/DistrictController.cs +++ b/Server/HetsApi/Controllers/DistrictController.cs @@ -14,6 +14,7 @@ using HetsApi.Model; using HetsData.Helpers; using HetsData.Model; +using HetsData.Hangfire; namespace HetsApi.Controllers { @@ -27,11 +28,13 @@ public class DistrictController : Controller private readonly Object _thisLock = new Object(); private readonly DbAppContext _context; private readonly IConfiguration _configuration; + private readonly IAnnualRollover _annualRollover; - public DistrictController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor) + public DistrictController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IAnnualRollover annualRollover) { _context = context; _configuration = configuration; + _annualRollover = annualRollover; // set context data User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); @@ -130,7 +133,7 @@ public virtual IActionResult RolloverStatusGet([FromRoute]int id) if (!exists) return new NotFoundObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration))); // get status of current district - return new ObjectResult(new HetsResponse(AnnualRolloverHelper.GetRecord(id, _context))); + return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); } /// @@ -146,7 +149,7 @@ public virtual IActionResult DismissRolloverMessagePost([FromRoute]int id) bool exists = _context.HetDistrictStatus.Any(a => a.DistrictId == id); // not found - return new status record - if (!exists) return new ObjectResult(new HetsResponse(AnnualRolloverHelper.GetRecord(id, _context))); + if (!exists) return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); // get record and update HetDistrictStatus status = _context.HetDistrictStatus @@ -165,7 +168,7 @@ public virtual IActionResult DismissRolloverMessagePost([FromRoute]int id) } // get status of current district - return new ObjectResult(new HetsResponse(AnnualRolloverHelper.GetRecord(id, _context))); + return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); } /// @@ -195,7 +198,7 @@ public virtual IActionResult AnnualRolloverGet([FromRoute]int id) } // get record and ensure it isn't already processing - HetDistrictStatus status = AnnualRolloverHelper.GetRecord(id, _context); + HetDistrictStatus status = _annualRollover.GetRecord(id); if (status == null) { @@ -223,7 +226,8 @@ public virtual IActionResult AnnualRolloverGet([FromRoute]int id) string connectionString = GetConnectionString(); // queue the job - BackgroundJob.Enqueue(() => AnnualRolloverHelper.AnnualRolloverJob(null, id, seniorityScoringRules, connectionString)); + //BackgroundJob.Enqueue(() => AnnualRolloverHelper.AnnualRolloverJob(null, id, seniorityScoringRules, connectionString)); + BackgroundJob.Enqueue(x => x.AnnualRolloverJob(id, seniorityScoringRules)); // get counts for this district int localAreaCount = _context.HetLocalArea diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index b1f693816..9cd6d3c03 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -15,6 +15,7 @@ using HetsReport; using Hangfire; using System.Text; +using HetsData.Hangfire; namespace HetsApi.Controllers { @@ -544,8 +545,10 @@ public virtual IActionResult RecalculateSeniorityListPost() string seniorityScoringRules = GetConfigJson(scoringRules); // queue the job - BackgroundJob.Enqueue(() => EquipmentHelper.RecalculateSeniorityList(null, - seniorityScoringRules, connectionString)); + //BackgroundJob.Enqueue(() => EquipmentHelper.RecalculateSeniorityList(null, + // seniorityScoringRules, connectionString)); + + BackgroundJob.Enqueue(x => x.RecalculateSeniorityList(seniorityScoringRules)); // return ok return new ObjectResult(new HetsResponse("Recalculate job added to hangfire")); @@ -768,7 +771,9 @@ public virtual IActionResult EquipmentSearchGet([FromQuery]string localAreas, [F SeniorityScoringRules scoringRules = new SeniorityScoringRules(_configuration); List result = new List(); - foreach (HetEquipment item in data) + var dataList = data.ToList(); + + foreach (HetEquipment item in dataList) { result.Add(EquipmentHelper.ToLiteModel(item, scoringRules, (int)agreementStatusId, _context)); } diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 90a61db93..70c862769 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -19,6 +19,7 @@ using Microsoft.OpenApi.Models; using Microsoft.Extensions.Hosting; using Swashbuckle.AspNetCore.SwaggerUI; +using HetsData.Hangfire; namespace HetsApi { @@ -46,6 +47,7 @@ public void ConfigureServices(IServiceCollection services) // add database context services.AddDbContext(options => options.UseNpgsql(connectionString)); + services.AddScoped(); services .AddControllers(options => @@ -85,32 +87,31 @@ public void ConfigureServices(IServiceCollection services) }); // enable Hangfire - PostgreSqlStorageOptions postgreSqlStorageOptions = new PostgreSqlStorageOptions { - SchemaName = "public" - }; - if (connectionString != null) + //enable Hangfire + + services.AddHangfire(configuration => + configuration + //.UseSerilogLogProvider() + .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) + .UseSimpleAssemblyNameTypeSerializer() + .UseRecommendedSerializerSettings() + .UsePostgreSqlStorage(connectionString) + ); + + services.AddHangfireServer(options => { - PostgreSqlStorage storage = new PostgreSqlStorage(connectionString, postgreSqlStorageOptions); - services.AddHangfire(config => - { - config.UseStorage(storage); - config.UseConsole(); - }); - } + options.WorkerCount = 1; + }); - // Configure Swagger - only required in the Development Environment - if (_hostingEnv.IsDevelopment()) + services.AddSwaggerGen(options => { - services.AddSwaggerGen(options => + options.SwaggerDoc("v1", new OpenApiInfo { - options.SwaggerDoc("v1", new OpenApiInfo - { - Version = "v1", - Title = "HETS REST API", - Description = "Hired Equipment Tracking System" - }); + Version = "v1", + Title = "HETS REST API", + Description = "Hired Equipment Tracking System" }); - } + }); } /// @@ -166,24 +167,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger< options.SwaggerEndpoint(Configuration.GetSection("Constants:SwaggerApiUrl").Value, "HETS REST API v1"); options.DocExpansion(DocExpansion.None); }); - - // enable Hangfire Dashboard - // disable the back to site link - DashboardOptions dashboardOptions = new DashboardOptions - { - AppPath = null, - Authorization = new[] { new HangfireAuthorizationFilter() } - }; - - // enable the hangfire dashboard - app.UseHangfireDashboard(Configuration.GetSection("Constants:HangfireUrl").Value, dashboardOptions); - - BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions - { - WorkerCount = 1 - }; - - app.UseHangfireServer(jsOptions); } /// @@ -206,9 +189,11 @@ private string GetConnectionString() else { // environment variables override all other settings (OpenShift) - connectionString = $"Host={host};Username={username};Password={password};Database={database};"; + connectionString = $"Host={host};Username={username};Password={password};Database={database}"; } + connectionString += ";Timeout=600;CommandTimeout=0;"; + return connectionString; } } diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index 5eeb55ec5..7d8da7b11 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -81,7 +81,7 @@ "DumpTruck": 600 }, "ConnectionStrings": { - "HETS": "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" + "HETS": "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010;" }, "UploadPath": "D:\\Temp\\HETSUploads\\", "ReportsPath": "D:\\Temp\\HETSReports\\", diff --git a/Server/HetsCommon/FiscalHelper.cs b/Server/HetsCommon/FiscalHelper.cs new file mode 100644 index 000000000..64dbc528c --- /dev/null +++ b/Server/HetsCommon/FiscalHelper.cs @@ -0,0 +1,19 @@ +using System; + +namespace HetsApi.Helpers +{ + public static class FiscalHelper + { + public static int GetCurrentFiscalStartYear() + { + if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) + { + return DateTime.UtcNow.AddYears(-1).Year; + } + else + { + return DateTime.UtcNow.Year; + } + } + } +} diff --git a/Server/HetsData/Hangfire/AnnualRollover.cs b/Server/HetsData/Hangfire/AnnualRollover.cs new file mode 100644 index 000000000..5b137effe --- /dev/null +++ b/Server/HetsData/Hangfire/AnnualRollover.cs @@ -0,0 +1,277 @@ +using Hangfire; +using HetsApi.Helpers; +using HetsData.Helpers; +using HetsData.Model; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace HetsData.Hangfire +{ + public interface IAnnualRollover + { + public HetDistrictStatus GetRecord(int id); + public void AnnualRolloverJob(int districtId, string seniorityScoringRules); + } + + public class AnnualRollover : IAnnualRollover + { + private DbAppContext _dbContextMain; + private DbAppContext _dbContextSub; + private string _jobId; + + public AnnualRollover(DbAppContext dbContextMain, DbAppContext dbContextSub) + { + _dbContextMain = dbContextMain; + _dbContextSub = dbContextSub; + _jobId = Guid.NewGuid().ToString(); + } + + #region Get a District Status record + + /// + /// Get a District Status record + /// + /// + /// + /// + public HetDistrictStatus GetRecord(int id) + { + HetDistrictStatus status = _dbContextMain.HetDistrictStatus + .Include(a => a.District) + .FirstOrDefault(a => a.DistrictId == id); + + // if there isn't a status - we'll add one now + if (status == null) + { + var rolloverYear = FiscalHelper.GetCurrentFiscalStartYear(); + + status = new HetDistrictStatus + { + DistrictId = id, + CurrentFiscalYear = rolloverYear - 1, + NextFiscalYear = rolloverYear, + DisplayRolloverMessage = false + }; + + _dbContextMain.HetDistrictStatus.Add(status); + } + + return status; + } + + #endregion + + #region Annual Rollover Process + + /// + /// Annual Rollover + /// + /// + /// + /// + /// + [SkipSameJob] + [AutomaticRetry(Attempts = 0)] + public void AnnualRolloverJob(int districtId, string seniorityScoringRules) + { + try + { + var rolloverYear = FiscalHelper.GetCurrentFiscalStartYear(); + + // get processing rules + SeniorityScoringRules scoringRules = new SeniorityScoringRules(seniorityScoringRules); + + // validate district id + HetDistrict district = _dbContextMain.HetDistrict + .FirstOrDefault(x => x.DistrictId == districtId); + + if (district == null) + { + WriteLog("District not found"); + return; + } + + WriteLog("Starting - District #" + district.DistrictNumber); + + // get status record - and ensure we're active + HetDistrictStatus status = GetRecord(districtId); + + if (status == null) + { + WriteLog("District Status not found"); + return; + } + + if (status.CurrentFiscalYear == rolloverYear) + { + // return - cannot rollover again + WriteLog($"Annual Rollover for the fiscal year ({rolloverYear}/{rolloverYear+1}) of the district #{district.DistrictNumber} cannot be run again."); + return; + } + + // get equipment status + int? statusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", _dbContextMain); + if (statusId == null) + { + WriteLog("Equipment Status not found"); + return; + } + + //// determine the "Rollover Date" (required for testing) + //DateTime rolloverDate = new DateTime(rolloverYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); + //status.CurrentFiscalYear = rolloverYear; + //status.NextFiscalYear = rolloverYear + 1; + + // get all district equipment types + List equipmentTypes = _dbContextMain.HetDistrictEquipmentType + .Include(x => x.EquipmentType) + .Where(x => x.DistrictId == districtId).ToList(); + + // get all local areas + List localAreas = _dbContextMain.HetLocalArea + .Where(a => a.ServiceArea.DistrictId == districtId).ToList(); + + // update status - job is kicked off + int localAreaCompleteCount = 0; + int equipmentCompleteCount = 0; + + // process all local areas and equipment types + foreach (HetLocalArea localArea in localAreas) + { + if (localArea.Name != null) + { + WriteLog("Local Area: " + localArea.Name); + } + else + { + WriteLog("Local Area ID: " + localArea.LocalAreaId); + } + + // reset equipment counter + equipmentCompleteCount = 0; + + foreach (HetDistrictEquipmentType equipmentType in equipmentTypes) + { + WriteLog($"Equipment Type: {equipmentType.EquipmentTypeId}"); + // it this a dump truck? + bool isDumpTruck = equipmentType.EquipmentType.IsDumpTruck; + + // get rules for scoring and seniority block + int seniorityScoring = isDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); + int blockSize = isDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); + int totalBlocks = isDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); + + List data = _dbContextMain.HetEquipment + .Include(x => x.LocalArea) + .Include(x => x.DistrictEquipmentType.EquipmentType) + .Where(x => x.EquipmentStatusTypeId == statusId && + x.LocalAreaId == localArea.LocalAreaId && + x.DistrictEquipmentTypeId == equipmentType.DistrictEquipmentTypeId) + .ToList(); + + foreach (HetEquipment equipment in data) + { + // rollover the year + equipment.ServiceHoursThreeYearsAgo = equipment.ServiceHoursTwoYearsAgo; + equipment.ServiceHoursTwoYearsAgo = equipment.ServiceHoursLastYear; + equipment.ServiceHoursLastYear = EquipmentHelper.GetYtdServiceHours(equipment.EquipmentId, _dbContextMain); + equipment.CalculateYearsOfService(DateTime.UtcNow); + + // blank out the override reason + equipment.SeniorityOverrideReason = ""; + + // update the seniority score + equipment.CalculateSeniority(seniorityScoring); + } + + // now update the rotation list + int localAreaId = localArea.LocalAreaId; + int equipmentTypeId = equipmentType.DistrictEquipmentTypeId; + + SeniorityListHelper.AssignBlocks(localAreaId, equipmentTypeId, blockSize, totalBlocks, _dbContextMain, false); + + // increment counters and update status + equipmentCompleteCount++; + WriteLog($"Equipment Type ({equipmentCompleteCount}/{equipmentTypes.Count}"); + } + + // increment counters and update status + localAreaCompleteCount++; + WriteLog($"Local Area ({localAreaCompleteCount}/{localAreas.Count}"); + } + + // done! + UpdateStatusComplete(status, localAreaCompleteCount, equipmentCompleteCount); + _dbContextMain.SaveChanges(); //commit; + WriteLog("Save Completed"); + + // ********************************************************** + // regenerate Owner Secret Keys for this district + // ********************************************************** + WriteLog("Generate New Secret Keys - District #" + districtId); + + // get records + List owners = _dbContextMain.HetOwner + .Where(x => x.BusinessId == null && + x.LocalArea.ServiceArea.DistrictId == districtId) + .ToList(); + + int i = 0; + int ownerCount = owners.Count; + + foreach (HetOwner owner in owners) + { + i++; + string key = SecretKeyHelper.RandomString(8, owner.OwnerId); + + string temp = owner.OwnerCode; + + if (string.IsNullOrEmpty(temp)) + { + temp = SecretKeyHelper.RandomString(4, owner.OwnerId); + } + + key = temp + "-" + (rolloverYear + 1) + "-" + key; + + // get owner and update + HetOwner ownerRecord = _dbContextMain.HetOwner.First(x => x.OwnerId == owner.OwnerId); + ownerRecord.SharedKey = key; + + WriteLog($"Owner {i}/{ownerCount}"); + } + + // save remaining updates - done! + _dbContextMain.SaveChangesForImport(); + WriteLog("Generate New Secret Keys - Done"); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + private void UpdateStatusComplete(HetDistrictStatus status, int localAreaCompleteCount, int equipmentCompleteCount) + { + var rolloverYear = FiscalHelper.GetCurrentFiscalStartYear(); + + status.LocalAreaCompleteCount = localAreaCompleteCount; + status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; + status.ProgressPercentage = 100; + status.RolloverEndDate = DateTime.UtcNow; + status.CurrentFiscalYear = rolloverYear; + status.NextFiscalYear = rolloverYear + 1; + status.DisplayRolloverMessage = true; + } + + private void WriteLog(string message) + { + Console.WriteLine($"Annual Rollover[{_jobId}] {message}"); + } + + #endregion + + } +} diff --git a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs new file mode 100644 index 000000000..655b60921 --- /dev/null +++ b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs @@ -0,0 +1,302 @@ +using HetsData.Helpers; +using HetsData.Model; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace HetsData.Hangfire +{ + public class DistrictEquipmentTypesMerger + { + private DbAppContext _dbContext; + private string _jobId; + + public DistrictEquipmentTypesMerger(DbAppContext dbContext) + { + _dbContext = dbContext; + _jobId = Guid.NewGuid().ToString(); + } + + public void MergeDistrictEquipmentTypes(string seniorityScoringRules, + string connectionString) + { + // get equipment status + int? equipmentStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", _dbContext); + if (equipmentStatusId == null) + { + throw new ArgumentException("Status Code not found"); + } + + // ************************************************** + // Phase 1: Identify Master District Equipment Types + // ************************************************** + WriteLog("Phase 1: Identify Master District Equipment Types"); + + // get records + List masterList = _dbContext.HetDistrictEquipmentType + .Where(x => x.ServiceAreaId != null && + x.Deleted == false) + .Select(x => new MergeRecord + { + DistrictEquipmentTypeId = x.DistrictEquipmentTypeId, + DistrictEquipmentName = x.DistrictEquipmentName, + EquipmentPrefix = GetPrefix(x.DistrictEquipmentName), + DistrictId = x.DistrictId, + EquipmentTypeId = x.EquipmentTypeId + }) + .Distinct() + .ToList(); + + // sort the list accordingly + masterList = masterList + .OrderBy(x => x.DistrictId) + .ThenBy(x => x.EquipmentTypeId) + .ThenBy(x => x.EquipmentPrefix).ToList(); + + int increment = 0; + int? currentDistrict = -1; + int? masterDistrictEquipmentTypeId = -1; + int? currentEquipmentType = -1; + string currentPrefix = ""; + + foreach (MergeRecord detRecord in masterList) + { + bool newMerge; + + if (detRecord.DistrictId != currentDistrict || + detRecord.EquipmentTypeId != currentEquipmentType || + detRecord.EquipmentPrefix != currentPrefix) + { + newMerge = true; + currentDistrict = detRecord.DistrictId; + currentEquipmentType = detRecord.EquipmentTypeId; + currentPrefix = detRecord.EquipmentPrefix; + + masterDistrictEquipmentTypeId = detRecord.DistrictEquipmentTypeId; + detRecord.Master = true; + detRecord.MasterDistrictEquipmentTypeId = masterDistrictEquipmentTypeId; + } + else + { + newMerge = false; + detRecord.Master = false; + detRecord.MasterDistrictEquipmentTypeId = masterDistrictEquipmentTypeId; + } + + // kickoff the merge for this district, equipment type and prefix + if (newMerge) + { + int district = currentDistrict ?? -1; + int type = currentEquipmentType ?? -1; + string prefix = currentPrefix; + string masterName = ""; + + List types = masterList + .Where(x => x.DistrictId == district && + x.EquipmentTypeId == type && + x.EquipmentPrefix == prefix).ToList(); + + // create master name and update master record + foreach (MergeRecord equipmentType in types) + { + string temp = equipmentType.DistrictEquipmentName.Replace(currentPrefix, "").Trim(); + int start = temp.IndexOf("-", StringComparison.Ordinal); + if (start > -1) start++; + int length = temp.Length - start < 0 ? 0 : temp.Length - start; + temp = temp.Substring(start, length).Trim(); + + masterName = masterName.Length > 0 ? + $"{masterName} | {temp}" : + temp; + } + + masterName = $"{currentPrefix} - {masterName}"; + types.ElementAt(0).DistrictEquipmentName = masterName; + } + + // update status bar + increment++; + } + + // ************************************************** + // Phase 2: Update Master District Equipment Types + // ************************************************** + WriteLog("Phase 2: Update Master District Equipment Types"); + + List masterRecords = masterList.Where(x => x.Master).ToList(); + + increment = 0; + + foreach (MergeRecord detRecord in masterRecords) + { + // get det record & update name + HetDistrictEquipmentType det = _dbContext.HetDistrictEquipmentType + .First(x => x.DistrictEquipmentTypeId == detRecord.DistrictEquipmentTypeId); + + det.DistrictEquipmentName = detRecord.DistrictEquipmentName; + det.ServiceAreaId = null; + + // save changes to district equipment types and associated equipment records + _dbContext.SaveChangesForImport(); + + // update status bar + increment++; + } + + // ************************************************** + // Phase 3: Update Non-Master District Equipment Types + // ************************************************** + WriteLog("Phase 3: Update Non-Master District Equipment Types"); + + List mergeRecords = masterList.Where(x => !x.Master).ToList(); + + increment = 0; + + foreach (MergeRecord detRecord in mergeRecords) + { + int originalDistrictEquipmentTypeId = detRecord.DistrictEquipmentTypeId; + int? newDistrictEquipmentTypeId = detRecord.MasterDistrictEquipmentTypeId; + + // get equipment & update + IEnumerable equipmentRecords = _dbContext.HetEquipment + .Where(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); + + foreach (HetEquipment equipment in equipmentRecords) + { + equipment.DistrictEquipmentTypeId = newDistrictEquipmentTypeId; + } + + // save changes to associated equipment records + _dbContext.SaveChangesForImport(); + + // get det record + HetDistrictEquipmentType det = _dbContext.HetDistrictEquipmentType + .First(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); + + // delete old det record + HetRentalRequest request = _dbContext.HetRentalRequest + .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); + + HetLocalAreaRotationList rotationList = _dbContext.HetLocalAreaRotationList + .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); + + if (request != null || rotationList != null) + { + det.Deleted = true; + } + else + { + _dbContext.HetDistrictEquipmentType.Remove(det); + } + + // save changes to district equipment types and associated equipment records + _dbContext.SaveChangesForImport(); + + // update status bar + increment++; + } + + + // ************************************************** + // Phase 4: Update seniority and block assignments + // ************************************************** + WriteLog("Phase 4: Update seniority and block assignments"); + + increment = 0; + + foreach (MergeRecord detRecord in masterRecords) + { + // update the seniority and block assignments for the master record + List localAreas = _dbContext.HetEquipment + .Include(x => x.LocalArea) + .Where(x => x.EquipmentStatusTypeId == equipmentStatusId && + x.DistrictEquipmentTypeId == detRecord.DistrictEquipmentTypeId) + .Select(x => x.LocalArea) + .Distinct() + .ToList(); + + foreach (HetLocalArea localArea in localAreas) + { + EquipmentHelper.RecalculateSeniority(localArea.LocalAreaId, + detRecord.DistrictEquipmentTypeId, _dbContext, seniorityScoringRules); + } + + // save changes to equipment records + _dbContext.SaveChangesForImport(); + + // update status bar + increment++; + } + + // done! + + // ************************************************** + // Phase 5: Cleanup "empty" District Equipment Types + // ************************************************** + WriteLog("Phase 5: Cleanup empty District Equipment Types"); + + // get records + List districtEquipmentTypes = _dbContext.HetDistrictEquipmentType.AsNoTracking() + .Include(x => x.HetEquipment) + .Where(x => x.Deleted == false) + .Distinct() + .ToList(); + + increment = 0; + + foreach (HetDistrictEquipmentType districtEquipmentType in districtEquipmentTypes) + { + int districtEquipmentTypeId = districtEquipmentType.DistrictEquipmentTypeId; + + // does this det have any equipment records? + if (districtEquipmentType.HetEquipment.Count < 1) + { + // get det record + HetDistrictEquipmentType det = _dbContext.HetDistrictEquipmentType + .First(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); + + // delete old det record + HetRentalRequest request = _dbContext.HetRentalRequest.AsNoTracking() + .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); + + HetLocalAreaRotationList rotationList = _dbContext.HetLocalAreaRotationList.AsNoTracking() + .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); + + if (request != null || rotationList != null) + { + det.Deleted = true; + } + else + { + _dbContext.HetDistrictEquipmentType.Remove(det); + } + + // save changes to district equipment types and associated equipment records + _dbContext.SaveChangesForImport(); + } + + // update status bar + increment++; + } + + // done! + } + + private static string GetPrefix(string name) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentException("Invalid District Equipment Name"); + + int start = name.IndexOf("-", StringComparison.Ordinal); + + if (start <= 1) return name; + + return name.Substring(0, start).Trim(); + } + + private void WriteLog(string message) + { + Console.WriteLine($"Seniority Calculator[{_jobId}] {message}"); + } + } +} diff --git a/Server/HetsData/Hangfire/SeniorityCalculator.cs b/Server/HetsData/Hangfire/SeniorityCalculator.cs new file mode 100644 index 000000000..16dff3baa --- /dev/null +++ b/Server/HetsData/Hangfire/SeniorityCalculator.cs @@ -0,0 +1,62 @@ +using Hangfire; +using HetsData.Helpers; +using HetsData.Model; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace HetsData.Hangfire +{ + public class SeniorityCalculator + { + private DbAppContext _dbContext; + private string _jobId; + + public SeniorityCalculator(DbAppContext dbContext) + { + _dbContext = dbContext; + _jobId = Guid.NewGuid().ToString(); + } + /// + /// Recalculates seniority with the new sorting rule (sorting by equipment code) for the district equipment types that have the same seniority and received date + /// + /// + /// + /// + [SkipSameJob] + [AutomaticRetry(Attempts = 0)] + public void RecalculateSeniorityList(string seniorityScoringRules) + { + // get equipment status + int? equipmentStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", _dbContext); + if (equipmentStatusId == null) + { + throw new ArgumentException("Status Code not found"); + } + + WriteLog("Recalculation Started"); + + var equipments = _dbContext.HetEquipment + .Where(x => x.EquipmentStatusTypeId == equipmentStatusId) + .GroupBy(x => new { x.LocalAreaId, x.DistrictEquipmentTypeId, x.Seniority, x.ReceivedDate }) + .Where(x => x.Count() > 1) + .Select(x => new { x.Key.LocalAreaId, x.Key.DistrictEquipmentTypeId }) + .Distinct() + .ToList(); + + var count = 0; + foreach (var equipment in equipments) + { + EquipmentHelper.RecalculateSeniority(equipment.LocalAreaId, equipment.DistrictEquipmentTypeId, _dbContext, seniorityScoringRules); + WriteLog($"Processed {count} / {equipments.Count}"); + } + + WriteLog("Recalculation Finished"); + } + + private void WriteLog(string message) + { + Console.WriteLine($"Seniority Calculator[{_jobId}] {message}"); + } + } +} diff --git a/Server/HetsData/Hangfire/SkipSameJobAttribute.cs b/Server/HetsData/Hangfire/SkipSameJobAttribute.cs new file mode 100644 index 000000000..ea072fea8 --- /dev/null +++ b/Server/HetsData/Hangfire/SkipSameJobAttribute.cs @@ -0,0 +1,77 @@ +using Hangfire.Common; +using System; +using System.Linq; +using Newtonsoft.Json; +using Hangfire.Client; +using Hangfire.Server; + +namespace HetsData.Hangfire +{ + public sealed class SkipSameJobAttribute : JobFilterAttribute, IClientFilter, IServerFilter + { + private readonly int _timeoutInSeconds = 1; + + public void OnCreated(CreatedContext filterContext) + { + } + + public void OnCreating(CreatingContext context) + { + var job = context.Job; + var jobFingerprint = GetJobFingerprint(job); + + var monitor = context.Storage.GetMonitoringApi(); + var fingerprints = monitor.ProcessingJobs(0, 10000) + .Select(x => GetJobFingerprint(x.Value.Job)) + .ToList(); + + fingerprints.AddRange( + monitor.EnqueuedJobs("default", 0, 10000) + .Select(x => GetJobFingerprint(x.Value.Job)) + ); + + foreach (var fingerprint in fingerprints) + { + if (jobFingerprint != fingerprint) + continue; + + context.Canceled = true; + + return; + } + } + + public void OnPerforming(PerformingContext filterContext) + { + var resource = GetJobFingerprint(filterContext.BackgroundJob.Job); + + var timeout = TimeSpan.FromSeconds(_timeoutInSeconds); + + var distributedLock = filterContext.Connection.AcquireDistributedLock(resource, timeout); + filterContext.Items["DistributedLock"] = distributedLock; + } + + public void OnPerformed(PerformedContext filterContext) + { + if (!filterContext.Items.ContainsKey("DistributedLock")) + { + throw new InvalidOperationException("Can not release a distributed lock: it was not acquired."); + } + + var distributedLock = (IDisposable)filterContext.Items["DistributedLock"]; + distributedLock.Dispose(); + } + + private string GetJobFingerprint(Job job) + { + var args = ""; + + if (job.Args.Count > 0) + { + args = "-" + JsonConvert.SerializeObject(job.Args); + } + + return $"{job.Type.FullName}-{job.Method.Name}{args}"; + } + } +} diff --git a/Server/HetsData/Helpers/AnnualRolloverHelper.cs b/Server/HetsData/Helpers/AnnualRolloverHelper.cs index b547afad2..41fbd2525 100644 --- a/Server/HetsData/Helpers/AnnualRolloverHelper.cs +++ b/Server/HetsData/Helpers/AnnualRolloverHelper.cs @@ -9,387 +9,387 @@ namespace HetsData.Helpers { - /// - /// Annual Rollover List Helper - /// - public static class AnnualRolloverHelper - { - #region Get a District Status record - - /// - /// Get a District Status record - /// - /// - /// - /// - public static HetDistrictStatus GetRecord(int id, DbAppContext context) - { - HetDistrictStatus status = context.HetDistrictStatus.AsNoTracking() - .Include(a => a.District) - .FirstOrDefault(a => a.DistrictId == id); - - // if there isn't a status - we'll add one now - if (status == null) - { - // ******************************************************************************* - // determine current fiscal year - check for existing rotation lists this year - // ******************************************************************************* - DateTime fiscalStart; - - if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - { - fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); - } - else - { - fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); - } - - status = new HetDistrictStatus - { - DistrictId = id, - CurrentFiscalYear = fiscalStart.Year, - NextFiscalYear = fiscalStart.Year + 1, - DisplayRolloverMessage = false - }; - - context.HetDistrictStatus.Add(status); - context.SaveChanges(); - - // get updated record - status = context.HetDistrictStatus.AsNoTracking() - .Include(a => a.District) - .First(a => a.DistrictId == id); - } - - return status; - } - - #endregion - - #region Annual Rollover Process - - /// - /// Annual Rollover - /// - /// - /// - /// - /// - public static void AnnualRolloverJob(PerformContext context, int districtId, string seniorityScoringRules, string connectionString) - { - try - { - // open a connection to the database - DbAppContext dbContext = new DbAppContext(connectionString); - - // get processing rules - SeniorityScoringRules scoringRules = new SeniorityScoringRules(seniorityScoringRules); - - // update progress bar - IProgressBar progress = context.WriteProgressBar(); - context.WriteLine("Starting Annual Rollover Job - District #" + districtId); - - progress.SetValue(0); - - // validate district id - HetDistrict district = dbContext.HetDistrict.AsNoTracking() - .FirstOrDefault(x => x.DistrictId == districtId); - - if (district == null) - { - context.WriteLine("District not found"); - progress.SetValue(100); - return; - } - - // get status record - and ensure we're active - HetDistrictStatus status = GetRecord(districtId, dbContext); - - if (status == null) - { - context.WriteLine("District Status not found"); - progress.SetValue(100); - return; - } - - // get equipment status - int? statusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); - if (statusId == null) - { - context.WriteLine("Equipment Status not found"); - progress.SetValue(100); - return; - } - - // determine the "Rollover Date" (required for testing) - DateTime rolloverDate; - - if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - { - if (status.NextFiscalYear == null) status.NextFiscalYear = DateTime.UtcNow.Year; - - rolloverDate = new DateTime((int)status.NextFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); - } - else - { - if (status.CurrentFiscalYear == null) status.CurrentFiscalYear = DateTime.UtcNow.Year; - - rolloverDate = new DateTime((int)status.CurrentFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); - } - - // get all district equipment types - List equipmentTypes = dbContext.HetDistrictEquipmentType.AsNoTracking() - .Include(x => x.EquipmentType) - .Where(x => x.DistrictId == districtId).ToList(); - - // get all local areas - List localAreas = dbContext.HetLocalArea.AsNoTracking() - .Where(a => a.ServiceArea.DistrictId == districtId).ToList(); - - // update status - job is kicked off - int localAreaCompleteCount = 0; - int equipmentCompleteCount = 0; - - UpdateStatusKickoff(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - - // process all local areas and equipment types - foreach (HetLocalArea localArea in localAreas.WithProgress(progress)) - { - // re-open the connection - dbContext = new DbAppContext(connectionString); - - if (localArea.Name != null) - { - context.WriteLine("Local Area: " + localArea.Name); - } - else - { - context.WriteLine("Local Area ID: " + localArea.LocalAreaId); - } - - // reset equipment counter - equipmentCompleteCount = 0; - - foreach (HetDistrictEquipmentType equipmentType in equipmentTypes) - { - // it this a dump truck? - bool isDumpTruck = equipmentType.EquipmentType.IsDumpTruck; - - // get rules for scoring and seniority block - int seniorityScoring = isDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); - int blockSize = isDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); - int totalBlocks = isDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); - - using (DbAppContext etContext = new DbAppContext(connectionString)) - { - List data = etContext.HetEquipment - .Include(x => x.LocalArea) - .Include(x => x.DistrictEquipmentType.EquipmentType) - .Where(x => x.EquipmentStatusTypeId == statusId && - x.LocalAreaId == localArea.LocalAreaId && - x.DistrictEquipmentTypeId == equipmentType.DistrictEquipmentTypeId) - .ToList(); - - foreach (HetEquipment equipment in data) - { - // rollover the year - equipment.ServiceHoursThreeYearsAgo = equipment.ServiceHoursTwoYearsAgo; - equipment.ServiceHoursTwoYearsAgo = equipment.ServiceHoursLastYear; - equipment.ServiceHoursLastYear = EquipmentHelper.GetYtdServiceHours(equipment.EquipmentId, dbContext, rolloverDate); - equipment.CalculateYearsOfService(DateTime.UtcNow); - - // blank out the override reason - equipment.SeniorityOverrideReason = ""; - - // update the seniority score - equipment.CalculateSeniority(seniorityScoring); - - etContext.HetEquipment.Update(equipment); - etContext.SaveChanges(); - } - } - - // now update the rotation list - using (DbAppContext abContext = new DbAppContext(connectionString)) - { - int localAreaId = localArea.LocalAreaId; - int equipmentTypeId = equipmentType.DistrictEquipmentTypeId; - - SeniorityListHelper.AssignBlocks(localAreaId, equipmentTypeId, blockSize, totalBlocks, abContext); - } - - // increment counters and update status - equipmentCompleteCount++; - UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - } - - // increment counters and update status - localAreaCompleteCount++; - UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - if (status.ProgressPercentage != null) progress.SetValue((int)status.ProgressPercentage); - } - - // done! - UpdateStatusComplete(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - progress.SetValue(100); - - // ********************************************************** - // regenerate Owner Secret Keys for this district - // ********************************************************** - dbContext = new DbAppContext(connectionString); - - context.WriteLine(""); - context.WriteLine("Generate New Secret Keys - District #" + districtId); - progress = context.WriteProgressBar(); - - progress.SetValue(0); - // get records - List owners = dbContext.HetOwner.AsNoTracking() - .Where(x => x.BusinessId == null && - x.LocalArea.ServiceArea.DistrictId == districtId) - .ToList(); - - int i = 0; - int ownerCount = owners.Count; - - foreach (HetOwner owner in owners) - { - i++; - string key = SecretKeyHelper.RandomString(8, owner.OwnerId); - - string temp = owner.OwnerCode; - - if (string.IsNullOrEmpty(temp)) - { - temp = SecretKeyHelper.RandomString(4, owner.OwnerId); - } - - key = temp + "-" + (rolloverDate.Year + 1) + "-" + key; - - // get owner and update - HetOwner ownerRecord = dbContext.HetOwner.First(x => x.OwnerId == owner.OwnerId); - ownerRecord.SharedKey = key; - dbContext.HetOwner.Update(ownerRecord); - - decimal tempProgress = Convert.ToDecimal(i) / Convert.ToDecimal(ownerCount); - tempProgress = tempProgress * 100; - int percentComplete = Convert.ToInt32(tempProgress); - - if (percentComplete < 1) percentComplete = 1; - if (percentComplete > 99) percentComplete = 100; - - progress.SetValue(percentComplete); - } - - // save remaining updates - done! - dbContext.SaveChangesForImport(); - progress.SetValue(100); - context.WriteLine("Generate New Secret Keys - Done"); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - private static void UpdateStatus(DbAppContext dbContext, HetDistrictStatus status, - int localAreaCompleteCount, int equipmentCompleteCount) - { - try - { - int localAreaCount = status.LocalAreaCount ?? 0; - int equipmentCount = status.DistrictEquipmentTypeCount ?? 0; - int percentComplete; - - if (localAreaCount == 0 && - equipmentCount == 0) - { - percentComplete = 100; - } - else - { - // (current / maximum) * 100 -> just using the local area - decimal temp = Convert.ToDecimal(localAreaCompleteCount) / Convert.ToDecimal(localAreaCount); - temp = temp * 100; - percentComplete = Convert.ToInt32(temp); - - if (percentComplete < 1) percentComplete = 1; - if (percentComplete > 99) percentComplete = 100; - } - - status.LocalAreaCompleteCount = localAreaCompleteCount; - status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - status.ProgressPercentage = percentComplete; - status.DisplayRolloverMessage = true; - - dbContext.HetDistrictStatus.Update(status); - dbContext.SaveChanges(); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - private static void UpdateStatusKickoff(DbAppContext dbContext, HetDistrictStatus status, - int localAreaCompleteCount, int equipmentCompleteCount) - { - try - { - status.LocalAreaCompleteCount = localAreaCompleteCount; - status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - status.ProgressPercentage = 1; - status.RolloverStartDate = DateTime.UtcNow; - status.DisplayRolloverMessage = true; - - dbContext.HetDistrictStatus.Update(status); - dbContext.SaveChanges(); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - private static void UpdateStatusComplete(DbAppContext dbContext, HetDistrictStatus status, - int localAreaCompleteCount, int equipmentCompleteCount) - { - try - { - // determine the current fiscal year - DateTime fiscalStart; - - if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - { - fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); - } - else - { - fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); - } - - status.LocalAreaCompleteCount = localAreaCompleteCount; - status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - status.ProgressPercentage = 100; - status.RolloverEndDate = DateTime.UtcNow; - status.CurrentFiscalYear = fiscalStart.Year; - status.NextFiscalYear = fiscalStart.Year + 1; - status.DisplayRolloverMessage = true; - - dbContext.HetDistrictStatus.Update(status); - dbContext.SaveChanges(); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - - #endregion - } + ///// + ///// Annual Rollover List Helper + ///// + //public static class AnnualRolloverHelper + //{ + // #region Get a District Status record + + // /// + // /// Get a District Status record + // /// + // /// + // /// + // /// + // public static HetDistrictStatus GetRecord(int id, DbAppContext context) + // { + // HetDistrictStatus status = context.HetDistrictStatus.AsNoTracking() + // .Include(a => a.District) + // .FirstOrDefault(a => a.DistrictId == id); + + // // if there isn't a status - we'll add one now + // if (status == null) + // { + // // ******************************************************************************* + // // determine current fiscal year - check for existing rotation lists this year + // // ******************************************************************************* + // DateTime fiscalStart; + + // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) + // { + // fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); + // } + // else + // { + // fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); + // } + + // status = new HetDistrictStatus + // { + // DistrictId = id, + // CurrentFiscalYear = fiscalStart.Year, + // NextFiscalYear = fiscalStart.Year + 1, + // DisplayRolloverMessage = false + // }; + + // context.HetDistrictStatus.Add(status); + // context.SaveChanges(); + + // // get updated record + // status = context.HetDistrictStatus.AsNoTracking() + // .Include(a => a.District) + // .First(a => a.DistrictId == id); + // } + + // return status; + // } + + // #endregion + + // #region Annual Rollover Process + + // /// + // /// Annual Rollover + // /// + // /// + // /// + // /// + // /// + // public static void AnnualRolloverJob(PerformContext context, int districtId, string seniorityScoringRules, string connectionString) + // { + // try + // { + // // open a connection to the database + // DbAppContext dbContext = new DbAppContext(connectionString); + + // // get processing rules + // SeniorityScoringRules scoringRules = new SeniorityScoringRules(seniorityScoringRules); + + // // update progress bar + // IProgressBar progress = context.WriteProgressBar(); + // context.WriteLine("Starting Annual Rollover Job - District #" + districtId); + + // progress.SetValue(0); + + // // validate district id + // HetDistrict district = dbContext.HetDistrict.AsNoTracking() + // .FirstOrDefault(x => x.DistrictId == districtId); + + // if (district == null) + // { + // context.WriteLine("District not found"); + // progress.SetValue(100); + // return; + // } + + // // get status record - and ensure we're active + // HetDistrictStatus status = GetRecord(districtId, dbContext); + + // if (status == null) + // { + // context.WriteLine("District Status not found"); + // progress.SetValue(100); + // return; + // } + + // // get equipment status + // int? statusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); + // if (statusId == null) + // { + // context.WriteLine("Equipment Status not found"); + // progress.SetValue(100); + // return; + // } + + // // determine the "Rollover Date" (required for testing) + // DateTime rolloverDate; + + // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) + // { + // if (status.NextFiscalYear == null) status.NextFiscalYear = DateTime.UtcNow.Year; + + // rolloverDate = new DateTime((int)status.NextFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); + // } + // else + // { + // if (status.CurrentFiscalYear == null) status.CurrentFiscalYear = DateTime.UtcNow.Year; + + // rolloverDate = new DateTime((int)status.CurrentFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); + // } + + // // get all district equipment types + // List equipmentTypes = dbContext.HetDistrictEquipmentType.AsNoTracking() + // .Include(x => x.EquipmentType) + // .Where(x => x.DistrictId == districtId).ToList(); + + // // get all local areas + // List localAreas = dbContext.HetLocalArea.AsNoTracking() + // .Where(a => a.ServiceArea.DistrictId == districtId).ToList(); + + // // update status - job is kicked off + // int localAreaCompleteCount = 0; + // int equipmentCompleteCount = 0; + + // UpdateStatusKickoff(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); + + // // process all local areas and equipment types + // foreach (HetLocalArea localArea in localAreas.WithProgress(progress)) + // { + // // re-open the connection + // dbContext = new DbAppContext(connectionString); + + // if (localArea.Name != null) + // { + // context.WriteLine("Local Area: " + localArea.Name); + // } + // else + // { + // context.WriteLine("Local Area ID: " + localArea.LocalAreaId); + // } + + // // reset equipment counter + // equipmentCompleteCount = 0; + + // foreach (HetDistrictEquipmentType equipmentType in equipmentTypes) + // { + // // it this a dump truck? + // bool isDumpTruck = equipmentType.EquipmentType.IsDumpTruck; + + // // get rules for scoring and seniority block + // int seniorityScoring = isDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); + // int blockSize = isDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); + // int totalBlocks = isDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); + + // using (DbAppContext etContext = new DbAppContext(connectionString)) + // { + // List data = etContext.HetEquipment + // .Include(x => x.LocalArea) + // .Include(x => x.DistrictEquipmentType.EquipmentType) + // .Where(x => x.EquipmentStatusTypeId == statusId && + // x.LocalAreaId == localArea.LocalAreaId && + // x.DistrictEquipmentTypeId == equipmentType.DistrictEquipmentTypeId) + // .ToList(); + + // foreach (HetEquipment equipment in data) + // { + // // rollover the year + // equipment.ServiceHoursThreeYearsAgo = equipment.ServiceHoursTwoYearsAgo; + // equipment.ServiceHoursTwoYearsAgo = equipment.ServiceHoursLastYear; + // equipment.ServiceHoursLastYear = EquipmentHelper.GetYtdServiceHours(equipment.EquipmentId, dbContext); + // equipment.CalculateYearsOfService(DateTime.UtcNow); + + // // blank out the override reason + // equipment.SeniorityOverrideReason = ""; + + // // update the seniority score + // equipment.CalculateSeniority(seniorityScoring); + + // etContext.HetEquipment.Update(equipment); + // etContext.SaveChanges(); + // } + // } + + // // now update the rotation list + // using (DbAppContext abContext = new DbAppContext(connectionString)) + // { + // int localAreaId = localArea.LocalAreaId; + // int equipmentTypeId = equipmentType.DistrictEquipmentTypeId; + + // SeniorityListHelper.AssignBlocks(localAreaId, equipmentTypeId, blockSize, totalBlocks, abContext); + // } + + // // increment counters and update status + // equipmentCompleteCount++; + // UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); + // } + + // // increment counters and update status + // localAreaCompleteCount++; + // UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); + // if (status.ProgressPercentage != null) progress.SetValue((int)status.ProgressPercentage); + // } + + // // done! + // UpdateStatusComplete(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); + // progress.SetValue(100); + + // // ********************************************************** + // // regenerate Owner Secret Keys for this district + // // ********************************************************** + // dbContext = new DbAppContext(connectionString); + + // context.WriteLine(""); + // context.WriteLine("Generate New Secret Keys - District #" + districtId); + // progress = context.WriteProgressBar(); + + // progress.SetValue(0); + // // get records + // List owners = dbContext.HetOwner.AsNoTracking() + // .Where(x => x.BusinessId == null && + // x.LocalArea.ServiceArea.DistrictId == districtId) + // .ToList(); + + // int i = 0; + // int ownerCount = owners.Count; + + // foreach (HetOwner owner in owners) + // { + // i++; + // string key = SecretKeyHelper.RandomString(8, owner.OwnerId); + + // string temp = owner.OwnerCode; + + // if (string.IsNullOrEmpty(temp)) + // { + // temp = SecretKeyHelper.RandomString(4, owner.OwnerId); + // } + + // key = temp + "-" + (rolloverDate.Year + 1) + "-" + key; + + // // get owner and update + // HetOwner ownerRecord = dbContext.HetOwner.First(x => x.OwnerId == owner.OwnerId); + // ownerRecord.SharedKey = key; + // dbContext.HetOwner.Update(ownerRecord); + + // decimal tempProgress = Convert.ToDecimal(i) / Convert.ToDecimal(ownerCount); + // tempProgress = tempProgress * 100; + // int percentComplete = Convert.ToInt32(tempProgress); + + // if (percentComplete < 1) percentComplete = 1; + // if (percentComplete > 99) percentComplete = 100; + + // progress.SetValue(percentComplete); + // } + + // // save remaining updates - done! + // dbContext.SaveChangesForImport(); + // progress.SetValue(100); + // context.WriteLine("Generate New Secret Keys - Done"); + // } + // catch (Exception e) + // { + // Console.WriteLine(e); + // throw; + // } + // } + + // private static void UpdateStatus(DbAppContext dbContext, HetDistrictStatus status, + // int localAreaCompleteCount, int equipmentCompleteCount) + // { + // try + // { + // int localAreaCount = status.LocalAreaCount ?? 0; + // int equipmentCount = status.DistrictEquipmentTypeCount ?? 0; + // int percentComplete; + + // if (localAreaCount == 0 && + // equipmentCount == 0) + // { + // percentComplete = 100; + // } + // else + // { + // // (current / maximum) * 100 -> just using the local area + // decimal temp = Convert.ToDecimal(localAreaCompleteCount) / Convert.ToDecimal(localAreaCount); + // temp = temp * 100; + // percentComplete = Convert.ToInt32(temp); + + // if (percentComplete < 1) percentComplete = 1; + // if (percentComplete > 99) percentComplete = 100; + // } + + // status.LocalAreaCompleteCount = localAreaCompleteCount; + // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; + // status.ProgressPercentage = percentComplete; + // status.DisplayRolloverMessage = true; + + // dbContext.HetDistrictStatus.Update(status); + // dbContext.SaveChanges(); + // } + // catch (Exception e) + // { + // Console.WriteLine(e); + // throw; + // } + // } + + // private static void UpdateStatusKickoff(DbAppContext dbContext, HetDistrictStatus status, + // int localAreaCompleteCount, int equipmentCompleteCount) + // { + // try + // { + // status.LocalAreaCompleteCount = localAreaCompleteCount; + // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; + // status.ProgressPercentage = 1; + // status.RolloverStartDate = DateTime.UtcNow; + // status.DisplayRolloverMessage = true; + + // dbContext.HetDistrictStatus.Update(status); + // dbContext.SaveChanges(); + // } + // catch (Exception e) + // { + // Console.WriteLine(e); + // throw; + // } + // } + + // private static void UpdateStatusComplete(DbAppContext dbContext, HetDistrictStatus status, + // int localAreaCompleteCount, int equipmentCompleteCount) + // { + // try + // { + // // determine the current fiscal year + // DateTime fiscalStart; + + // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) + // { + // fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); + // } + // else + // { + // fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); + // } + + // status.LocalAreaCompleteCount = localAreaCompleteCount; + // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; + // status.ProgressPercentage = 100; + // status.RolloverEndDate = DateTime.UtcNow; + // status.CurrentFiscalYear = fiscalStart.Year; + // status.NextFiscalYear = fiscalStart.Year + 1; + // status.DisplayRolloverMessage = true; + + // dbContext.HetDistrictStatus.Update(status); + // dbContext.SaveChanges(); + // } + // catch (Exception e) + // { + // Console.WriteLine(e); + // throw; + // } + // } + + // #endregion + //} } diff --git a/Server/HetsData/Helpers/EquipmentHelper.cs b/Server/HetsData/Helpers/EquipmentHelper.cs index 2b0ef591f..0ba4f7e86 100644 --- a/Server/HetsData/Helpers/EquipmentHelper.cs +++ b/Server/HetsData/Helpers/EquipmentHelper.cs @@ -9,6 +9,7 @@ using HetsData.Model; using Hangfire.Server; using Hangfire.Console; +using HetsApi.Helpers; namespace HetsData.Helpers { @@ -419,7 +420,7 @@ public static int GetNumberOfBlocks(HetEquipment item, IConfiguration configurat /// /// /// - public static float GetYtdServiceHours(int id, DbAppContext context, DateTime? rolloverDate = null) + public static float GetYtdServiceHours(int id, DbAppContext context) { float result = 0.0F; @@ -434,9 +435,17 @@ public static float GetYtdServiceHours(int id, DbAppContext context, DateTime? r HetDistrictStatus district = context.HetDistrictStatus.AsNoTracking() .First(x => x.DistrictId == equipment.LocalArea.ServiceArea.DistrictId); - if (district?.NextFiscalYear == null) throw new ArgumentException("Error retrieving district status record"); + var fiscalYear = DateTime.Today.Year; + + if (district?.NextFiscalYear == null) + { + fiscalYear = FiscalHelper.GetCurrentFiscalStartYear() + 1; + } + else + { + fiscalYear = (int)district.NextFiscalYear; // status table uses the start of the year + } - int fiscalYear = (int)district.NextFiscalYear; // status table uses the start of the year DateTime fiscalEnd = new DateTime(fiscalYear, 3, 31); DateTime fiscalStart = new DateTime(fiscalYear - 1, 4, 1); @@ -492,11 +501,11 @@ public static void RecalculateSeniority(int? localAreaId, int? districtEquipment if (!exists) throw new ArgumentException("District Equipment Type is invalid"); // get the local area - HetLocalArea localArea = context.HetLocalArea.AsNoTracking() + HetLocalArea localArea = context.HetLocalArea .First(a => a.LocalAreaId == localAreaId); // get the equipment type - HetDistrictEquipmentType districtEquipmentType = context.HetDistrictEquipmentType.AsNoTracking() + HetDistrictEquipmentType districtEquipmentType = context.HetDistrictEquipmentType .Include(x => x.EquipmentType) .First(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); diff --git a/Server/HetsData/Helpers/SeniorityListHelper.cs b/Server/HetsData/Helpers/SeniorityListHelper.cs index f2b6e99ba..802401f5d 100644 --- a/Server/HetsData/Helpers/SeniorityListHelper.cs +++ b/Server/HetsData/Helpers/SeniorityListHelper.cs @@ -145,14 +145,12 @@ public static void CalculateSeniorityList(int localAreaId, int districtEquipment equipment.CalculateSeniority(seniorityScoring); equipment.SeniorityEffectiveDate = DateTime.UtcNow; } - - context.HetEquipment.Update(equipment); } - context.SaveChanges(); - // put equipment into the correct blocks - AssignBlocks(localAreaId, districtEquipmentTypeId, blockSize, totalBlocks, context); + AssignBlocks(localAreaId, districtEquipmentTypeId, blockSize, totalBlocks, context, false); + + context.SaveChanges(); } } } @@ -259,8 +257,6 @@ private static bool AddedToBlock(int currentBlock, int totalBlocks, int blockSiz equipment.BlockNumber = currentBlock + 1; equipment.NumberInBlock = blocks[currentBlock].Count; - context.HetEquipment.Update(equipment); - if (saveChanges) { context.SaveChanges(); diff --git a/Server/HetsData/HetsData.csproj b/Server/HetsData/HetsData.csproj index b75e55f4b..597efa04b 100644 --- a/Server/HetsData/HetsData.csproj +++ b/Server/HetsData/HetsData.csproj @@ -17,6 +17,10 @@ + + + + ..\..\..\..\..\Users\paulm\.nuget\packages\hangfire.core\1.6.20\lib\netstandard1.3\Hangfire.Core.dll diff --git a/client/.gitignore b/client/.gitignore index 4d29575de..800f3a80c 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -10,6 +10,7 @@ # production /build +/dist # misc .DS_Store diff --git a/client/package-lock.json b/client/package-lock.json index f6d9df9a8..ffd1bbe87 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12752,6 +12752,31 @@ } } }, + "react-bootstrap-datetimepicker": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/react-bootstrap-datetimepicker/-/react-bootstrap-datetimepicker-0.0.22.tgz", + "integrity": "sha1-B+RI2ZMVfQSa0IdtD5o8nFAp2cU=", + "requires": { + "babel-runtime": "^5.6.18", + "classnames": "^2.1.2", + "moment": "^2.8.2" + }, + "dependencies": { + "babel-runtime": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz", + "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", + "requires": { + "core-js": "^1.0.0" + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + } + } + }, "react-context-toolbox": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz", diff --git a/client/package.json b/client/package.json index cb10ca48f..bb25ce11b 100644 --- a/client/package.json +++ b/client/package.json @@ -16,6 +16,7 @@ "node-sass": "^4.14.1", "react": "^17.0.2", "react-bootstrap": "^0.32.4", + "react-bootstrap-datetimepicker": "0.0.22", "react-datetime": "^3.0.4", "react-dom": "^16.8.4", "react-hot-loader": "^4.8.0", diff --git a/client/src/sass/components/date-control.scss b/client/src/sass/components/date-control.scss index d1442d37b..cf3d3195c 100644 --- a/client/src/sass/components/date-control.scss +++ b/client/src/sass/components/date-control.scss @@ -1,3 +1,5 @@ +@import "../../../node_modules/react-datetime/css/react-datetime"; + .date-control { .rdt { display: inline; @@ -32,7 +34,7 @@ .btn { color: #a94442; border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } } From a30e9bac196334576fc208777436742cd4d46d1a Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Mon, 7 Jun 2021 10:10:59 -0700 Subject: [PATCH 018/352] Added rollover progress table --- Db Scripts/UPDATE/RELEASE1.9.3.sql | 18 ++++ Server/HetsApi/Startup.cs | 1 + Server/HetsData/Model/BcbidRotationDoc.cs | 33 ------ Server/HetsData/Model/DbAppContext.cs | 106 ++++--------------- Server/HetsData/Model/DbAppMonitorContext.cs | 12 +++ Server/HetsData/Model/HetRolloverProgress.cs | 13 +++ Server/HetsData/Scaffold.txt | 5 +- 7 files changed, 69 insertions(+), 119 deletions(-) create mode 100644 Db Scripts/UPDATE/RELEASE1.9.3.sql delete mode 100644 Server/HetsData/Model/BcbidRotationDoc.cs create mode 100644 Server/HetsData/Model/DbAppMonitorContext.cs create mode 100644 Server/HetsData/Model/HetRolloverProgress.cs diff --git a/Db Scripts/UPDATE/RELEASE1.9.3.sql b/Db Scripts/UPDATE/RELEASE1.9.3.sql new file mode 100644 index 000000000..1baabf537 --- /dev/null +++ b/Db Scripts/UPDATE/RELEASE1.9.3.sql @@ -0,0 +1,18 @@ +CREATE TABLE public."HET_ROLLOVER_PROGRESS" +( + "DISTRICT_ID" integer, + "PROGRESS_PERCENTAGE" integer +); + +CREATE UNIQUE INDEX "HET_ROLLOVER_PROGRESS_UK" ON public."HET_ROLLOVER_PROGRESS" +("DISTRICT_ID") TABLESPACE pg_default; + +ALTER TABLE "HET_ROLLOVER_PROGRESS" ADD CONSTRAINT "HET_ROLLOVER_PROGRESS_UK" UNIQUE +USING INDEX "HET_ROLLOVER_PROGRESS_UK"; + +ALTER TABLE ONLY public."HET_ROLLOVER_PROGRESS" +ADD CONSTRAINT "FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID" FOREIGN KEY +("DISTRICT_ID") REFERENCES public."HET_DISTRICT" +("DISTRICT_ID"); + +GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public."HET_ROLLOVER_PROGRESS" TO het_application_proxy; diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index a563ed549..463eb46bb 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -47,6 +47,7 @@ public void ConfigureServices(IServiceCollection services) // add database context services.AddDbContext(options => options.UseNpgsql(connectionString)); + services.AddDbContext(options => options.UseNpgsql(connectionString)); services.AddScoped(); services diff --git a/Server/HetsData/Model/BcbidRotationDoc.cs b/Server/HetsData/Model/BcbidRotationDoc.cs deleted file mode 100644 index b9543dbac..000000000 --- a/Server/HetsData/Model/BcbidRotationDoc.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace HetsData.Model -{ - public partial class BcbidRotationDoc - { - [JsonProperty("Id")] - public int NoteId { get; set; } - - public string NoteType { get; set; } - public string Reason { get; set; } - public DateTime AskedDate { get; set; } - public bool? WasAsked { get; set; } - public string OfferRefusalReason { get; set; } - public bool? IsForceHire { get; set; } - public int? EquipmentId { get; set; } - public int? ProjectId { get; set; } - [JsonIgnore]public string AppCreateUserDirectory { get; set; } - [JsonIgnore]public string AppCreateUserGuid { get; set; } - [JsonIgnore]public string AppCreateUserid { get; set; } - [JsonIgnore]public DateTime AppCreateTimestamp { get; set; } - [JsonIgnore]public string AppLastUpdateUserDirectory { get; set; } - [JsonIgnore]public string AppLastUpdateUserGuid { get; set; } - [JsonIgnore]public string AppLastUpdateUserid { get; set; } - [JsonIgnore]public DateTime AppLastUpdateTimestamp { get; set; } - [JsonIgnore]public string DbCreateUserId { get; set; } - [JsonIgnore]public DateTime DbCreateTimestamp { get; set; } - [JsonIgnore]public DateTime DbLastUpdateTimestamp { get; set; } - [JsonIgnore]public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/DbAppContext.cs b/Server/HetsData/Model/DbAppContext.cs index 65cd6ed1c..1145c7c14 100644 --- a/Server/HetsData/Model/DbAppContext.cs +++ b/Server/HetsData/Model/DbAppContext.cs @@ -21,7 +21,6 @@ public DbAppContext(string connectionString) } public virtual DbSet HetBatchReport { get; set; } - public virtual DbSet BcbidRotationDoc { get; set; } public virtual DbSet HetBusiness { get; set; } public virtual DbSet HetBusinessUser { get; set; } public virtual DbSet HetBusinessUserRole { get; set; } @@ -67,6 +66,7 @@ public DbAppContext(string connectionString) public virtual DbSet HetRentalRequestStatusType { get; set; } public virtual DbSet HetRole { get; set; } public virtual DbSet HetRolePermission { get; set; } + public virtual DbSet HetRolloverProgress { get; set; } public virtual DbSet HetSeniorityAudit { get; set; } public virtual DbSet HetServiceArea { get; set; } public virtual DbSet HetTimePeriodType { get; set; } @@ -167,90 +167,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); }); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.NoteId); - - entity.ToTable("BCBID_ROTATION_DOC"); - - entity.Property(e => e.NoteId) - .HasColumnName("NOTE_ID"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasColumnName("APP_CREATE_USER_DIRECTORY") - .HasMaxLength(50); - - entity.Property(e => e.AppCreateUserGuid) - .HasColumnName("APP_CREATE_USER_GUID") - .HasMaxLength(255); - - entity.Property(e => e.AppCreateUserid) - .HasColumnName("APP_CREATE_USERID") - .HasMaxLength(255); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY") - .HasMaxLength(50); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasColumnName("APP_LAST_UPDATE_USER_GUID") - .HasMaxLength(255); - - entity.Property(e => e.AppLastUpdateUserid) - .HasColumnName("APP_LAST_UPDATE_USERID") - .HasMaxLength(255); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasColumnName("DB_CREATE_USER_ID") - .HasMaxLength(63); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasColumnName("DB_LAST_UPDATE_USER_ID") - .HasMaxLength(63); - - entity.Property(e => e.NoteType) - .HasColumnName("NOTE_TYPE") - .HasMaxLength(255); - - entity.Property(e => e.Reason) - .HasColumnName("REASON") - .HasMaxLength(255); - - entity.Property(e => e.AskedDate) - .HasColumnName("ASKED_DATE_TIME") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.WasAsked).HasColumnName("WAS_ASKED"); - - entity.Property(e => e.OfferRefusalReason) - .HasColumnName("OFFER_REFUSAL_REASON") - .HasMaxLength(50); - - entity.Property(e => e.IsForceHire).HasColumnName("IS_FORCE_HIRE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - }); - modelBuilder.Entity(entity => { entity.HasKey(e => e.BusinessId); @@ -4644,6 +4560,26 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasConstraintName("FK_HET_ROLE_PERMISSION_ROLE_ID"); }); + modelBuilder.Entity(entity => + { + entity.HasNoKey(); + + entity.ToTable("HET_ROLLOVER_PROGRESS"); + + entity.HasIndex(e => e.DistrictId) + .HasName("HET_ROLLOVER_PROGRESS_UK") + .IsUnique(); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); + + entity.HasOne(d => d.District) + .WithOne() + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID"); + }); + modelBuilder.Entity(entity => { entity.HasKey(e => e.SeniorityAuditId); diff --git a/Server/HetsData/Model/DbAppMonitorContext.cs b/Server/HetsData/Model/DbAppMonitorContext.cs new file mode 100644 index 000000000..4ceda8bf8 --- /dev/null +++ b/Server/HetsData/Model/DbAppMonitorContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; + +namespace HetsData.Model +{ + public partial class DbAppMonitorContext : DbAppContext + { + public DbAppMonitorContext(DbContextOptions options) + : base(options) + { + } + } +} diff --git a/Server/HetsData/Model/HetRolloverProgress.cs b/Server/HetsData/Model/HetRolloverProgress.cs new file mode 100644 index 000000000..5ab594f78 --- /dev/null +++ b/Server/HetsData/Model/HetRolloverProgress.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace HetsData.Model +{ + public partial class HetRolloverProgress + { + public int? DistrictId { get; set; } + public int? ProgressPercentage { get; set; } + + public virtual HetDistrict District { get; set; } + } +} diff --git a/Server/HetsData/Scaffold.txt b/Server/HetsData/Scaffold.txt index 9ce1d0cc6..62259b78d 100644 --- a/Server/HetsData/Scaffold.txt +++ b/Server/HetsData/Scaffold.txt @@ -7,10 +7,13 @@ Remove Hangfire tables and sequences before scaffolding the db ******************************************** Step 2: Generate / Update Model: ******************************************** -Scaffold-DbContext "Host=localhost;Username=trdbhetd;Password=IhUFdcC0wGJeIMDJ;Database=hets" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" +Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" For a specific table(s) only: +Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -t public.HET_ROLLOVER_PROGRESS -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" + + Scaffold-DbContext "Host=localhost;Username=trdbhetd;Password=IhUFdcC0wGJeIMDJ;Database=hets" Npgsql.EntityFrameworkCore.PostgreSQL -t public.HET_BUSINESS -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" Scaffold-DbContext "Host=localhost;Username=trdbhetd;Password=IhUFdcC0wGJeIMDJ;Database=hets" Npgsql.EntityFrameworkCore.PostgreSQL -t public.HET_BUSINESS_USER_ROLE -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" From c4198a2da599e550b33d301270610dcbd9693d4d Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Mon, 7 Jun 2021 14:59:50 -0700 Subject: [PATCH 019/352] Annual Rollover rewrite --- Db Scripts/UPDATE/RELEASE1.9.3.sql | 8 +- .../HetsApi/Controllers/DistrictController.cs | 109 +++-- Server/HetsApi/Startup.cs | 11 +- Server/HetsData/Hangfire/AnnualRollover.cs | 103 ++++- .../HetsData/Helpers/AnnualRolloverHelper.cs | 395 ------------------ Server/HetsData/Model/DbAppContext.cs | 13 +- Server/HetsData/Model/HetDistrict.cs | 3 + Server/HetsData/View/RolloverProgressDto.cs | 8 + client/src/js/api.js | 2 +- 9 files changed, 163 insertions(+), 489 deletions(-) delete mode 100644 Server/HetsData/Helpers/AnnualRolloverHelper.cs create mode 100644 Server/HetsData/View/RolloverProgressDto.cs diff --git a/Db Scripts/UPDATE/RELEASE1.9.3.sql b/Db Scripts/UPDATE/RELEASE1.9.3.sql index 1baabf537..4fea71a98 100644 --- a/Db Scripts/UPDATE/RELEASE1.9.3.sql +++ b/Db Scripts/UPDATE/RELEASE1.9.3.sql @@ -4,11 +4,9 @@ CREATE TABLE public."HET_ROLLOVER_PROGRESS" "PROGRESS_PERCENTAGE" integer ); -CREATE UNIQUE INDEX "HET_ROLLOVER_PROGRESS_UK" ON public."HET_ROLLOVER_PROGRESS" -("DISTRICT_ID") TABLESPACE pg_default; - -ALTER TABLE "HET_ROLLOVER_PROGRESS" ADD CONSTRAINT "HET_ROLLOVER_PROGRESS_UK" UNIQUE -USING INDEX "HET_ROLLOVER_PROGRESS_UK"; +ALTER TABLE ONLY public."HET_ROLLOVER_PROGRESS" +ADD CONSTRAINT "PK_HET_ROLLOVER_PROGRESS" PRIMARY KEY +("DISTRICT_ID"); ALTER TABLE ONLY public."HET_ROLLOVER_PROGRESS" ADD CONSTRAINT "FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID" FOREIGN KEY diff --git a/Server/HetsApi/Controllers/DistrictController.cs b/Server/HetsApi/Controllers/DistrictController.cs index c1178c742..418b710f8 100644 --- a/Server/HetsApi/Controllers/DistrictController.cs +++ b/Server/HetsApi/Controllers/DistrictController.cs @@ -12,9 +12,12 @@ using HetsApi.Authorization; using HetsApi.Helpers; using HetsApi.Model; -using HetsData.Helpers; +using HetsData.View; using HetsData.Model; using HetsData.Hangfire; +using Hangfire.Storage; +using Newtonsoft.Json; +using Hangfire.Common; namespace HetsApi.Controllers { @@ -29,12 +32,14 @@ public class DistrictController : Controller private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly IAnnualRollover _annualRollover; + private IMonitoringApi _monitoringApi; public DistrictController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IAnnualRollover annualRollover) { _context = context; _configuration = configuration; _annualRollover = annualRollover; + _monitoringApi = JobStorage.Current.GetMonitoringApi(); // set context data User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); @@ -127,15 +132,44 @@ public virtual IActionResult DistrictLocalAreasGet([FromRoute]int id) [RequiresPermission(HetPermission.Login)] public virtual IActionResult RolloverStatusGet([FromRoute]int id) { - bool exists = _context.HetDistrict.Any(a => a.DistrictId == id); + var typeFullName = "HetsData.Hangfire.AnnualRollover"; + var methodName = "AnnualRolloverJob"; + var rolloverJob = $"{typeFullName}-{methodName}-{id}"; + + var jobProcessing = _monitoringApi.ProcessingJobs(0, 10000) + .ToList(); + + var jobExists = jobProcessing.Any(x => GetJobFingerprint(x.Value.Job) == rolloverJob); + + var status = _annualRollover.GetRecord(id); + + var progress = _context.HetRolloverProgress.FirstOrDefault(a => a.DistrictId == id); // not found - if (!exists) return new NotFoundObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration))); + if (progress == null) return new ObjectResult(new HetsResponse(new RolloverProgressDto { DistrictId = id, ProgressPercentage = null })); + + if (!jobExists) + { + return new ObjectResult(new HetsResponse(new RolloverProgressDto { DistrictId = id, ProgressPercentage = status.ProgressPercentage })); + } // get status of current district - return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); + return new ObjectResult(new HetsResponse(new RolloverProgressDto { DistrictId = id, ProgressPercentage = progress.ProgressPercentage })); + } + + private string GetJobFingerprint(Job job) + { + var args = ""; + + if (job.Args.Count > 0) + { + args = job.Args[0].ToString(); + } + + return $"{job.Type.FullName}-{job.Method.Name}-{args}"; } + /// /// Dismiss district rollover status message /// @@ -149,7 +183,7 @@ public virtual IActionResult DismissRolloverMessagePost([FromRoute]int id) bool exists = _context.HetDistrictStatus.Any(a => a.DistrictId == id); // not found - return new status record - if (!exists) return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); + if (!exists) return NotFound(); // get record and update HetDistrictStatus status = _context.HetDistrictStatus @@ -163,10 +197,14 @@ public virtual IActionResult DismissRolloverMessagePost([FromRoute]int id) { status.ProgressPercentage = null; status.DisplayRolloverMessage = false; - - _context.SaveChanges(); } + var progress = _context.HetRolloverProgress.FirstOrDefault(a => a.DistrictId == id); + + progress.ProgressPercentage = null; + + _context.SaveChanges(); + // get status of current district return new ObjectResult(new HetsResponse(_annualRollover.GetRecord(id))); } @@ -222,65 +260,12 @@ public virtual IActionResult AnnualRolloverGet([FromRoute]int id) IConfigurationSection scoringRules = _configuration.GetSection("SeniorityScoringRules"); string seniorityScoringRules = GetConfigJson(scoringRules); - // get connection string - string connectionString = GetConnectionString(); - // queue the job //BackgroundJob.Enqueue(() => AnnualRolloverHelper.AnnualRolloverJob(null, id, seniorityScoringRules, connectionString)); BackgroundJob.Enqueue(x => x.AnnualRolloverJob(id, seniorityScoringRules)); + var progressDto = _annualRollover.KickoffProgress(id); - // get counts for this district - int localAreaCount = _context.HetLocalArea - .Count(a => a.ServiceArea.DistrictId == id); - - int equipmentCount = _context.HetDistrictEquipmentType - .Count(a => a.DistrictId == id); - - // update status - job is kicked off - status.LocalAreaCount = localAreaCount; - status.DistrictEquipmentTypeCount = equipmentCount; - status.ProgressPercentage = 1; - status.DisplayRolloverMessage = true; - - _context.HetDistrictStatus.Update(status); - _context.SaveChanges(); - - return new ObjectResult(status); - } - - #endregion - - #region Get Database Connection String - - /// - /// Retrieve database connection string - /// - /// - private string GetConnectionString() - { - string connectionString; - - lock (_thisLock) - { - string host = _configuration["DATABASE_SERVICE_NAME"]; - string username = _configuration["POSTGRESQL_USER"]; - string password = _configuration["POSTGRESQL_PASSWORD"]; - string database = _configuration["POSTGRESQL_DATABASE"]; - - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || - string.IsNullOrEmpty(database)) - { - // When things get cleaned up properly, this is the only call we'll have to make. - connectionString = _configuration.GetConnectionString("HETS"); - } - else - { - // Environment variables override all other settings; same behaviour as the configuration provider when things get cleaned up. - connectionString = $"Host={host};Username={username};Password={password};Database={database};"; - } - } - - return connectionString; + return new ObjectResult(progressDto); } #endregion diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 463eb46bb..636de7a00 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -126,15 +126,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) builder.UseExceptionHandler(Configuration.GetSection("Constants:ErrorUrl").Value); }); - - // enable Hangfire - BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions - { - WorkerCount = 1 - }; - - app.UseHangfireServer(jsOptions); - // disable the back to site link DashboardOptions dashboardOptions = new DashboardOptions { @@ -142,6 +133,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) Authorization = new[] { new HangfireAuthorizationFilter() } }; + app.UseHangfireDashboard(Configuration.GetSection("Constants:HangfireUrl").Value, dashboardOptions); + //app.UseHealthChecks("/healthz", healthCheckOptions); app.UseRouting(); diff --git a/Server/HetsData/Hangfire/AnnualRollover.cs b/Server/HetsData/Hangfire/AnnualRollover.cs index 5b137effe..6023e0bb8 100644 --- a/Server/HetsData/Hangfire/AnnualRollover.cs +++ b/Server/HetsData/Hangfire/AnnualRollover.cs @@ -2,6 +2,7 @@ using HetsApi.Helpers; using HetsData.Helpers; using HetsData.Model; +using HetsData.View; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; @@ -13,18 +14,19 @@ public interface IAnnualRollover { public HetDistrictStatus GetRecord(int id); public void AnnualRolloverJob(int districtId, string seniorityScoringRules); + public RolloverProgressDto KickoffProgress(int districtId); } public class AnnualRollover : IAnnualRollover { private DbAppContext _dbContextMain; - private DbAppContext _dbContextSub; + private DbAppMonitorContext _dbContextMonitor; private string _jobId; - public AnnualRollover(DbAppContext dbContextMain, DbAppContext dbContextSub) + public AnnualRollover(DbAppContext dbContextMain, DbAppMonitorContext dbContextMonitor) { _dbContextMain = dbContextMain; - _dbContextSub = dbContextSub; + _dbContextMonitor = dbContextMonitor; _jobId = Guid.NewGuid().ToString(); } @@ -54,8 +56,6 @@ public HetDistrictStatus GetRecord(int id) NextFiscalYear = rolloverYear, DisplayRolloverMessage = false }; - - _dbContextMain.HetDistrictStatus.Add(status); } return status; @@ -96,7 +96,7 @@ public void AnnualRolloverJob(int districtId, string seniorityScoringRules) WriteLog("Starting - District #" + district.DistrictNumber); // get status record - and ensure we're active - HetDistrictStatus status = GetRecord(districtId); + HetDistrictStatus status = GetStatus(districtId); if (status == null) { @@ -194,18 +194,21 @@ public void AnnualRolloverJob(int districtId, string seniorityScoringRules) // increment counters and update status equipmentCompleteCount++; - WriteLog($"Equipment Type ({equipmentCompleteCount}/{equipmentTypes.Count}"); + WriteLog($"Equipment Type ({equipmentCompleteCount}/{equipmentTypes.Count})"); } // increment counters and update status localAreaCompleteCount++; - WriteLog($"Local Area ({localAreaCompleteCount}/{localAreas.Count}"); + UpdateProgress(districtId, localAreaCompleteCount, localAreas.Count); + WriteLog($"Local Area ({localAreaCompleteCount}/{localAreas.Count})"); } // done! UpdateStatusComplete(status, localAreaCompleteCount, equipmentCompleteCount); _dbContextMain.SaveChanges(); //commit; - WriteLog("Save Completed"); + UpdateProgress(districtId, 0, 0, true); + + WriteLog("Rollover Save Completed"); // ********************************************************** // regenerate Owner Secret Keys for this district @@ -239,7 +242,7 @@ public void AnnualRolloverJob(int districtId, string seniorityScoringRules) HetOwner ownerRecord = _dbContextMain.HetOwner.First(x => x.OwnerId == owner.OwnerId); ownerRecord.SharedKey = key; - WriteLog($"Owner {i}/{ownerCount}"); + WriteLog($"Owner ({i}/{ownerCount})"); } // save remaining updates - done! @@ -266,6 +269,86 @@ private void UpdateStatusComplete(HetDistrictStatus status, int localAreaComplet status.DisplayRolloverMessage = true; } + private void UpdateProgress(int districtId, int localAreaCompleteCount, int localAreaCount, bool finished = false) + { + decimal percentage = localAreaCount == 0 ? 80 : Convert.ToDecimal(localAreaCompleteCount) / Convert.ToDecimal(localAreaCount) * 80; + + if (finished) percentage = 100; + + try + { + var progress = _dbContextMonitor.HetRolloverProgress.FirstOrDefault(x => x.DistrictId == districtId); + if (progress == null) + { + progress = new HetRolloverProgress { DistrictId = districtId, ProgressPercentage = (int?)percentage }; + _dbContextMonitor.Add(progress); + } + else + { + progress.ProgressPercentage = (int?)percentage; + } + + _dbContextMonitor.SaveChanges(); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + public RolloverProgressDto KickoffProgress(int districtId) + { + try + { + var progress = _dbContextMonitor.HetRolloverProgress.FirstOrDefault(x => x.DistrictId == districtId); + + if (progress == null) + { + progress = new HetRolloverProgress { DistrictId = districtId, ProgressPercentage = (int?)0 }; + _dbContextMonitor.HetRolloverProgress.Add(progress); + } + else + { + progress.ProgressPercentage = (int?)0; + } + + _dbContextMonitor.SaveChanges(); + + return new RolloverProgressDto { DistrictId = districtId, ProgressPercentage = 0 }; + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } + + private HetDistrictStatus GetStatus(int id) + { + HetDistrictStatus status = _dbContextMain.HetDistrictStatus + .Include(a => a.District) + .FirstOrDefault(a => a.DistrictId == id); + + // if there isn't a status - we'll add one now + if (status == null) + { + var rolloverYear = FiscalHelper.GetCurrentFiscalStartYear(); + + status = new HetDistrictStatus + { + DistrictId = id, + CurrentFiscalYear = rolloverYear - 1, + NextFiscalYear = rolloverYear, + DisplayRolloverMessage = false + }; + + _dbContextMain.HetDistrictStatus.Add(status); + } + + return status; + } + private void WriteLog(string message) { Console.WriteLine($"Annual Rollover[{_jobId}] {message}"); diff --git a/Server/HetsData/Helpers/AnnualRolloverHelper.cs b/Server/HetsData/Helpers/AnnualRolloverHelper.cs deleted file mode 100644 index 41fbd2525..000000000 --- a/Server/HetsData/Helpers/AnnualRolloverHelper.cs +++ /dev/null @@ -1,395 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Hangfire.Console; -using Hangfire.Server; -using Hangfire.Console.Progress; -using Microsoft.EntityFrameworkCore; -using HetsData.Model; - -namespace HetsData.Helpers -{ - ///// - ///// Annual Rollover List Helper - ///// - //public static class AnnualRolloverHelper - //{ - // #region Get a District Status record - - // /// - // /// Get a District Status record - // /// - // /// - // /// - // /// - // public static HetDistrictStatus GetRecord(int id, DbAppContext context) - // { - // HetDistrictStatus status = context.HetDistrictStatus.AsNoTracking() - // .Include(a => a.District) - // .FirstOrDefault(a => a.DistrictId == id); - - // // if there isn't a status - we'll add one now - // if (status == null) - // { - // // ******************************************************************************* - // // determine current fiscal year - check for existing rotation lists this year - // // ******************************************************************************* - // DateTime fiscalStart; - - // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - // { - // fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); - // } - // else - // { - // fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); - // } - - // status = new HetDistrictStatus - // { - // DistrictId = id, - // CurrentFiscalYear = fiscalStart.Year, - // NextFiscalYear = fiscalStart.Year + 1, - // DisplayRolloverMessage = false - // }; - - // context.HetDistrictStatus.Add(status); - // context.SaveChanges(); - - // // get updated record - // status = context.HetDistrictStatus.AsNoTracking() - // .Include(a => a.District) - // .First(a => a.DistrictId == id); - // } - - // return status; - // } - - // #endregion - - // #region Annual Rollover Process - - // /// - // /// Annual Rollover - // /// - // /// - // /// - // /// - // /// - // public static void AnnualRolloverJob(PerformContext context, int districtId, string seniorityScoringRules, string connectionString) - // { - // try - // { - // // open a connection to the database - // DbAppContext dbContext = new DbAppContext(connectionString); - - // // get processing rules - // SeniorityScoringRules scoringRules = new SeniorityScoringRules(seniorityScoringRules); - - // // update progress bar - // IProgressBar progress = context.WriteProgressBar(); - // context.WriteLine("Starting Annual Rollover Job - District #" + districtId); - - // progress.SetValue(0); - - // // validate district id - // HetDistrict district = dbContext.HetDistrict.AsNoTracking() - // .FirstOrDefault(x => x.DistrictId == districtId); - - // if (district == null) - // { - // context.WriteLine("District not found"); - // progress.SetValue(100); - // return; - // } - - // // get status record - and ensure we're active - // HetDistrictStatus status = GetRecord(districtId, dbContext); - - // if (status == null) - // { - // context.WriteLine("District Status not found"); - // progress.SetValue(100); - // return; - // } - - // // get equipment status - // int? statusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); - // if (statusId == null) - // { - // context.WriteLine("Equipment Status not found"); - // progress.SetValue(100); - // return; - // } - - // // determine the "Rollover Date" (required for testing) - // DateTime rolloverDate; - - // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - // { - // if (status.NextFiscalYear == null) status.NextFiscalYear = DateTime.UtcNow.Year; - - // rolloverDate = new DateTime((int)status.NextFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); - // } - // else - // { - // if (status.CurrentFiscalYear == null) status.CurrentFiscalYear = DateTime.UtcNow.Year; - - // rolloverDate = new DateTime((int)status.CurrentFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); - // } - - // // get all district equipment types - // List equipmentTypes = dbContext.HetDistrictEquipmentType.AsNoTracking() - // .Include(x => x.EquipmentType) - // .Where(x => x.DistrictId == districtId).ToList(); - - // // get all local areas - // List localAreas = dbContext.HetLocalArea.AsNoTracking() - // .Where(a => a.ServiceArea.DistrictId == districtId).ToList(); - - // // update status - job is kicked off - // int localAreaCompleteCount = 0; - // int equipmentCompleteCount = 0; - - // UpdateStatusKickoff(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - - // // process all local areas and equipment types - // foreach (HetLocalArea localArea in localAreas.WithProgress(progress)) - // { - // // re-open the connection - // dbContext = new DbAppContext(connectionString); - - // if (localArea.Name != null) - // { - // context.WriteLine("Local Area: " + localArea.Name); - // } - // else - // { - // context.WriteLine("Local Area ID: " + localArea.LocalAreaId); - // } - - // // reset equipment counter - // equipmentCompleteCount = 0; - - // foreach (HetDistrictEquipmentType equipmentType in equipmentTypes) - // { - // // it this a dump truck? - // bool isDumpTruck = equipmentType.EquipmentType.IsDumpTruck; - - // // get rules for scoring and seniority block - // int seniorityScoring = isDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); - // int blockSize = isDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); - // int totalBlocks = isDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); - - // using (DbAppContext etContext = new DbAppContext(connectionString)) - // { - // List data = etContext.HetEquipment - // .Include(x => x.LocalArea) - // .Include(x => x.DistrictEquipmentType.EquipmentType) - // .Where(x => x.EquipmentStatusTypeId == statusId && - // x.LocalAreaId == localArea.LocalAreaId && - // x.DistrictEquipmentTypeId == equipmentType.DistrictEquipmentTypeId) - // .ToList(); - - // foreach (HetEquipment equipment in data) - // { - // // rollover the year - // equipment.ServiceHoursThreeYearsAgo = equipment.ServiceHoursTwoYearsAgo; - // equipment.ServiceHoursTwoYearsAgo = equipment.ServiceHoursLastYear; - // equipment.ServiceHoursLastYear = EquipmentHelper.GetYtdServiceHours(equipment.EquipmentId, dbContext); - // equipment.CalculateYearsOfService(DateTime.UtcNow); - - // // blank out the override reason - // equipment.SeniorityOverrideReason = ""; - - // // update the seniority score - // equipment.CalculateSeniority(seniorityScoring); - - // etContext.HetEquipment.Update(equipment); - // etContext.SaveChanges(); - // } - // } - - // // now update the rotation list - // using (DbAppContext abContext = new DbAppContext(connectionString)) - // { - // int localAreaId = localArea.LocalAreaId; - // int equipmentTypeId = equipmentType.DistrictEquipmentTypeId; - - // SeniorityListHelper.AssignBlocks(localAreaId, equipmentTypeId, blockSize, totalBlocks, abContext); - // } - - // // increment counters and update status - // equipmentCompleteCount++; - // UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - // } - - // // increment counters and update status - // localAreaCompleteCount++; - // UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - // if (status.ProgressPercentage != null) progress.SetValue((int)status.ProgressPercentage); - // } - - // // done! - // UpdateStatusComplete(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); - // progress.SetValue(100); - - // // ********************************************************** - // // regenerate Owner Secret Keys for this district - // // ********************************************************** - // dbContext = new DbAppContext(connectionString); - - // context.WriteLine(""); - // context.WriteLine("Generate New Secret Keys - District #" + districtId); - // progress = context.WriteProgressBar(); - - // progress.SetValue(0); - // // get records - // List owners = dbContext.HetOwner.AsNoTracking() - // .Where(x => x.BusinessId == null && - // x.LocalArea.ServiceArea.DistrictId == districtId) - // .ToList(); - - // int i = 0; - // int ownerCount = owners.Count; - - // foreach (HetOwner owner in owners) - // { - // i++; - // string key = SecretKeyHelper.RandomString(8, owner.OwnerId); - - // string temp = owner.OwnerCode; - - // if (string.IsNullOrEmpty(temp)) - // { - // temp = SecretKeyHelper.RandomString(4, owner.OwnerId); - // } - - // key = temp + "-" + (rolloverDate.Year + 1) + "-" + key; - - // // get owner and update - // HetOwner ownerRecord = dbContext.HetOwner.First(x => x.OwnerId == owner.OwnerId); - // ownerRecord.SharedKey = key; - // dbContext.HetOwner.Update(ownerRecord); - - // decimal tempProgress = Convert.ToDecimal(i) / Convert.ToDecimal(ownerCount); - // tempProgress = tempProgress * 100; - // int percentComplete = Convert.ToInt32(tempProgress); - - // if (percentComplete < 1) percentComplete = 1; - // if (percentComplete > 99) percentComplete = 100; - - // progress.SetValue(percentComplete); - // } - - // // save remaining updates - done! - // dbContext.SaveChangesForImport(); - // progress.SetValue(100); - // context.WriteLine("Generate New Secret Keys - Done"); - // } - // catch (Exception e) - // { - // Console.WriteLine(e); - // throw; - // } - // } - - // private static void UpdateStatus(DbAppContext dbContext, HetDistrictStatus status, - // int localAreaCompleteCount, int equipmentCompleteCount) - // { - // try - // { - // int localAreaCount = status.LocalAreaCount ?? 0; - // int equipmentCount = status.DistrictEquipmentTypeCount ?? 0; - // int percentComplete; - - // if (localAreaCount == 0 && - // equipmentCount == 0) - // { - // percentComplete = 100; - // } - // else - // { - // // (current / maximum) * 100 -> just using the local area - // decimal temp = Convert.ToDecimal(localAreaCompleteCount) / Convert.ToDecimal(localAreaCount); - // temp = temp * 100; - // percentComplete = Convert.ToInt32(temp); - - // if (percentComplete < 1) percentComplete = 1; - // if (percentComplete > 99) percentComplete = 100; - // } - - // status.LocalAreaCompleteCount = localAreaCompleteCount; - // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - // status.ProgressPercentage = percentComplete; - // status.DisplayRolloverMessage = true; - - // dbContext.HetDistrictStatus.Update(status); - // dbContext.SaveChanges(); - // } - // catch (Exception e) - // { - // Console.WriteLine(e); - // throw; - // } - // } - - // private static void UpdateStatusKickoff(DbAppContext dbContext, HetDistrictStatus status, - // int localAreaCompleteCount, int equipmentCompleteCount) - // { - // try - // { - // status.LocalAreaCompleteCount = localAreaCompleteCount; - // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - // status.ProgressPercentage = 1; - // status.RolloverStartDate = DateTime.UtcNow; - // status.DisplayRolloverMessage = true; - - // dbContext.HetDistrictStatus.Update(status); - // dbContext.SaveChanges(); - // } - // catch (Exception e) - // { - // Console.WriteLine(e); - // throw; - // } - // } - - // private static void UpdateStatusComplete(DbAppContext dbContext, HetDistrictStatus status, - // int localAreaCompleteCount, int equipmentCompleteCount) - // { - // try - // { - // // determine the current fiscal year - // DateTime fiscalStart; - - // if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) - // { - // fiscalStart = new DateTime(DateTime.UtcNow.AddYears(-1).Year, 4, 1); - // } - // else - // { - // fiscalStart = new DateTime(DateTime.UtcNow.Year, 4, 1); - // } - - // status.LocalAreaCompleteCount = localAreaCompleteCount; - // status.DistrictEquipmentTypeCompleteCount = equipmentCompleteCount; - // status.ProgressPercentage = 100; - // status.RolloverEndDate = DateTime.UtcNow; - // status.CurrentFiscalYear = fiscalStart.Year; - // status.NextFiscalYear = fiscalStart.Year + 1; - // status.DisplayRolloverMessage = true; - - // dbContext.HetDistrictStatus.Update(status); - // dbContext.SaveChanges(); - // } - // catch (Exception e) - // { - // Console.WriteLine(e); - // throw; - // } - // } - - // #endregion - //} -} diff --git a/Server/HetsData/Model/DbAppContext.cs b/Server/HetsData/Model/DbAppContext.cs index 1145c7c14..b66cb3e21 100644 --- a/Server/HetsData/Model/DbAppContext.cs +++ b/Server/HetsData/Model/DbAppContext.cs @@ -4562,21 +4562,20 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasNoKey(); + entity.HasKey(e => e.DistrictId); entity.ToTable("HET_ROLLOVER_PROGRESS"); - entity.HasIndex(e => e.DistrictId) - .HasName("HET_ROLLOVER_PROGRESS_UK") - .IsUnique(); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + entity.Property(e => e.DistrictId) + .HasColumnName("DISTRICT_ID") + .ValueGeneratedNever(); entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); entity.HasOne(d => d.District) - .WithOne() + .WithOne(p => p.HetRolloverProgress) .HasForeignKey(d => d.DistrictId) + .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID"); }); diff --git a/Server/HetsData/Model/HetDistrict.cs b/Server/HetsData/Model/HetDistrict.cs index da7a9310b..88dba910a 100644 --- a/Server/HetsData/Model/HetDistrict.cs +++ b/Server/HetsData/Model/HetDistrict.cs @@ -50,6 +50,9 @@ public HetDistrict() [JsonIgnore] public ICollection HetDistrictStatus { get; set; } + [JsonIgnore] + public HetRolloverProgress HetRolloverProgress { get; set; } + [JsonIgnore] public ICollection HetDistrictEquipmentType { get; set; } diff --git a/Server/HetsData/View/RolloverProgressDto.cs b/Server/HetsData/View/RolloverProgressDto.cs new file mode 100644 index 000000000..84ed86d19 --- /dev/null +++ b/Server/HetsData/View/RolloverProgressDto.cs @@ -0,0 +1,8 @@ +namespace HetsData.View +{ + public class RolloverProgressDto + { + public int DistrictId { get; set; } + public int? ProgressPercentage { get; set; } + } +} diff --git a/client/src/js/api.js b/client/src/js/api.js index 40695e725..597e63ef7 100644 --- a/client/src/js/api.js +++ b/client/src/js/api.js @@ -2941,7 +2941,6 @@ export function validateOwner(secretKey, postalCode) { //////////////////// function parseRolloverStatus(status) { - status.rolloverInactive = status.progressPercentage == null; status.rolloverActive = status.progressPercentage != null && status.progressPercentage >= 0 && @@ -2953,6 +2952,7 @@ export function getRolloverStatus(districtId) { return new ApiRequest(`/districts/${districtId}/rolloverStatus`) .get(null, { silent: true }) .then((response) => { + console.log(response); var status = response.data; parseRolloverStatus(status); store.dispatch({ From 2a180b0d0792955a1fbd17e2b996be240deb49d6 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 08:38:01 -0700 Subject: [PATCH 020/352] Linq query - explicit client evaluation --- Server/HetsApi/Controllers/EquipmentController.cs | 7 ++++--- Server/HetsApi/Controllers/OwnerController.cs | 10 +++++++--- Server/HetsData/Helpers/EquipmentHelper.cs | 2 +- Server/HetsData/Helpers/OwnerHelper.cs | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index 9cd6d3c03..9feee5740 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -120,23 +120,24 @@ public virtual IActionResult EquipmentGetLiteTs() DateTime fiscalYearStart = new DateTime((int)fiscalYear, 3, 31); // get all active owners for this district (and any projects they're associated with) - IEnumerable equipment = _context.HetRentalAgreement.AsNoTracking() + var equipments = _context.HetRentalAgreement.AsNoTracking() .Include(x => x.Project) .Include(x => x.Equipment) .Where(x => x.Equipment.LocalArea.ServiceArea.DistrictId == districtId && x.Equipment.EquipmentStatusTypeId == statusId && x.Project.DbCreateTimestamp > fiscalYearStart) + .ToList() .GroupBy(x => x.Equipment, (e, agreements) => new EquipmentLiteList { EquipmentCode = e.EquipmentCode, Id = e.EquipmentId, OwnerId = e.OwnerId, LocalAreaId = e.LocalAreaId, - ProjectIds = agreements.Select(y => y.ProjectId).Distinct().ToList(), + ProjectIds = agreements.Select(y => y.ProjectId).Distinct(), DistrictEquipmentTypeId = e.DistrictEquipmentTypeId ?? 0, }); - return new ObjectResult(new HetsResponse(equipment)); + return new ObjectResult(new HetsResponse(equipments)); } /// diff --git a/Server/HetsApi/Controllers/OwnerController.cs b/Server/HetsApi/Controllers/OwnerController.cs index 63408cb22..62673d9e9 100644 --- a/Server/HetsApi/Controllers/OwnerController.cs +++ b/Server/HetsApi/Controllers/OwnerController.cs @@ -136,7 +136,7 @@ public virtual IActionResult OwnersGetLiteHires() if (statusId == null) return new BadRequestObjectResult(new HetsResponse("HETS-23", ErrorViewModel.GetDescription("HETS-23", _configuration))); // get all active owners for this district (and any projects they're associated with) - IEnumerable owners = _context.HetRentalRequestRotationList.AsNoTracking() + var ownerList = _context.HetRentalRequestRotationList.AsNoTracking() .Include(x => x.RentalRequest) .ThenInclude(y => y.LocalArea) .ThenInclude(z => z.ServiceArea) @@ -144,6 +144,9 @@ public virtual IActionResult OwnersGetLiteHires() .Include(x => x.Equipment) .ThenInclude(y => y.Owner) .Where(x => x.RentalRequest.LocalArea.ServiceArea.DistrictId.Equals(districtId)) + .ToList(); + + var owners = ownerList .GroupBy(x => x.Equipment.Owner, (o, rotationLists) => new OwnerLiteProjects { OwnerCode = o.OwnerCode, @@ -184,20 +187,21 @@ public virtual IActionResult OwnersGetLiteTs() DateTime fiscalYearStart = new DateTime((int)fiscalYear, 3, 31); // get all active owners for this district (and any projects they're associated with) - IEnumerable owners = _context.HetRentalAgreement.AsNoTracking() + var owners = _context.HetRentalAgreement.AsNoTracking() .Include(x => x.Project) .Include(x => x.Equipment) .ThenInclude(y => y.Owner) .Where(x => x.Equipment.LocalArea.ServiceArea.DistrictId == districtId && x.Equipment.Owner.OwnerStatusTypeId == statusId && x.Project.AppCreateTimestamp > fiscalYearStart) + .ToList() .GroupBy(x => x.Equipment.Owner, (o, agreements) => new OwnerLiteProjects { OwnerCode = o.OwnerCode, OrganizationName = o.OrganizationName, Id = o.OwnerId, LocalAreaId = o.LocalAreaId, - ProjectIds = agreements.Select(y => y.ProjectId).ToList() + ProjectIds = agreements.Select(y => y.ProjectId) }); return new ObjectResult(new HetsResponse(owners)); diff --git a/Server/HetsData/Helpers/EquipmentHelper.cs b/Server/HetsData/Helpers/EquipmentHelper.cs index 0ba4f7e86..9dad99cc1 100644 --- a/Server/HetsData/Helpers/EquipmentHelper.cs +++ b/Server/HetsData/Helpers/EquipmentHelper.cs @@ -21,7 +21,7 @@ public class EquipmentLiteList public string EquipmentCode { get; set; } public int? OwnerId { get; set; } public int? LocalAreaId { get; set; } - public List ProjectIds { get; set; } + public IEnumerable ProjectIds { get; set; } public int DistrictEquipmentTypeId { get; set; } } diff --git a/Server/HetsData/Helpers/OwnerHelper.cs b/Server/HetsData/Helpers/OwnerHelper.cs index 159c301a5..5ae5841e3 100644 --- a/Server/HetsData/Helpers/OwnerHelper.cs +++ b/Server/HetsData/Helpers/OwnerHelper.cs @@ -57,7 +57,7 @@ public class OwnerLiteProjects public string OwnerCode { get; set; } public string OrganizationName { get; set; } public int? LocalAreaId { get; set; } - public List ProjectIds { get; set; } + public IEnumerable ProjectIds { get; set; } } public class OwnerVerificationPdfViewModel From aea0511af25f8e9d96188d73b317737d85d4da3e Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 08:43:48 -0700 Subject: [PATCH 021/352] Linq - explicit client evalution --- .../Controllers/DistrictEquipmentTypeController.cs | 3 ++- Server/HetsApi/Controllers/EquipmentController.cs | 10 ++++++---- Server/HetsApi/Controllers/OwnerController.cs | 6 ++---- Server/HetsApi/Controllers/ProjectController.cs | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs index 337220ea7..a28caf139 100644 --- a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs +++ b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs @@ -119,10 +119,11 @@ public virtual IActionResult DistrictEquipmentTypesGetAgreementSummary() // get user's district int? districtId = UserAccountHelper.GetUsersDistrictId(_context, HttpContext); - IEnumerable equipmentTypes = _context.HetRentalAgreement.AsNoTracking() + var equipmentTypes = _context.HetRentalAgreement.AsNoTracking() .Include(x => x.Equipment.DistrictEquipmentType) .Where(x => x.DistrictId == districtId && !x.Number.StartsWith("BCBid")) + .ToList() .GroupBy(x => x.Equipment.DistrictEquipmentType, (t, agreements) => new DistrictEquipmentTypeAgreementSummary { Id = t.DistrictEquipmentTypeId, diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index 9feee5740..04c88d100 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -153,10 +153,11 @@ public virtual IActionResult EquipmentGetAgreementSummary() // get user's district int? districtId = UserAccountHelper.GetUsersDistrictId(_context, _httpContext); - IEnumerable equipment = _context.HetRentalAgreement.AsNoTracking() + var equipments = _context.HetRentalAgreement.AsNoTracking() .Include(x => x.Equipment) .Where(x => x.DistrictId == districtId && !x.Number.StartsWith("BCBid")) + .ToList() .GroupBy(x => x.Equipment, (e, agreements) => new EquipmentAgreementSummary { EquipmentCode = e.EquipmentCode, @@ -166,7 +167,7 @@ public virtual IActionResult EquipmentGetAgreementSummary() DistrictEquipmentTypeId = e.DistrictEquipmentTypeId ?? 0, }); - return new ObjectResult(new HetsResponse(equipment)); + return new ObjectResult(new HetsResponse(equipments)); } /// @@ -182,7 +183,7 @@ public virtual IActionResult EquipmentGetLiteHires() // get users district int? districtId = UserAccountHelper.GetUsersDistrictId(_context, _httpContext); - IQueryable equipment = _context.HetRentalRequestRotationList.AsNoTracking() + var equipments = _context.HetRentalRequestRotationList.AsNoTracking() .Include(x => x.RentalRequest) .ThenInclude(y => y.LocalArea) .ThenInclude(z => z.ServiceArea) @@ -190,6 +191,7 @@ public virtual IActionResult EquipmentGetLiteHires() .ThenInclude(y => y.Project) .Include(x => x.Equipment) .Where(x => x.RentalRequest.LocalArea.ServiceArea.DistrictId.Equals(districtId)) + .ToList() .GroupBy(x => x.Equipment, (e, rotationLists) => new EquipmentLiteList { EquipmentCode = e.EquipmentCode, @@ -199,7 +201,7 @@ public virtual IActionResult EquipmentGetLiteHires() DistrictEquipmentTypeId = e.DistrictEquipmentTypeId ?? 0, }); - return new ObjectResult(new HetsResponse(equipment)); + return new ObjectResult(new HetsResponse(equipments)); } /// diff --git a/Server/HetsApi/Controllers/OwnerController.cs b/Server/HetsApi/Controllers/OwnerController.cs index 62673d9e9..ec1ba62b7 100644 --- a/Server/HetsApi/Controllers/OwnerController.cs +++ b/Server/HetsApi/Controllers/OwnerController.cs @@ -136,7 +136,7 @@ public virtual IActionResult OwnersGetLiteHires() if (statusId == null) return new BadRequestObjectResult(new HetsResponse("HETS-23", ErrorViewModel.GetDescription("HETS-23", _configuration))); // get all active owners for this district (and any projects they're associated with) - var ownerList = _context.HetRentalRequestRotationList.AsNoTracking() + var owners = _context.HetRentalRequestRotationList.AsNoTracking() .Include(x => x.RentalRequest) .ThenInclude(y => y.LocalArea) .ThenInclude(z => z.ServiceArea) @@ -144,9 +144,7 @@ public virtual IActionResult OwnersGetLiteHires() .Include(x => x.Equipment) .ThenInclude(y => y.Owner) .Where(x => x.RentalRequest.LocalArea.ServiceArea.DistrictId.Equals(districtId)) - .ToList(); - - var owners = ownerList + .ToList() .GroupBy(x => x.Equipment.Owner, (o, rotationLists) => new OwnerLiteProjects { OwnerCode = o.OwnerCode, diff --git a/Server/HetsApi/Controllers/ProjectController.cs b/Server/HetsApi/Controllers/ProjectController.cs index 775e3e756..c17333630 100644 --- a/Server/HetsApi/Controllers/ProjectController.cs +++ b/Server/HetsApi/Controllers/ProjectController.cs @@ -303,10 +303,11 @@ public virtual IActionResult ProjectsGetAgreementSummary() // get user's district int? districtId = UserAccountHelper.GetUsersDistrictId(_context, _httpContext); - List result = _context.HetRentalAgreement.AsNoTracking() + var result = _context.HetRentalAgreement.AsNoTracking() .Include(x => x.Project) .Where(x => x.DistrictId.Equals(districtId) && !x.Number.StartsWith("BCBid")) + .ToList() .GroupBy(x => x.Project, (p, agreements) => new ProjectAgreementSummary { Id = p.ProjectId, From d241c910e6779654a4a32cf1fef5314c5ae2f815 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 09:45:38 -0700 Subject: [PATCH 022/352] miscellaneous fix including fix for postgres another command is already in progress --- .../HetsApi/Controllers/DistrictController.cs | 1 - .../Controllers/EquipmentController.cs | 53 +++---------------- .../Controllers/RentalRequestController.cs | 5 +- Server/HetsReport/MailingLabel.cs | 6 +-- 4 files changed, 12 insertions(+), 53 deletions(-) diff --git a/Server/HetsApi/Controllers/DistrictController.cs b/Server/HetsApi/Controllers/DistrictController.cs index 418b710f8..1870b80aa 100644 --- a/Server/HetsApi/Controllers/DistrictController.cs +++ b/Server/HetsApi/Controllers/DistrictController.cs @@ -261,7 +261,6 @@ public virtual IActionResult AnnualRolloverGet([FromRoute]int id) string seniorityScoringRules = GetConfigJson(scoringRules); // queue the job - //BackgroundJob.Enqueue(() => AnnualRolloverHelper.AnnualRolloverJob(null, id, seniorityScoringRules, connectionString)); BackgroundJob.Enqueue(x => x.AnnualRolloverJob(id, seniorityScoringRules)); var progressDto = _annualRollover.KickoffProgress(id); diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index 04c88d100..cc7257917 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -26,7 +26,6 @@ namespace HetsApi.Controllers [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public class EquipmentController : Controller { - private readonly Object _thisLock = new Object(); private readonly DbAppContext _context; private readonly IConfiguration _configuration; private readonly HttpContext _httpContext; @@ -542,15 +541,10 @@ public virtual IActionResult EquipmentPost([FromBody]HetEquipment item) [RequiresPermission(HetPermission.DistrictCodeTableManagement, HetPermission.WriteAccess)] public virtual IActionResult RecalculateSeniorityListPost() { - string connectionString = GetConnectionString(); - IConfigurationSection scoringRules = _configuration.GetSection("SeniorityScoringRules"); string seniorityScoringRules = GetConfigJson(scoringRules); // queue the job - //BackgroundJob.Enqueue(() => EquipmentHelper.RecalculateSeniorityList(null, - // seniorityScoringRules, connectionString)); - BackgroundJob.Enqueue(x => x.RecalculateSeniorityList(seniorityScoringRules)); // return ok @@ -605,41 +599,6 @@ private string RecurseConfigJson(IConfigurationSection scoringRules) #endregion - #region Get Database Connection String - - /// - /// Retrieve database connection string - /// - /// - private string GetConnectionString() - { - string connectionString; - - lock (_thisLock) - { - string host = _configuration["DATABASE_SERVICE_NAME"]; - string username = _configuration["POSTGRESQL_USER"]; - string password = _configuration["POSTGRESQL_PASSWORD"]; - string database = _configuration["POSTGRESQL_DATABASE"]; - - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || - string.IsNullOrEmpty(database)) - { - // When things get cleaned up properly, this is the only call we'll have to make. - connectionString = _configuration.GetConnectionString("HETS"); - } - else - { - // Environment variables override all other settings; same behaviour as the configuration provider when things get cleaned up. - connectionString = $"Host={host};Username={username};Password={password};Database={database};"; - } - } - - return connectionString; - } - - #endregion - #region Equipment Search /// @@ -1430,8 +1389,9 @@ public virtual IActionResult EquipmentSeniorityListDocGet([FromQuery]string loca // manage the rotation list data HetRentalRequestRotationList rotation = null; int currentBlock = -1; + var items = data.ToList(); - foreach (HetEquipment item in data) + foreach (HetEquipment item in items) { if (listRecord.LocalAreaName != item.LocalArea.Name || listRecord.DistrictEquipmentTypeName != item.DistrictEquipmentType.DistrictEquipmentName) @@ -1464,7 +1424,7 @@ public virtual IActionResult EquipmentSeniorityListDocGet([FromQuery]string loca // get the rotation info for the first block if (item.BlockNumber != null) currentBlock = (int) item.BlockNumber; - rotation = GetRotationList(_context, item.LocalArea.LocalAreaId, + rotation = GetRotationList(item.LocalArea.LocalAreaId, item.DistrictEquipmentType.DistrictEquipmentTypeId, currentBlock, fiscalEnd); } @@ -1473,7 +1433,7 @@ public virtual IActionResult EquipmentSeniorityListDocGet([FromQuery]string loca // get the rotation info for the next block currentBlock = (int)item.BlockNumber; - rotation = GetRotationList(_context, item.LocalArea.LocalAreaId, + rotation = GetRotationList(item.LocalArea.LocalAreaId, item.DistrictEquipmentType.DistrictEquipmentTypeId, currentBlock, fiscalEnd); } @@ -1520,8 +1480,7 @@ public virtual IActionResult EquipmentSeniorityListDocGet([FromQuery]string loca return result; } - private static HetRentalRequestRotationList GetRotationList(DbAppContext context, - int localAreaId, int districtEquipmentTypeId, int currentBlock, DateTime fiscalEnd) + private HetRentalRequestRotationList GetRotationList(int localAreaId, int districtEquipmentTypeId, int currentBlock, DateTime fiscalEnd) { try { @@ -1531,7 +1490,7 @@ private static HetRentalRequestRotationList GetRotationList(DbAppContext context // * For "Forced Hire" there will be no changes to this // column in the seniority list (as if nothing happened and nobody got called) // * Must be this fiscal year - HetRentalRequestRotationList blockRotation = context.HetRentalRequestRotationList.AsNoTracking() + HetRentalRequestRotationList blockRotation = _context.HetRentalRequestRotationList.AsNoTracking() .Include(x => x.Equipment) .Include(x => x.RentalRequest) .ThenInclude(x => x.LocalArea) diff --git a/Server/HetsApi/Controllers/RentalRequestController.cs b/Server/HetsApi/Controllers/RentalRequestController.cs index d881aab03..f61166588 100644 --- a/Server/HetsApi/Controllers/RentalRequestController.cs +++ b/Server/HetsApi/Controllers/RentalRequestController.cs @@ -1005,8 +1005,9 @@ public virtual IActionResult RentalRequestsHiresGet([FromQuery]string localAreas // convert Rental Request Model to the "RentalRequestHires" Model List result = new List(); - - foreach (HetRentalRequestRotationList item in data) + + var items = data.ToList(); + foreach (HetRentalRequestRotationList item in items) { HetUser user = _context.HetUser.AsNoTracking() .FirstOrDefault(x => x.SmUserId == item.AppCreateUserid); diff --git a/Server/HetsReport/MailingLabel.cs b/Server/HetsReport/MailingLabel.cs index e33c32a6d..af0961988 100644 --- a/Server/HetsReport/MailingLabel.cs +++ b/Server/HetsReport/MailingLabel.cs @@ -214,9 +214,9 @@ private static UInt32 CentimeterToDxa(double cm) private static void PopulateParagraph(HetOwner owner, Paragraph paragraph) { - paragraph.AppendChild(new Text(owner.OrganizationName.Trim())); + paragraph.AppendChild(new Text(owner.OrganizationName?.Trim())); paragraph.AppendChild(new Break()); - paragraph.AppendChild(new Text(owner.Address1.Trim())); + paragraph.AppendChild(new Text(owner.Address1?.Trim())); paragraph.AppendChild(new Break()); if (!string.IsNullOrWhiteSpace(owner.Address2)) @@ -225,7 +225,7 @@ private static void PopulateParagraph(HetOwner owner, Paragraph paragraph) paragraph.AppendChild(new Text(", ")); } - paragraph.AppendChild(new Text($"{owner.City.Trim()}, {owner.Province.Trim()} {owner.PostalCode.Trim()}")); + paragraph.AppendChild(new Text($"{owner.City?.Trim()}, {owner.Province?.Trim()} {owner.PostalCode?.Trim()}")); } } From 7d99cf9fd8b918320e41fe9fc40e3e5898365583 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 10:03:38 -0700 Subject: [PATCH 023/352] Pipeline for CRA changes --- client/Dockerfile | 8 ++++---- openshift/client-build-config.yaml | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/client/Dockerfile b/client/Dockerfile index 6f445285b..eab331cdb 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,14 +1,14 @@ FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/node:1 AS builder LABEL maintainer="young-jin.chung@gov.bc.ca" -COPY . /src +COPY . ./src -RUN cd /src && npm ci && \ - ./node_modules/.bin/gulp --production --commit=$OPENSHIFT_BUILD_COMMIT +RUN cd ./src && npm ci && \ + npm run build FROM image-registry.openshift-image-registry.svc:5000/e0cee6-tools/nginx-116-rhel8:1 -COPY --from=builder /src/dist/. /tmp/src +COPY --from=builder /src/build/. /tmp/src COPY --from=builder /src/nginx-start/. /tmp/src/nginx-start COPY --from=builder /src/nginx.conf.tmpl /tmp/src/nginx.conf.tmpl diff --git a/openshift/client-build-config.yaml b/openshift/client-build-config.yaml index 01702d5bc..8107a8d1f 100644 --- a/openshift/client-build-config.yaml +++ b/openshift/client-build-config.yaml @@ -6,6 +6,21 @@ metadata: labels: template: client-build objects: + - apiVersion: "v1" + kind: ImageStream + metadata: + name: node + spec: + lookupPolicy: + local: false + tags: + - annotations: null + from: + kind: DockerImage + name: docker.io/node:13.7-alpine3.11 + name: "1" + referencePolicy: + type: Local - apiVersion: "v1" kind: ImageStream metadata: @@ -17,7 +32,7 @@ objects: - annotations: null from: kind: DockerImage - name: registry.redhat.io/rhel8/nginx-116:1-39 + name: registry.redhat.io/rhel8/nginx-116:1-58 name: "1" referencePolicy: type: Local From 3b9c1c6cad55f822f518a3d7e17864585dbc4df9 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 10:11:28 -0700 Subject: [PATCH 024/352] dotnet image to 3.1 --- openshift/api-build-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openshift/api-build-config.yaml b/openshift/api-build-config.yaml index e960aa455..c13415fda 100644 --- a/openshift/api-build-config.yaml +++ b/openshift/api-build-config.yaml @@ -9,7 +9,7 @@ objects: - apiVersion: v1 kind: ImageStream metadata: - name: dotnet-21-rhel7 + name: dotnet-31-rhel7 labels: shared: "true" spec: @@ -19,8 +19,8 @@ objects: - annotations: null from: kind: DockerImage - name: registry.redhat.io/dotnet/dotnet-21-rhel7:2.1-41 - name: "2.1-41" + name: registry.redhat.io/dotnet/dotnet-31-rhel7:3.1-5 + name: "3.1" referencePolicy: type: Local - apiVersion: v1 @@ -82,7 +82,7 @@ objects: value: "${DOTNET_STARTUP_PROJECT}" from: kind: ImageStreamTag - name: dotnet-21-rhel7:2.1-41 + name: "dotnet-31-rhel7:3.1" parameters: - description: Name of the project (HETS) displayName: PROJECT_NAME From 22fd2063acc8e9a23f945493b41a0744834cb51d Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 10:25:00 -0700 Subject: [PATCH 025/352] Renamed sql script --- Db Scripts/UPDATE/{RELEASE1.9.sql => RELEASE1.9.1.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Db Scripts/UPDATE/{RELEASE1.9.sql => RELEASE1.9.1.sql} (100%) diff --git a/Db Scripts/UPDATE/RELEASE1.9.sql b/Db Scripts/UPDATE/RELEASE1.9.1.sql similarity index 100% rename from Db Scripts/UPDATE/RELEASE1.9.sql rename to Db Scripts/UPDATE/RELEASE1.9.1.sql From bbb4d640cbebb0598805dd75e839d17f076b3e68 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 8 Jun 2021 14:54:39 -0700 Subject: [PATCH 026/352] renamed script file --- Db Scripts/UPDATE/{RELEASE1.9.3.sql => RELEASE1.9.3-01.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Db Scripts/UPDATE/{RELEASE1.9.3.sql => RELEASE1.9.3-01.sql} (100%) diff --git a/Db Scripts/UPDATE/RELEASE1.9.3.sql b/Db Scripts/UPDATE/RELEASE1.9.3-01.sql similarity index 100% rename from Db Scripts/UPDATE/RELEASE1.9.3.sql rename to Db Scripts/UPDATE/RELEASE1.9.3-01.sql From c026dce97ae0fbac2daebab79fc2b4f5acf6fcd1 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 9 Jun 2021 08:09:47 -0700 Subject: [PATCH 027/352] .net core 3.1 to .net 5 --- .../SiteminderAuthenticationHandler.cs | 7 ++- Server/HetsApi/Helpers/UserAccountHelper.cs | 8 +-- Server/HetsApi/HetsApi.csproj | 54 ++++++++++--------- Server/HetsApi/Startup.cs | 4 -- Server/HetsApi/appsettings.json | 4 +- Server/HetsCommon/HetsCommon.csproj | 10 ++-- Server/HetsData/HetsData.csproj | 10 ++-- Server/HetsReport/HetsReport.csproj | 6 +-- openshift/api-build-config.yaml | 8 +-- 9 files changed, 58 insertions(+), 53 deletions(-) diff --git a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs index e53c3e921..bbb8d8590 100644 --- a/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs +++ b/Server/HetsApi/Authentication/SiteminderAuthenticationHandler.cs @@ -181,7 +181,10 @@ public class SiteMinderAuthenticationHandler : AuthenticationHandler /// /// - public SiteMinderAuthenticationHandler(IOptionsMonitor configureOptions, ILoggerFactory loggerFactory, UrlEncoder encoder, ISystemClock clock) : base(configureOptions, loggerFactory, encoder, clock) + public SiteMinderAuthenticationHandler(IOptionsMonitor configureOptions, + ILoggerFactory loggerFactory, + UrlEncoder encoder, + ISystemClock clock) : base(configureOptions, loggerFactory, encoder, clock) { _logger = loggerFactory.CreateLogger(typeof(SiteMinderAuthenticationHandler)); } @@ -392,7 +395,7 @@ protected override Task HandleAuthenticateAsync() using (IDbContextTransaction transaction = dbAppContext.Database.BeginTransaction()) { // lock the table during this transaction - dbAppContext.Database.ExecuteSqlCommand(@"LOCK TABLE ""HET_USER"" IN EXCLUSIVE MODE;"); + dbAppContext.Database.ExecuteSqlRaw(@"LOCK TABLE ""HET_USER"" IN EXCLUSIVE MODE;"); HetUser user = dbAppContext.HetUser.First(x => x.UserId == updUserId); user.DistrictId = districtId; diff --git a/Server/HetsApi/Helpers/UserAccountHelper.cs b/Server/HetsApi/Helpers/UserAccountHelper.cs index 3accd34eb..70e9f389a 100644 --- a/Server/HetsApi/Helpers/UserAccountHelper.cs +++ b/Server/HetsApi/Helpers/UserAccountHelper.cs @@ -101,12 +101,12 @@ public static User GetUser(DbAppContext context, HttpContext httpContext) // is this a business? bool isBusinessUser = IsBusiness(httpContext); - string userId = GetUserId(httpContext); + string userId = GetUserId(httpContext)?.ToLower(); if (!isBusinessUser) { HetUser tmpUser = context.HetUser.AsNoTracking() - .FirstOrDefault(x => x.SmUserId.ToLower().Equals(userId.ToLower())); + .FirstOrDefault(x => x.SmUserId.ToLower() == userId); if (tmpUser != null) { @@ -124,7 +124,7 @@ public static User GetUser(DbAppContext context, HttpContext httpContext) else { HetBusinessUser tmpUser = context.HetBusinessUser.AsNoTracking() - .FirstOrDefault(x => x.BceidUserId.ToLower().Equals(userId.ToLower())); + .FirstOrDefault(x => x.BceidUserId.ToLower() == userId); if (tmpUser != null) { @@ -182,7 +182,7 @@ public static HetUser GetUser(DbAppContext context, string userId, string guid = using (IDbContextTransaction transaction = context.Database.BeginTransaction()) { // lock the table during this transaction - context.Database.ExecuteSqlCommand(@"LOCK TABLE ""HET_USER"" IN EXCLUSIVE MODE;"); + context.Database.ExecuteSqlRaw(@"LOCK TABLE ""HET_USER"" IN EXCLUSIVE MODE;"); HetUser updUser = context.HetUser.First(x => x.UserId == updUserId); diff --git a/Server/HetsApi/HetsApi.csproj b/Server/HetsApi/HetsApi.csproj index a79bb01c4..4080dcbdc 100644 --- a/Server/HetsApi/HetsApi.csproj +++ b/Server/HetsApi/HetsApi.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net5.0 The Api server for the Hired Equipment Tracking System Copyright© 2017, Province of British Columbia. Hets Api Server @@ -11,8 +11,8 @@ 1.0.0.0 - sprint4 - 1.9.2.0 + sprint1 + 1.9.3.0 @@ -35,33 +35,39 @@ - - - - - + + + + + - - - + + + - - - - - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + - - - - - - + + + + + + diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 636de7a00..991291b52 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -2,14 +2,11 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Http.Features; using Newtonsoft.Json.Serialization; -using Swashbuckle.AspNetCore.Swagger; using Hangfire; using Hangfire.PostgreSql; -using Hangfire.Console; using HetsApi.Authorization; using HetsApi.Authentication; using HetsData.Model; @@ -17,7 +14,6 @@ using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Models; -using Microsoft.Extensions.Hosting; using Swashbuckle.AspNetCore.SwaggerUI; using HetsData.Hangfire; diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index 7d8da7b11..d66c79486 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -13,8 +13,8 @@ "LogoffUrl-Training": "https://logontest.gov.bc.ca/clp-cgi/logoff.cgi?returl=https://trn-hets.th.gov.bc.ca&retnow=1", "LogoffUrl-UAT": "https://logontest.gov.bc.ca/clp-cgi/logoff.cgi?returl=https://uat-hets.th.gov.bc.ca&retnow=1", "LogoffUrl-Production": "https://logon.gov.bc.ca/clp-cgi/logoff.cgi?returl=https://hets.th.gov.bc.ca&retnow=1", - "Version-Application": "Release 1.9.2.0", - "Version-Database": "Release 1.9.2.0", + "Version-Application": "Release 1.9.3.0", + "Version-Database": "Release 1.9.3.0", "Maximum-Blank-Agreements": "3", "ExceptionDescriptions": { "HETS-01": "Record not found", diff --git a/Server/HetsCommon/HetsCommon.csproj b/Server/HetsCommon/HetsCommon.csproj index 3e767fea8..954d5bd15 100644 --- a/Server/HetsCommon/HetsCommon.csproj +++ b/Server/HetsCommon/HetsCommon.csproj @@ -1,19 +1,19 @@  - netcoreapp3.1 + net5.0 Common code for the HETS application Copyright© 2017, Province of British Columbia Hets Common HetsCommon HetsCommon - 1.9.2.0 + 1.9.3.0 - - - + + + diff --git a/Server/HetsData/HetsData.csproj b/Server/HetsData/HetsData.csproj index 597efa04b..5352633b5 100644 --- a/Server/HetsData/HetsData.csproj +++ b/Server/HetsData/HetsData.csproj @@ -1,20 +1,20 @@ - netcoreapp3.1 + net5.0 Common data code for the HETS application Copyright© 2017, Province of British Columbia Hets Data HetsData HetsData - 1.9.2.0 + 1.9.3.0 - - - + + + diff --git a/Server/HetsReport/HetsReport.csproj b/Server/HetsReport/HetsReport.csproj index c1a21c053..8d5663b26 100644 --- a/Server/HetsReport/HetsReport.csproj +++ b/Server/HetsReport/HetsReport.csproj @@ -1,8 +1,8 @@ - netcoreapp3.1 - 1.9.2.0 + net5.0 + 1.9.3.0 @@ -20,7 +20,7 @@ - + diff --git a/openshift/api-build-config.yaml b/openshift/api-build-config.yaml index c13415fda..ee70a540e 100644 --- a/openshift/api-build-config.yaml +++ b/openshift/api-build-config.yaml @@ -9,7 +9,7 @@ objects: - apiVersion: v1 kind: ImageStream metadata: - name: dotnet-31-rhel7 + name: dotnet-50-rhel8 labels: shared: "true" spec: @@ -19,8 +19,8 @@ objects: - annotations: null from: kind: DockerImage - name: registry.redhat.io/dotnet/dotnet-31-rhel7:3.1-5 - name: "3.1" + name: registry.redhat.io/rhel8/dotnet-50:5.0-4 + name: "5.0" referencePolicy: type: Local - apiVersion: v1 @@ -82,7 +82,7 @@ objects: value: "${DOTNET_STARTUP_PROJECT}" from: kind: ImageStreamTag - name: "dotnet-31-rhel7:3.1" + name: "dotnet-50-rhel8:5.0" parameters: - description: Name of the project (HETS) displayName: PROJECT_NAME From 3387c288706cf2553bdecaa548957fc340971c4f Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 9 Jun 2021 10:28:38 -0700 Subject: [PATCH 028/352] refactored hangfire jobs --- .../DistrictEquipmentTypeController.cs | 41 +-- .../Hangfire/DistrictEquipmentTypesMerger.cs | 3 +- .../Helpers/DistrictEquipmentTypeHelper.cs | 318 +----------------- Server/HetsData/Helpers/EquipmentHelper.cs | 45 --- 4 files changed, 4 insertions(+), 403 deletions(-) diff --git a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs index a28caf139..7aa678a0d 100644 --- a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs +++ b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs @@ -13,6 +13,7 @@ using HetsApi.Model; using HetsData.Helpers; using HetsData.Model; +using HetsData.Hangfire; namespace HetsApi.Controllers { @@ -339,14 +340,11 @@ public virtual IActionResult DistrictEquipmentTypesIdPost([FromRoute]int id, [Fr [RequiresPermission(HetPermission.DistrictCodeTableManagement, HetPermission.WriteAccess)] public virtual IActionResult MergeDistrictEquipmentTypesPost() { - string connectionString = GetConnectionString(); - IConfigurationSection scoringRules = _configuration.GetSection("SeniorityScoringRules"); string seniorityScoringRules = GetConfigJson(scoringRules); // queue the job - BackgroundJob.Enqueue(() => DistrictEquipmentTypeHelper.MergeDistrictEquipmentTypes(null, - seniorityScoringRules, connectionString)); + BackgroundJob.Enqueue(x => x.MergeDistrictEquipmentTypes(seniorityScoringRules)); // return ok return new ObjectResult(new HetsResponse("Merge job added to hangfire")); @@ -399,40 +397,5 @@ private string RecurseConfigJson(IConfigurationSection scoringRules) } #endregion - - #region Get Database Connection String - - /// - /// Retrieve database connection string - /// - /// - private string GetConnectionString() - { - string connectionString; - - lock (_thisLock) - { - string host = _configuration["DATABASE_SERVICE_NAME"]; - string username = _configuration["POSTGRESQL_USER"]; - string password = _configuration["POSTGRESQL_PASSWORD"]; - string database = _configuration["POSTGRESQL_DATABASE"]; - - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || - string.IsNullOrEmpty(database)) - { - // When things get cleaned up properly, this is the only call we'll have to make. - connectionString = _configuration.GetConnectionString("HETS"); - } - else - { - // Environment variables override all other settings; same behaviour as the configuration provider when things get cleaned up. - connectionString = $"Host={host};Username={username};Password={password};Database={database};"; - } - } - - return connectionString; - } - - #endregion } } diff --git a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs index 655b60921..469c7290b 100644 --- a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs +++ b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs @@ -18,8 +18,7 @@ public DistrictEquipmentTypesMerger(DbAppContext dbContext) _jobId = Guid.NewGuid().ToString(); } - public void MergeDistrictEquipmentTypes(string seniorityScoringRules, - string connectionString) + public void MergeDistrictEquipmentTypes(string seniorityScoringRules) { // get equipment status int? equipmentStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", _dbContext); diff --git a/Server/HetsData/Helpers/DistrictEquipmentTypeHelper.cs b/Server/HetsData/Helpers/DistrictEquipmentTypeHelper.cs index 9cebe2463..d40b2ad69 100644 --- a/Server/HetsData/Helpers/DistrictEquipmentTypeHelper.cs +++ b/Server/HetsData/Helpers/DistrictEquipmentTypeHelper.cs @@ -1,12 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Hangfire.Console; -using Hangfire.Console.Progress; -using Hangfire.Server; -using Microsoft.EntityFrameworkCore; -using HetsData.Model; -using Newtonsoft.Json; +using System.Collections.Generic; namespace HetsData.Helpers { @@ -25,314 +17,6 @@ public class MergeRecord #endregion - public static class DistrictEquipmentTypeHelper - { - public static void MergeDistrictEquipmentTypes(PerformContext context, string seniorityScoringRules, - string connectionString) - { - // open a connection to the database - DbAppContext dbContext = new DbAppContext(connectionString); - - // get equipment status - int? equipmentStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); - if (equipmentStatusId == null) - { - throw new ArgumentException("Status Code not found"); - } - - // ************************************************** - // Phase 1: Identify Master District Equipment Types - // ************************************************** - context.WriteLine("Phase 1: Identify Master District Equipment Types"); - IProgressBar progress = context.WriteProgressBar(); - progress.SetValue(0); - - // get records - List masterList = dbContext.HetDistrictEquipmentType.AsNoTracking() - .Where(x => x.ServiceAreaId != null && - x.Deleted == false) - .Select(x => new MergeRecord - { - DistrictEquipmentTypeId = x.DistrictEquipmentTypeId, - DistrictEquipmentName = x.DistrictEquipmentName, - EquipmentPrefix = GetPrefix(x.DistrictEquipmentName), - DistrictId = x.DistrictId, - EquipmentTypeId = x.EquipmentTypeId - }) - .Distinct() - .ToList(); - - // sort the list accordingly - masterList = masterList - .OrderBy(x => x.DistrictId) - .ThenBy(x => x.EquipmentTypeId) - .ThenBy(x => x.EquipmentPrefix).ToList(); - - int increment = 0; - int? currentDistrict = -1; - int? masterDistrictEquipmentTypeId = -1; - int? currentEquipmentType = -1; - string currentPrefix = ""; - - foreach (MergeRecord detRecord in masterList) - { - bool newMerge; - - if (detRecord.DistrictId != currentDistrict || - detRecord.EquipmentTypeId != currentEquipmentType || - detRecord.EquipmentPrefix != currentPrefix) - { - newMerge = true; - currentDistrict = detRecord.DistrictId; - currentEquipmentType = detRecord.EquipmentTypeId; - currentPrefix = detRecord.EquipmentPrefix; - - masterDistrictEquipmentTypeId = detRecord.DistrictEquipmentTypeId; - detRecord.Master = true; - detRecord.MasterDistrictEquipmentTypeId = masterDistrictEquipmentTypeId; - } - else - { - newMerge = false; - detRecord.Master = false; - detRecord.MasterDistrictEquipmentTypeId = masterDistrictEquipmentTypeId; - } - - // kickoff the merge for this district, equipment type and prefix - if (newMerge) - { - int district = currentDistrict ?? -1; - int type = currentEquipmentType ?? -1; - string prefix = currentPrefix; - string masterName = ""; - - List types = masterList - .Where(x => x.DistrictId == district && - x.EquipmentTypeId == type && - x.EquipmentPrefix == prefix).ToList(); - - // create master name and update master record - foreach (MergeRecord equipmentType in types) - { - string temp = equipmentType.DistrictEquipmentName.Replace(currentPrefix, "").Trim(); - int start = temp.IndexOf("-", StringComparison.Ordinal); - if (start > -1) start++; - int length = temp.Length - start < 0 ? 0 : temp.Length - start; - temp = temp.Substring(start, length).Trim(); - - masterName = masterName.Length > 0 ? - $"{masterName} | {temp}" : - temp; - } - - masterName = $"{currentPrefix} - {masterName}"; - types.ElementAt(0).DistrictEquipmentName = masterName; - } - - // update status bar - increment++; - progress.SetValue(Convert.ToInt32((decimal)(masterList.Count - (masterList.Count - increment)) / masterList.Count * 100)); - } - - // done! - progress.SetValue(100); - - // ************************************************** - // Phase 2: Update Master District Equipment Types - // ************************************************** - context.WriteLine("Phase 2: Update Master District Equipment Types"); - progress = context.WriteProgressBar(); - progress.SetValue(0); - - List masterRecords = masterList.Where(x => x.Master).ToList(); - - increment = 0; - - foreach (MergeRecord detRecord in masterRecords) - { - // get det record & update name - HetDistrictEquipmentType det = dbContext.HetDistrictEquipmentType - .First(x => x.DistrictEquipmentTypeId == detRecord.DistrictEquipmentTypeId); - - det.DistrictEquipmentName = detRecord.DistrictEquipmentName; - det.ServiceAreaId = null; - - // save changes to district equipment types and associated equipment records - dbContext.SaveChangesForImport(); - - // update status bar - increment++; - progress.SetValue(Convert.ToInt32((decimal)(masterRecords.Count - (masterRecords.Count - increment)) / masterRecords.Count * 100)); - } - - // done! - progress.SetValue(100); - - // ************************************************** - // Phase 3: Update Non-Master District Equipment Types - // ************************************************** - context.WriteLine("Phase 3: Update Non-Master District Equipment Types"); - progress = context.WriteProgressBar(); - progress.SetValue(0); - - List mergeRecords = masterList.Where(x => !x.Master).ToList(); - - increment = 0; - - foreach (MergeRecord detRecord in mergeRecords) - { - int originalDistrictEquipmentTypeId = detRecord.DistrictEquipmentTypeId; - int? newDistrictEquipmentTypeId = detRecord.MasterDistrictEquipmentTypeId; - - // get equipment & update - IEnumerable equipmentRecords = dbContext.HetEquipment - .Where(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - - foreach (HetEquipment equipment in equipmentRecords) - { - equipment.DistrictEquipmentTypeId = newDistrictEquipmentTypeId; - } - - // save changes to associated equipment records - dbContext.SaveChangesForImport(); - - // get det record - HetDistrictEquipmentType det = dbContext.HetDistrictEquipmentType - .First(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - - // delete old det record - HetRentalRequest request = dbContext.HetRentalRequest.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - - HetLocalAreaRotationList rotationList = dbContext.HetLocalAreaRotationList.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - - if (request != null || rotationList != null) - { - det.Deleted = true; - } - else - { - dbContext.HetDistrictEquipmentType.Remove(det); - } - - // save changes to district equipment types and associated equipment records - dbContext.SaveChangesForImport(); - - // update status bar - increment++; - progress.SetValue(Convert.ToInt32((decimal)(mergeRecords.Count - (mergeRecords.Count - increment)) / mergeRecords.Count * 100)); - } - - // done! - progress.SetValue(100); - - // ************************************************** - // Phase 4: Update seniority and block assignments - // ************************************************** - context.WriteLine("Phase 4: Update seniority and block assignments"); - progress = context.WriteProgressBar(); - progress.SetValue(0); - - increment = 0; - - foreach (MergeRecord detRecord in masterRecords) - { - // update the seniority and block assignments for the master record - List localAreas = dbContext.HetEquipment.AsNoTracking() - .Include(x => x.LocalArea) - .Where(x => x.EquipmentStatusTypeId == equipmentStatusId && - x.DistrictEquipmentTypeId == detRecord.DistrictEquipmentTypeId) - .Select(x => x.LocalArea) - .Distinct() - .ToList(); - - foreach (HetLocalArea localArea in localAreas) - { - EquipmentHelper.RecalculateSeniority(localArea.LocalAreaId, - detRecord.DistrictEquipmentTypeId, dbContext, seniorityScoringRules); - } - - // save changes to equipment records - dbContext.SaveChangesForImport(); - - // update status bar - increment++; - progress.SetValue(Convert.ToInt32((decimal)(masterRecords.Count - (masterRecords.Count - increment)) / masterRecords.Count * 100)); - } - - // done! - progress.SetValue(100); - - // ************************************************** - // Phase 5: Cleanup "empty" District Equipment Types - // ************************************************** - context.WriteLine("Phase 5: Cleanup empty District Equipment Types"); - progress = context.WriteProgressBar(); - progress.SetValue(0); - - // get records - List districtEquipmentTypes = dbContext.HetDistrictEquipmentType.AsNoTracking() - .Include(x => x.HetEquipment) - .Where(x => x.Deleted == false) - .Distinct() - .ToList(); - - increment = 0; - - foreach (HetDistrictEquipmentType districtEquipmentType in districtEquipmentTypes) - { - int districtEquipmentTypeId = districtEquipmentType.DistrictEquipmentTypeId; - - // does this det have any equipment records? - if (districtEquipmentType.HetEquipment.Count < 1) - { - // get det record - HetDistrictEquipmentType det = dbContext.HetDistrictEquipmentType - .First(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); - - // delete old det record - HetRentalRequest request = dbContext.HetRentalRequest.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); - - HetLocalAreaRotationList rotationList = dbContext.HetLocalAreaRotationList.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); - - if (request != null || rotationList != null) - { - det.Deleted = true; - } - else - { - dbContext.HetDistrictEquipmentType.Remove(det); - } - - // save changes to district equipment types and associated equipment records - dbContext.SaveChangesForImport(); - } - - // update status bar - increment++; - progress.SetValue(Convert.ToInt32((decimal)(districtEquipmentTypes.Count - (districtEquipmentTypes.Count - increment)) / districtEquipmentTypes.Count * 100)); - } - - // done! - progress.SetValue(100); - } - - private static string GetPrefix(string name) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentException("Invalid District Equipment Name"); - - int start = name.IndexOf("-", StringComparison.Ordinal); - - if (start <= 1) return name; - - return name.Substring(0, start).Trim(); - } - - } - public class DistrictEquipmentTypeAgreementSummary { public int Id { get; set; } diff --git a/Server/HetsData/Helpers/EquipmentHelper.cs b/Server/HetsData/Helpers/EquipmentHelper.cs index 9dad99cc1..3a448e64e 100644 --- a/Server/HetsData/Helpers/EquipmentHelper.cs +++ b/Server/HetsData/Helpers/EquipmentHelper.cs @@ -785,50 +785,5 @@ public static List GetHistoryRecords(int id, int? offset, int? limit, D } #endregion - - - /// - /// Recalculates seniority with the new sorting rule (sorting by equipment code) for the district equipment types that have the same seniority and received date - /// - /// - /// - /// - public static void RecalculateSeniorityList(PerformContext context, string seniorityScoringRules, string connectionString) - { - // open a connection to the database - DbAppContext dbContext = new DbAppContext(connectionString); - - // get equipment status - int? equipmentStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); - if (equipmentStatusId == null) - { - throw new ArgumentException("Status Code not found"); - } - - context.WriteLine("Recalculation Started"); - - var progress = context.WriteProgressBar(); - progress.SetValue(0); - - var equipments = dbContext.HetEquipment.AsNoTracking() - .Where(x => x.EquipmentStatusTypeId == equipmentStatusId) - .GroupBy(x => new { x.LocalAreaId, x.DistrictEquipmentTypeId, x.Seniority, x.ReceivedDate }) - .Where(x => x.Count() > 1) - .Select(x => new { x.Key.LocalAreaId, x.Key.DistrictEquipmentTypeId }) - .Distinct() - .ToList(); - - var count = 0; - foreach (var equipment in equipments) - { - EquipmentHelper.RecalculateSeniority(equipment.LocalAreaId, equipment.DistrictEquipmentTypeId, dbContext, seniorityScoringRules); - progress.SetValue(Convert.ToInt32(++count / equipments.Count * 100)); - context.WriteLine($"Processed {count} / {equipments.Count}"); - } - - progress.SetValue(100); - - context.WriteLine("Recalculation Finished"); - } } } From eb1d411f57298e1db72c03ede9261eba845d35cb Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 9 Jun 2021 14:43:37 -0700 Subject: [PATCH 029/352] Implemented KC for IDIR --- .../Authentication/HetsJwtBearerEvents.cs | 182 ++++++++++++++++++ .../Extensions/ClaimsPrincipalExtensions.cs | 21 ++ .../Extensions/HttpResponseExtensions.cs | 17 ++ Server/HetsApi/Startup.cs | 15 +- Server/HetsApi/appsettings.json | 4 + Server/HetsData/Constants.cs | 12 ++ 6 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 Server/HetsApi/Authentication/HetsJwtBearerEvents.cs create mode 100644 Server/HetsApi/Extensions/ClaimsPrincipalExtensions.cs create mode 100644 Server/HetsApi/Extensions/HttpResponseExtensions.cs create mode 100644 Server/HetsData/Constants.cs diff --git a/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs b/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs new file mode 100644 index 000000000..34e5150f6 --- /dev/null +++ b/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs @@ -0,0 +1,182 @@ +using HetsApi.Extensions; +using HetsApi.Helpers; +using HetsData.Model; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Linq; +using System.Threading.Tasks; +using HetsData; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore; + +namespace HetsApi.Authentication +{ + public class HetsJwtBearerEvents : JwtBearerEvents + { + private DbAppContext _dbContext; + private ILogger _logger; + + public HetsJwtBearerEvents(IWebHostEnvironment env, + DbAppContext dbContext, + + ILogger logger) : base() + { + _dbContext = dbContext; + _logger = logger; + } + + public override async Task AuthenticationFailed(AuthenticationFailedContext context) + { + context.Response.ContentType = "application/json"; + context.Response.StatusCode = StatusCodes.Status401Unauthorized; + + var problem = new ValidationProblemDetails() + { + Type = "https://Hets.bc.gov.ca/exception", + Title = "Access denied", + Status = StatusCodes.Status401Unauthorized, + Detail = "Authentication failed.", + Instance = context.Request.Path + }; + + problem.Extensions.Add("traceId", context.HttpContext.TraceIdentifier); + + await context.Response.WriteJsonAsync(problem, "application/problem+json"); + } + + public override async Task TokenValidated(TokenValidatedContext context) + { + var userSettings = new UserSettings(); + + var (username, userGuid, directory) = context.Principal.GetUserInfo(); + + if (directory != "IDIR") + { + context.Fail($"BCeID({directory}) user is not suppored yet!"); + return; + } + else + { + var idirUserResult = LoadIdirUser(context, username, userGuid, userSettings); + if (!idirUserResult.success) + { + context.Fail(idirUserResult.message); + return; + } + } + + var addClaimResult = AddClaimsFromUserInfo(userSettings); + if (!addClaimResult.success) + { + context.Fail(addClaimResult.message); + return; + } + + await Task.CompletedTask; + } + + private (bool success, string message) LoadIdirUser(TokenValidatedContext context, string username, string userGuid, UserSettings userSettings) + { + try + { + userSettings.HetsUser = UserAccountHelper.GetUser(_dbContext, username, userGuid); + + if (userSettings.HetsUser == null) + { + return (false, $"{Constants.MissingDbUserIdError} {username}"); + } + + if (!userSettings.HetsUser.Active) + { + return (false, $"{Constants.InactiveDbUserIdError} {username}"); + } + + // ************************************************** + // update the user back to their default district + // ************************************************** + string tempSwitch = context.Request.Cookies["HETSDistrict"]; + + if (string.IsNullOrEmpty(tempSwitch)) + { + HetUserDistrict userDistrict = _dbContext.HetUserDistrict.AsNoTracking() + .Include(x => x.User) + .Include(x => x.District) + .FirstOrDefault(x => x.User.UserId == userSettings.HetsUser.UserId && + x.IsPrimary); + + // if we don't find a primary - look for the first one in the list + if (userDistrict == null) + { + userDistrict = _dbContext.HetUserDistrict.AsNoTracking() + .Include(x => x.User) + .Include(x => x.District) + .FirstOrDefault(x => x.User.UserId == userSettings.HetsUser.UserId); + } + + // update the current district for the user + if (userDistrict != null && + userSettings.HetsUser.DistrictId != userDistrict.District.DistrictId) + { + int districtId = userDistrict.District.DistrictId; + int updUserId = userSettings.HetsUser.UserId; + + _logger.LogInformation("Resetting users district back to primary ({0})", userSettings.HetsUser.SmUserId); + + userSettings.HetsUser.DistrictId = districtId; + + using (IDbContextTransaction transaction = _dbContext.Database.BeginTransaction()) + { + // lock the table during this transaction + _dbContext.Database.ExecuteSqlRaw(@"LOCK TABLE ""HET_USER"" IN EXCLUSIVE MODE;"); + + HetUser user = _dbContext.HetUser.First(x => x.UserId == updUserId); + user.DistrictId = districtId; + _dbContext.SaveChanges(); + transaction.Commit(); + } + } + } + + userSettings.SiteMinderGuid = userGuid; + userSettings.UserAuthenticated = true; + userSettings.BusinessUser = false; + + return (true, ""); + } + catch (Exception e) + { + _logger.LogError(e.ToString()); + throw; + } + } + + private (bool success, string message) AddClaimsFromUserInfo(UserSettings userSettings) + { + if (userSettings.BusinessUser) + { + var userPrincipal = userSettings.HetsBusinessUser.ToClaimsPrincipal(JwtBearerDefaults.AuthenticationScheme); + + if (!userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) + { + return (false, $"{Constants.MissingDbUserIdError} {userSettings.UserId}"); + } + } + else + { + var userPrincipal = userSettings.HetsUser.ToClaimsPrincipal(JwtBearerDefaults.AuthenticationScheme); + + if (!userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.Login) && + !userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) + { + return (false, $"{Constants.MissingDbUserIdError} {userSettings.UserId}"); + } + } + + return (true, ""); + } + } +} diff --git a/Server/HetsApi/Extensions/ClaimsPrincipalExtensions.cs b/Server/HetsApi/Extensions/ClaimsPrincipalExtensions.cs new file mode 100644 index 000000000..2d655ba34 --- /dev/null +++ b/Server/HetsApi/Extensions/ClaimsPrincipalExtensions.cs @@ -0,0 +1,21 @@ +using System.Security.Claims; + +namespace HetsApi.Extensions +{ + public static class ClaimsPrincipalExtensions + { + public static (string username, string userGuid, string directory) GetUserInfo(this ClaimsPrincipal principal) + { + var preferredUsername = principal.FindFirstValue("preferred_username"); + + var usernames = preferredUsername?.Split("@"); + var username = usernames?[0].ToUpperInvariant(); + var directory = usernames?[1].ToUpperInvariant(); + + var userGuidClaim = directory == "IDIR" ? "idir_userid" : "bceid_userid"; + var userGuid = principal.FindFirstValue(userGuidClaim)?.ToUpperInvariant(); + + return (username, userGuid, directory); + } + } +} diff --git a/Server/HetsApi/Extensions/HttpResponseExtensions.cs b/Server/HetsApi/Extensions/HttpResponseExtensions.cs new file mode 100644 index 000000000..7e4ff01b7 --- /dev/null +++ b/Server/HetsApi/Extensions/HttpResponseExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace HetsApi.Extensions +{ + public static class HttpResponseExtensions + { + private static JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + public static async Task WriteJsonAsync(this HttpResponse response, T obj, string contentType = null) + { + response.ContentType = contentType ?? "application/json"; + await response.WriteAsync(JsonSerializer.Serialize(obj, _jsonOptions)); + } + } +} diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 991291b52..8a81c81a3 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -16,6 +16,7 @@ using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerUI; using HetsData.Hangfire; +using Microsoft.AspNetCore.Authentication.JwtBearer; namespace HetsApi { @@ -64,18 +65,24 @@ public void ConfigureServices(IServiceCollection services) }) .SetCompatibilityVersion(CompatibilityVersion.Version_3_0); - // setup SiteMinder authentication (core 2.0+) services.AddAuthentication(options => { - options.DefaultAuthenticateScheme = SiteMinderAuthOptions.AuthenticationSchemeName; - options.DefaultChallengeScheme = SiteMinderAuthOptions.AuthenticationSchemeName; - }).AddSiteMinderAuth(options => + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => { + options.Authority = Configuration.GetValue("JWT:Authority"); + options.Audience = Configuration.GetValue("JWT:Audience"); + options.RequireHttpsMetadata = false; + options.IncludeErrorDetails = true; + options.EventsType = typeof(HetsJwtBearerEvents); }); // setup authorization services.AddAuthorization(); services.RegisterPermissionHandler(); + services.AddScoped(); // allow for large files to be uploaded services.Configure(options => diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index d66c79486..97d89502f 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -83,6 +83,10 @@ "ConnectionStrings": { "HETS": "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010;" }, + "JWT": { + "Authority": "https://dev.oidc.gov.bc.ca/auth/realms/", + "Audience": "" + }, "UploadPath": "D:\\Temp\\HETSUploads\\", "ReportsPath": "D:\\Temp\\HETSReports\\", "Logging": { diff --git a/Server/HetsData/Constants.cs b/Server/HetsData/Constants.cs new file mode 100644 index 000000000..832b6c32b --- /dev/null +++ b/Server/HetsData/Constants.cs @@ -0,0 +1,12 @@ +namespace HetsData +{ + public class Constants + { + public const string MissingSiteMinderUserIdError = "Missing SiteMinder UserId"; + public const string MissingSiteMinderGuidError = "Missing SiteMinder Guid"; + public const string MissingDbUserIdError = "Could not find UserId in the HETS database"; + public const string InactiveDbUserIdError = "HETS database UserId is inactive"; + public const string InvalidPermissions = "HETS UserId does not have valid permissions"; + public const string MissingBusinessIdError = "Invalid Business Record"; + } +} From 33a82674ca4cdc8bb9d766219c213d72c29eb96a Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 10 Jun 2021 09:55:37 -0700 Subject: [PATCH 030/352] Keycloak for IDIR --- .../Authentication/HetsJwtBearerEvents.cs | 25 ++-- .../Controllers/AttachmentController.cs | 7 -- .../Controllers/AttachmentUploadController.cs | 7 -- .../HetsApi/Controllers/BusinessController.cs | 11 +- .../Controllers/ConditionTypeController.cs | 7 -- .../HetsApi/Controllers/ContactController.cs | 7 -- Server/HetsApi/Controllers/CountController.cs | 7 -- .../Controllers/CurrentUserController.cs | 7 -- .../HetsApi/Controllers/DistrictController.cs | 7 -- .../DistrictEquipmentTypeController.cs | 7 -- .../EquipmentAttachmentController.cs | 7 -- .../Controllers/EquipmentController.cs | 7 -- .../Controllers/EquipmentTypeController.cs | 7 -- Server/HetsApi/Controllers/NoteController.cs | 7 -- Server/HetsApi/Controllers/OwnerController.cs | 7 -- .../Controllers/PermissionController.cs | 7 -- .../HetsApi/Controllers/ProjectController.cs | 7 -- .../ProvincialRateTypeController.cs | 7 -- .../HetsApi/Controllers/RegionController.cs | 7 -- .../RentalAgreementConditionController.cs | 7 -- .../Controllers/RentalAgreementController.cs | 7 -- .../RentalAgreementRateController.cs | 7 -- .../Controllers/RentalRequestController.cs | 7 -- .../HetsApi/Controllers/ReportController.cs | 7 -- Server/HetsApi/Controllers/RoleController.cs | 7 -- .../Controllers/ServiceAreaController.cs | 7 -- .../Controllers/TimeRecordController.cs | 7 -- Server/HetsApi/Controllers/UserController.cs | 7 -- .../Controllers/UserDistrictsController.cs | 11 +- .../HetsApi/Controllers/VersionController.cs | 7 -- Server/HetsApi/Helpers/UserAccountHelper.cs | 15 +-- .../Extension/HetBusinessUserExtension.cs | 6 +- Server/HetsData/Extension/HetUserExtension.cs | 6 +- client/.env.development | 5 + client/.env.production | 1 + client/.prettierrc | 6 + client/package-lock.json | 21 ++++ client/package.json | 1 + client/src/index.js | 27 +++-- client/src/js/Keycloak.js | 27 +++++ client/src/js/utils/http.js | 114 ++++++++---------- client/src/setupProxy.js | 7 +- 42 files changed, 157 insertions(+), 315 deletions(-) create mode 100644 client/.env.development create mode 100644 client/.env.production create mode 100644 client/.prettierrc create mode 100644 client/src/js/Keycloak.js diff --git a/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs b/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs index 34e5150f6..a249e4256 100644 --- a/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs +++ b/Server/HetsApi/Authentication/HetsJwtBearerEvents.cs @@ -12,6 +12,7 @@ using HetsData; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore; +using System.Security.Claims; namespace HetsApi.Authentication { @@ -22,7 +23,6 @@ public class HetsJwtBearerEvents : JwtBearerEvents public HetsJwtBearerEvents(IWebHostEnvironment env, DbAppContext dbContext, - ILogger logger) : base() { _dbContext = dbContext; @@ -50,6 +50,8 @@ public override async Task AuthenticationFailed(AuthenticationFailedContext cont public override async Task TokenValidated(TokenValidatedContext context) { + await Task.CompletedTask; + var userSettings = new UserSettings(); var (username, userGuid, directory) = context.Principal.GetUserInfo(); @@ -69,20 +71,25 @@ public override async Task TokenValidated(TokenValidatedContext context) } } - var addClaimResult = AddClaimsFromUserInfo(userSettings); + var addClaimResult = AddClaimsFromUserInfo(context.Principal, userSettings); if (!addClaimResult.success) { context.Fail(addClaimResult.message); return; } - await Task.CompletedTask; + _dbContext.SmUserId = username; + _dbContext.DirectoryName = directory; + _dbContext.SmUserGuid = userGuid; + _dbContext.SmBusinessGuid = userSettings.SiteMinderBusinessGuid; + } private (bool success, string message) LoadIdirUser(TokenValidatedContext context, string username, string userGuid, UserSettings userSettings) { try { + userSettings.UserId = username; userSettings.HetsUser = UserAccountHelper.GetUser(_dbContext, username, userGuid); if (userSettings.HetsUser == null) @@ -154,23 +161,23 @@ public override async Task TokenValidated(TokenValidatedContext context) } } - private (bool success, string message) AddClaimsFromUserInfo(UserSettings userSettings) + private (bool success, string message) AddClaimsFromUserInfo(ClaimsPrincipal principal, UserSettings userSettings) { if (userSettings.BusinessUser) { - var userPrincipal = userSettings.HetsBusinessUser.ToClaimsPrincipal(JwtBearerDefaults.AuthenticationScheme); + principal.AddIdentity(userSettings.HetsBusinessUser.ToClaimsIdentity()); - if (!userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) + if (!principal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) { return (false, $"{Constants.MissingDbUserIdError} {userSettings.UserId}"); } } else { - var userPrincipal = userSettings.HetsUser.ToClaimsPrincipal(JwtBearerDefaults.AuthenticationScheme); + principal.AddIdentity(userSettings.HetsUser.ToClaimsIdentity()); - if (!userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.Login) && - !userPrincipal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) + if (!principal.HasClaim(HetUser.PermissionClaim, HetPermission.Login) && + !principal.HasClaim(HetUser.PermissionClaim, HetPermission.BusinessLogin)) { return (false, $"{Constants.MissingDbUserIdError} {userSettings.UserId}"); } diff --git a/Server/HetsApi/Controllers/AttachmentController.cs b/Server/HetsApi/Controllers/AttachmentController.cs index 056ccae73..28985f730 100644 --- a/Server/HetsApi/Controllers/AttachmentController.cs +++ b/Server/HetsApi/Controllers/AttachmentController.cs @@ -24,13 +24,6 @@ public AttachmentController(DbAppContext context, IConfiguration configuration, { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/AttachmentUploadController.cs b/Server/HetsApi/Controllers/AttachmentUploadController.cs index f5ac6b1e2..5f2a4de78 100644 --- a/Server/HetsApi/Controllers/AttachmentUploadController.cs +++ b/Server/HetsApi/Controllers/AttachmentUploadController.cs @@ -26,13 +26,6 @@ public class AttachmentUploadController : Controller public AttachmentUploadController(DbAppContext context, IHttpContextAccessor httpContextAccessor) { _context = context; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/BusinessController.cs b/Server/HetsApi/Controllers/BusinessController.cs index 680f8b2fa..5a6b8293c 100644 --- a/Server/HetsApi/Controllers/BusinessController.cs +++ b/Server/HetsApi/Controllers/BusinessController.cs @@ -33,13 +33,6 @@ public BusinessController(DbAppContext context, IConfiguration configuration, IH _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _env = hostingEnv; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } #region Get Business for the logged on business user @@ -269,7 +262,7 @@ public virtual IActionResult BceidOwnerEquipmentGet([FromRoute]int id) private bool CanAccessOwner(int businessId, int ownerId) { // validate that the current user can access this record - string userId = UserAccountHelper.GetUserId(_httpContext); + string userId = _context.SmUserId; bool isBusiness = UserAccountHelper.IsBusiness(_httpContext); // not a business user @@ -293,7 +286,7 @@ private bool CanAccessOwner(int businessId, int ownerId) private bool CanAccessBusiness(int businessId) { // validate that the current user can access this record - string userId = UserAccountHelper.GetUserId(_httpContext); + string userId = _context.SmUserId; bool isBusiness = UserAccountHelper.IsBusiness(_httpContext); // not a business user diff --git a/Server/HetsApi/Controllers/ConditionTypeController.cs b/Server/HetsApi/Controllers/ConditionTypeController.cs index 7b8b79185..de68cb9a0 100644 --- a/Server/HetsApi/Controllers/ConditionTypeController.cs +++ b/Server/HetsApi/Controllers/ConditionTypeController.cs @@ -26,13 +26,6 @@ public ConditionTypeController(DbAppContext context, IConfiguration configuratio { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/ContactController.cs b/Server/HetsApi/Controllers/ContactController.cs index dc37b96a5..c6373475e 100644 --- a/Server/HetsApi/Controllers/ContactController.cs +++ b/Server/HetsApi/Controllers/ContactController.cs @@ -24,13 +24,6 @@ public ContactController(DbAppContext context, IConfiguration configuration, IHt { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/CountController.cs b/Server/HetsApi/Controllers/CountController.cs index fc2ebdf27..7b3daf632 100644 --- a/Server/HetsApi/Controllers/CountController.cs +++ b/Server/HetsApi/Controllers/CountController.cs @@ -40,13 +40,6 @@ public CountController(DbAppContext context, IConfiguration configuration, IHttp _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } [HttpGet] diff --git a/Server/HetsApi/Controllers/CurrentUserController.cs b/Server/HetsApi/Controllers/CurrentUserController.cs index 5aa7ed792..781075296 100644 --- a/Server/HetsApi/Controllers/CurrentUserController.cs +++ b/Server/HetsApi/Controllers/CurrentUserController.cs @@ -38,13 +38,6 @@ public CurrentUserController(DbAppContext context, IConfiguration configuration, _logger = loggerFactory.CreateLogger(typeof(CurrentUserController)); _env = env; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, _httpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/DistrictController.cs b/Server/HetsApi/Controllers/DistrictController.cs index 1870b80aa..eaac8017d 100644 --- a/Server/HetsApi/Controllers/DistrictController.cs +++ b/Server/HetsApi/Controllers/DistrictController.cs @@ -40,13 +40,6 @@ public DistrictController(DbAppContext context, IConfiguration configuration, IH _configuration = configuration; _annualRollover = annualRollover; _monitoringApi = JobStorage.Current.GetMonitoringApi(); - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs index 7aa678a0d..b4f8b1a60 100644 --- a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs +++ b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs @@ -33,13 +33,6 @@ public DistrictEquipmentTypeController(DbAppContext context, IConfiguration conf { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/EquipmentAttachmentController.cs b/Server/HetsApi/Controllers/EquipmentAttachmentController.cs index e5092e80a..3cd84d426 100644 --- a/Server/HetsApi/Controllers/EquipmentAttachmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentAttachmentController.cs @@ -26,13 +26,6 @@ public EquipmentAttachmentController(DbAppContext context, IConfiguration config { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index cc7257917..3d694451a 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -37,13 +37,6 @@ public EquipmentController(DbAppContext context, IConfiguration configuration, I _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _logger = loggerFactory.CreateLogger(); - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/EquipmentTypeController.cs b/Server/HetsApi/Controllers/EquipmentTypeController.cs index e27cf4d12..8a7a0e553 100644 --- a/Server/HetsApi/Controllers/EquipmentTypeController.cs +++ b/Server/HetsApi/Controllers/EquipmentTypeController.cs @@ -22,13 +22,6 @@ public class EquipmentTypeController : Controller public EquipmentTypeController(DbAppContext context, IHttpContextAccessor httpContextAccessor) { _context = context; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/NoteController.cs b/Server/HetsApi/Controllers/NoteController.cs index 254d400ac..b194a803f 100644 --- a/Server/HetsApi/Controllers/NoteController.cs +++ b/Server/HetsApi/Controllers/NoteController.cs @@ -24,13 +24,6 @@ public NoteController(DbAppContext context, IConfiguration configuration, IHttpC { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/OwnerController.cs b/Server/HetsApi/Controllers/OwnerController.cs index ec1ba62b7..619ed975f 100644 --- a/Server/HetsApi/Controllers/OwnerController.cs +++ b/Server/HetsApi/Controllers/OwnerController.cs @@ -60,13 +60,6 @@ public OwnerController(DbAppContext context, IConfiguration configuration, IHttp _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _logger = loggerFactory.CreateLogger(); - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/PermissionController.cs b/Server/HetsApi/Controllers/PermissionController.cs index 18bb1fb3f..f8eec10e3 100644 --- a/Server/HetsApi/Controllers/PermissionController.cs +++ b/Server/HetsApi/Controllers/PermissionController.cs @@ -24,13 +24,6 @@ public class PermissionController : Controller public PermissionController(DbAppContext context, IHttpContextAccessor httpContextAccessor) { _context = context; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/ProjectController.cs b/Server/HetsApi/Controllers/ProjectController.cs index c17333630..af5700ddc 100644 --- a/Server/HetsApi/Controllers/ProjectController.cs +++ b/Server/HetsApi/Controllers/ProjectController.cs @@ -31,13 +31,6 @@ public ProjectController(DbAppContext context, IConfiguration configuration, IHt _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/ProvincialRateTypeController.cs b/Server/HetsApi/Controllers/ProvincialRateTypeController.cs index 34cdbff09..93c370c7e 100644 --- a/Server/HetsApi/Controllers/ProvincialRateTypeController.cs +++ b/Server/HetsApi/Controllers/ProvincialRateTypeController.cs @@ -26,13 +26,6 @@ public ProvincialRateTypeController(DbAppContext context, IConfiguration configu { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RegionController.cs b/Server/HetsApi/Controllers/RegionController.cs index bfe33e720..efed138a1 100644 --- a/Server/HetsApi/Controllers/RegionController.cs +++ b/Server/HetsApi/Controllers/RegionController.cs @@ -23,13 +23,6 @@ public class RegionController : Controller public RegionController(DbAppContext context, IHttpContextAccessor httpContextAccessor) { _context = context; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RentalAgreementConditionController.cs b/Server/HetsApi/Controllers/RentalAgreementConditionController.cs index bcaca2509..3d2805551 100644 --- a/Server/HetsApi/Controllers/RentalAgreementConditionController.cs +++ b/Server/HetsApi/Controllers/RentalAgreementConditionController.cs @@ -25,13 +25,6 @@ public RentalAgreementConditionController(DbAppContext context, IConfiguration c { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RentalAgreementController.cs b/Server/HetsApi/Controllers/RentalAgreementController.cs index 255dba469..13e9f4270 100644 --- a/Server/HetsApi/Controllers/RentalAgreementController.cs +++ b/Server/HetsApi/Controllers/RentalAgreementController.cs @@ -36,13 +36,6 @@ public RentalAgreementController(DbAppContext context, IConfiguration configurat _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _logger = loggerFactory.CreateLogger(); - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RentalAgreementRateController.cs b/Server/HetsApi/Controllers/RentalAgreementRateController.cs index 699157140..f4297cef7 100644 --- a/Server/HetsApi/Controllers/RentalAgreementRateController.cs +++ b/Server/HetsApi/Controllers/RentalAgreementRateController.cs @@ -26,13 +26,6 @@ public RentalAgreementRateController(DbAppContext context, IConfiguration config { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RentalRequestController.cs b/Server/HetsApi/Controllers/RentalRequestController.cs index f61166588..cf3150f86 100644 --- a/Server/HetsApi/Controllers/RentalRequestController.cs +++ b/Server/HetsApi/Controllers/RentalRequestController.cs @@ -31,13 +31,6 @@ public RentalRequestController(DbAppContext context, IConfiguration configuratio _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/ReportController.cs b/Server/HetsApi/Controllers/ReportController.cs index 65ec9509f..ffed92525 100644 --- a/Server/HetsApi/Controllers/ReportController.cs +++ b/Server/HetsApi/Controllers/ReportController.cs @@ -39,13 +39,6 @@ public ReportController(DbAppContext context, IConfiguration configuration, IHtt _context = context; _httpContext = httpContextAccessor.HttpContext; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/RoleController.cs b/Server/HetsApi/Controllers/RoleController.cs index f3cc774b5..1b2311a92 100644 --- a/Server/HetsApi/Controllers/RoleController.cs +++ b/Server/HetsApi/Controllers/RoleController.cs @@ -27,13 +27,6 @@ public RoleController(DbAppContext context, IConfiguration configuration, IHttpC { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/ServiceAreaController.cs b/Server/HetsApi/Controllers/ServiceAreaController.cs index 4bb632e02..ded051562 100644 --- a/Server/HetsApi/Controllers/ServiceAreaController.cs +++ b/Server/HetsApi/Controllers/ServiceAreaController.cs @@ -23,13 +23,6 @@ public class ServiceAreaController : Controller public ServiceAreaController(DbAppContext context, IHttpContextAccessor httpContextAccessor) { _context = context; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/TimeRecordController.cs b/Server/HetsApi/Controllers/TimeRecordController.cs index 11cd816d8..01c8eff7f 100644 --- a/Server/HetsApi/Controllers/TimeRecordController.cs +++ b/Server/HetsApi/Controllers/TimeRecordController.cs @@ -30,13 +30,6 @@ public TimeRecordController(DbAppContext context, IConfiguration configuration, _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/UserController.cs b/Server/HetsApi/Controllers/UserController.cs index b3be70072..1a8b27da2 100644 --- a/Server/HetsApi/Controllers/UserController.cs +++ b/Server/HetsApi/Controllers/UserController.cs @@ -27,13 +27,6 @@ public UserController(DbAppContext context, IConfiguration configuration, IHttpC { _context = context; _configuration = configuration; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Controllers/UserDistrictsController.cs b/Server/HetsApi/Controllers/UserDistrictsController.cs index ee7a804c5..446fdd242 100644 --- a/Server/HetsApi/Controllers/UserDistrictsController.cs +++ b/Server/HetsApi/Controllers/UserDistrictsController.cs @@ -29,13 +29,6 @@ public UserDistrictController(DbAppContext context, IConfiguration configuration _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// @@ -49,7 +42,7 @@ public UserDistrictController(DbAppContext context, IConfiguration configuration public virtual IActionResult UserDistrictsGet() { // return for the current user only - string userId = UserAccountHelper.GetUserId(_httpContext); + string userId = _context.SmUserId; List result = _context.HetUserDistrict.AsNoTracking() .Include(x => x.User) @@ -295,7 +288,7 @@ public virtual IActionResult UserDistrictsIdSwitchPost([FromRoute]int id) // get record HetUserDistrict userDistrict = _context.HetUserDistrict.First(a => a.UserDistrictId == id); - string userId = UserAccountHelper.GetUserId(_httpContext); + string userId = _context.SmUserId; HetUser user = _context.HetUser.First(a => a.SmUserId == userId); user.DistrictId = userDistrict.DistrictId; diff --git a/Server/HetsApi/Controllers/VersionController.cs b/Server/HetsApi/Controllers/VersionController.cs index 70064be18..6d9a9b256 100644 --- a/Server/HetsApi/Controllers/VersionController.cs +++ b/Server/HetsApi/Controllers/VersionController.cs @@ -30,13 +30,6 @@ public VersionController(DbAppContext context, IConfiguration configuration, IHt _context = context; _configuration = configuration; _env = env; - - // set context data - User user = UserAccountHelper.GetUser(context, httpContextAccessor.HttpContext); - _context.SmUserId = user.SmUserId; - _context.DirectoryName = user.SmAuthorizationDirectory; - _context.SmUserGuid = user.UserGuid; - _context.SmBusinessGuid = user.BusinessGuid; } /// diff --git a/Server/HetsApi/Helpers/UserAccountHelper.cs b/Server/HetsApi/Helpers/UserAccountHelper.cs index 70e9f389a..f30145adf 100644 --- a/Server/HetsApi/Helpers/UserAccountHelper.cs +++ b/Server/HetsApi/Helpers/UserAccountHelper.cs @@ -21,17 +21,6 @@ public static class UserAccountHelper private const string ConstSiteMinderBusinessLegalName = "smgov_businesslegalname"; private const string ConstSiteMinderBusinessNumber = "smgov_businessnumber"; - /// - /// Get user id from http context - /// - /// - /// - public static string GetUserId(HttpContext httpContext) - { - string userId = httpContext.User.Identity.Name; - return userId; - } - /// /// Check if this is a Business User /// @@ -84,7 +73,7 @@ public static string GetBusinessGuid(HttpContext httpContext, IWebHostEnvironmen /// public static int? GetUsersDistrictId(DbAppContext context, HttpContext httpContext) { - string userId = GetUserId(httpContext); + string userId = context.SmUserId; int? districtId = context.HetUser.FirstOrDefault(x => x.SmUserId == userId)?.DistrictId; return districtId; } @@ -101,7 +90,7 @@ public static User GetUser(DbAppContext context, HttpContext httpContext) // is this a business? bool isBusinessUser = IsBusiness(httpContext); - string userId = GetUserId(httpContext)?.ToLower(); + string userId = context.SmUserId; if (!isBusinessUser) { diff --git a/Server/HetsData/Extension/HetBusinessUserExtension.cs b/Server/HetsData/Extension/HetBusinessUserExtension.cs index 56298c63f..dc0f51110 100644 --- a/Server/HetsData/Extension/HetBusinessUserExtension.cs +++ b/Server/HetsData/Extension/HetBusinessUserExtension.cs @@ -24,12 +24,12 @@ public partial class HetBusinessUser /// public ClaimsPrincipal ToClaimsPrincipal(string authenticationType) { - return new ClaimsPrincipal(ToClaimsIdentity(authenticationType)); + return new ClaimsPrincipal(ToClaimsIdentity()); } - private ClaimsIdentity ToClaimsIdentity(string authenticationType) + public ClaimsIdentity ToClaimsIdentity() { - return new ClaimsIdentity(GetClaims(), authenticationType); + return new ClaimsIdentity(GetClaims()); } private List GetClaims() diff --git a/Server/HetsData/Extension/HetUserExtension.cs b/Server/HetsData/Extension/HetUserExtension.cs index 4e79ee8a2..87def8db8 100644 --- a/Server/HetsData/Extension/HetUserExtension.cs +++ b/Server/HetsData/Extension/HetUserExtension.cs @@ -24,12 +24,12 @@ public partial class HetUser /// public ClaimsPrincipal ToClaimsPrincipal(string authenticationType) { - return new ClaimsPrincipal(ToClaimsIdentity(authenticationType)); + return new ClaimsPrincipal(ToClaimsIdentity()); } - private ClaimsIdentity ToClaimsIdentity(string authenticationType) + public ClaimsIdentity ToClaimsIdentity() { - return new ClaimsIdentity(GetClaims(), authenticationType); + return new ClaimsIdentity(GetClaims()); } private List GetClaims() diff --git a/client/.env.development b/client/.env.development new file mode 100644 index 000000000..9e83b9429 --- /dev/null +++ b/client/.env.development @@ -0,0 +1,5 @@ +BROWSER=none +REACT_APP_API_HOST=http://localhost:27238 +REACT_APP_SSO_CLIENT=hmcr-public-dev +REACT_APP_SSO_REALM=fygf50pt +REACT_APP_SSO_HOST=https://dev.oidc.gov.bc.ca/auth diff --git a/client/.env.production b/client/.env.production new file mode 100644 index 000000000..ba7cc18de --- /dev/null +++ b/client/.env.production @@ -0,0 +1 @@ +GENERATE_SOURCEMAP=false diff --git a/client/.prettierrc b/client/.prettierrc new file mode 100644 index 000000000..9bd686331 --- /dev/null +++ b/client/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 120, + "trailingComma": "es5", + "tabWidth": 2, + "singleQuote": true +} diff --git a/client/package-lock.json b/client/package-lock.json index ffd1bbe87..2f8621658 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9700,6 +9700,11 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -9862,6 +9867,22 @@ "object.assign": "^4.1.2" } }, + "keycloak-js": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-13.0.1.tgz", + "integrity": "sha512-S9mFX8HHlgw+i2HAIhteccrkffQmUn4CpYcU8ViGnODSBcnaf2YTtLhiiRH/a6SaOBpxmJTN3XVIZbE9d/HyXQ==", + "requires": { + "base64-js": "1.3.1", + "js-sha256": "0.9.0" + }, + "dependencies": { + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + } + } + }, "keycode": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", diff --git a/client/package.json b/client/package.json index bb25ce11b..5dd097c02 100644 --- a/client/package.json +++ b/client/package.json @@ -11,6 +11,7 @@ "classnames": "^2.2.6", "http-proxy-middleware": "^2.0.0", "immer": "^9.0.2", + "keycloak-js": "^13.0.1", "lodash": "^4.17.21", "moment": "^2.22.2", "node-sass": "^4.14.1", diff --git a/client/src/index.js b/client/src/index.js index 7b5a6e7b8..4c623905d 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,18 +1,21 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import App from "./js/App"; -import reportWebVitals from "./reportWebVitals"; +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './js/App'; +import reportWebVitals from './reportWebVitals'; -import "bootstrap/dist/css/bootstrap.css"; -import "./sass/main.scss"; +import * as Keycloak from './js/Keycloak'; -ReactDOM.render( - - - , +import 'bootstrap/dist/css/bootstrap.css'; +import './sass/main.scss'; - document.getElementById("root") -); +Keycloak.init(() => { + ReactDOM.render( + + + , + document.getElementById('root') + ); +}); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) diff --git a/client/src/js/Keycloak.js b/client/src/js/Keycloak.js new file mode 100644 index 000000000..6c6544d00 --- /dev/null +++ b/client/src/js/Keycloak.js @@ -0,0 +1,27 @@ +import Keycloak from 'keycloak-js'; + +const keycloakConfig = { + url: window.RUNTIME_REACT_APP_SSO_HOST ? window.RUNTIME_REACT_APP_SSO_HOST : process.env.REACT_APP_SSO_HOST, + realm: window.RUNTIME_REACT_APP_SSO_REALM ? window.RUNTIME_REACT_APP_SSO_REALM : process.env.REACT_APP_SSO_REALM, + clientId: window.RUNTIME_REACT_APP_SSO_CLIENT + ? window.RUNTIME_REACT_APP_SSO_CLIENT + : process.env.REACT_APP_SSO_CLIENT, +}; + +export const keycloak = Keycloak(keycloakConfig); + +export const init = (onSuccess) => { + keycloak.init({ onLoad: 'login-required', promiseType: 'native' }).then((authenticated) => { + if (authenticated && onSuccess) { + onSuccess(); + } + }); + + keycloak.onAuthLogout = () => { + window.location.reload(); + }; +}; + +export const logout = () => { + keycloak.logout(); +}; diff --git a/client/src/js/utils/http.js b/client/src/js/utils/http.js index 0fb7a8e25..e3f5a5fa2 100644 --- a/client/src/js/utils/http.js +++ b/client/src/js/utils/http.js @@ -1,17 +1,15 @@ -import _ from "lodash"; -// import Promise from "bluebird"; +import _ from 'lodash'; -import * as Action from "../actionTypes"; -import store from "../store"; +import * as Action from '../actionTypes'; +import store from '../store'; +import { keycloak } from '../Keycloak'; -import * as Constant from "../constants"; +import * as Constant from '../constants'; -import { resetSessionTimeoutTimer } from "../App.jsx"; +import { resetSessionTimeoutTimer } from '../App.jsx'; const ROOT_API_PREFIX = - window.location.pathname === "/" - ? "" - : window.location.pathname.split("/").slice(0, -1).join("/"); + window.location.pathname === '/' ? '' : window.location.pathname.split('/').slice(0, -1).join('/'); var numRequestsInFlight = 0; @@ -31,7 +29,7 @@ function decrementRequests() { } export const HttpError = function (msg, method, path, status, body) { - this.message = msg || ""; + this.message = msg || ''; this.method = method; this.path = path; this.status = status || null; @@ -42,16 +40,8 @@ HttpError.prototype = Object.create(Error.prototype, { constructor: { value: HttpError }, }); -export const ApiError = function ( - msg, - method, - path, - status, - errorCode, - errorDescription, - json -) { - this.message = msg || ""; +export const ApiError = function (msg, method, path, status, errorCode, errorDescription, json) { + this.message = msg || ''; this.method = method; this.path = path; this.status = status || null; @@ -78,31 +68,35 @@ Resource404.prototype = Object.create(Error.prototype, { }, }); -export function request(path, options) { +export async function request(path, options) { + try { + await keycloak.updateToken(10); + } catch { + console.log('Failed to refresh the token, or the session has expired'); + } + options = options || {}; + options.headers = Object.assign( + { + Authorization: `Bearer ${keycloak.token}`, + }, + options.headers || {} + ); var xhr = new XMLHttpRequest(); - - // calling server service - // console.log('Calling service. Path: ' + path); - - if (!options.headers) { - options.headers = {}; - } + var method = (options.method || 'GET').toUpperCase(); if (!options.files) { options.headers = Object.assign( { - "Content-Type": "application/x-www-form-urlencoded", + 'Content-Type': 'application/x-www-form-urlencoded', }, options.headers ); } - var method = (options.method || "GET").toUpperCase(); - if (options.onUploadProgress) { - xhr.upload.addEventListener("progress", function (e) { + xhr.upload.addEventListener('progress', function (e) { if (e.lengthComputable) { options.onUploadProgress((e.loaded / e.total) * 100); } else { @@ -110,22 +104,22 @@ export function request(path, options) { } }); - xhr.upload.addEventListener("load", function (/*e*/) { + xhr.upload.addEventListener('load', function (/*e*/) { options.onUploadProgress(100); }); } - if (options.responseType && window.navigator.appName !== "Netscape") { + if (options.responseType && window.navigator.appName !== 'Netscape') { xhr.responseType = options.responseType; - } else if (options.responseType && window.navigator.appName === "Netscape") { + } else if (options.responseType && window.navigator.appName === 'Netscape') { xhr.open(options.method, path); xhr.responseType = options.responseType; } return new Promise((resolve, reject) => { - xhr.addEventListener("load", function () { + xhr.addEventListener('load', function () { if (xhr.status >= 400) { - var responseText = ""; + var responseText = ''; try { responseText = xhr.responseText; } catch (e) { @@ -146,17 +140,17 @@ export function request(path, options) { } }); - xhr.addEventListener("error", function () { - reject( - new HttpError(`Request ${method} ${path} failed to send`, method, path) - ); + xhr.addEventListener('error', function () { + reject(new HttpError(`Request ${method} ${path} failed to send`, method, path)); }); - var qs = _.map( - options.querystring, - (value, key) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}` - ).join("&"); - xhr.open(method, `${path}${qs ? "?" : ""}${qs}`, true); + var qs = _.map(options.querystring, (value, key) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join( + '&' + ); + + if (options.responseType) xhr.responseType = options.responseType; + + xhr.open(method, `${path}${qs ? '?' : ''}${qs}`, true); Object.keys(options.headers).forEach((key) => { xhr.setRequestHeader(key, options.headers[key]); @@ -170,13 +164,13 @@ export function request(path, options) { if (options.files) { payload = new FormData(); - if (typeof options.body === "object") { + if (typeof options.body === 'object') { Object.keys(options.body).forEach((key) => { payload.append(key, options.body[key]); }); } options.files.forEach((file) => { - payload.append("files", file, file.name); + payload.append('files', file, file.name); }); } @@ -194,12 +188,12 @@ export function jsonRequest(path, options) { } var jsonHeaders = { - Accept: "application/json", + Accept: 'application/json', }; if (options.body) { options.body = JSON.stringify(options.body); - jsonHeaders["Content-Type"] = "application/json"; + jsonHeaders['Content-Type'] = 'application/json'; } options.headers = Object.assign(options.headers || {}, jsonHeaders); @@ -240,15 +234,7 @@ export function jsonRequest(path, options) { /* not json */ } - throw new ApiError( - errMsg, - err.method, - err.path, - err.status, - errorCode, - errorDescription, - json - ); + throw new ApiError(errMsg, err.method, err.path, err.status, errorCode, errorDescription, json); } else { throw err; } @@ -256,7 +242,7 @@ export function jsonRequest(path, options) { } export function buildApiPath(path) { - return `${ROOT_API_PREFIX}/api/${path}`.replace("//", "/"); // remove double slashes + return `${ROOT_API_PREFIX}/api/${path}`.replace('//', '/'); // remove double slashes } export function ApiRequest(path, options) { @@ -266,7 +252,7 @@ export function ApiRequest(path, options) { ApiRequest.prototype.get = function apiGet(params, options) { return jsonRequest(this.path, { - method: "GET", + method: 'GET', querystring: params, ...this.options, ...options, @@ -275,7 +261,7 @@ ApiRequest.prototype.get = function apiGet(params, options) { ApiRequest.prototype.post = function apiPost(data, options) { return jsonRequest(this.path, { - method: "POST", + method: 'POST', body: data, ...this.options, ...options, @@ -284,7 +270,7 @@ ApiRequest.prototype.post = function apiPost(data, options) { ApiRequest.prototype.put = function apiPut(data, options) { return jsonRequest(this.path, { - method: "PUT", + method: 'PUT', body: data, ...this.options, ...options, @@ -293,7 +279,7 @@ ApiRequest.prototype.put = function apiPut(data, options) { ApiRequest.prototype.delete = function apiDelete(data, options) { return jsonRequest(this.path, { - method: "DELETE", + method: 'DELETE', body: data, ...this.options, ...options, diff --git a/client/src/setupProxy.js b/client/src/setupProxy.js index 6350bf763..6dea88330 100644 --- a/client/src/setupProxy.js +++ b/client/src/setupProxy.js @@ -1,11 +1,10 @@ -const { createProxyMiddleware } = require("http-proxy-middleware"); +const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function (app) { - debugger; app.use( - "/api", + '/api', createProxyMiddleware({ - target: process.env.REACT_APP_API_HOST || "http://localhost:27238", + target: process.env.REACT_APP_API_HOST || 'http://localhost:27238', changeOrigin: true, }) ); From af820a9a47d8a039b0d7417f346e0e7b624f0da9 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 10 Jun 2021 12:17:30 -0700 Subject: [PATCH 031/352] Keycloak for IDIR --- .pipeline/lib/clean.js | 4 + .pipeline/lib/deploy.js | 5 +- .pipeline/lib/keycloak.js | 130 ++++++++++++++++++ .pipeline/package-lock.json | 13 ++ .pipeline/package.json | 3 +- client/.env.development | 2 +- client/nginx-start/start.sh | 13 +- client/public/index.html | 6 +- openshift/api-deploy-config.yaml | 10 ++ openshift/client-deploy-config.yaml | 17 +++ .../keycloak-service-account-secrets.yaml | Bin 0 -> 2152 bytes openshift/secrets/sso-secrets.yaml | Bin 0 -> 3100 bytes 12 files changed, 189 insertions(+), 14 deletions(-) create mode 100644 .pipeline/lib/keycloak.js create mode 100644 openshift/secrets/keycloak-service-account-secrets.yaml create mode 100644 openshift/secrets/sso-secrets.yaml diff --git a/.pipeline/lib/clean.js b/.pipeline/lib/clean.js index 990583838..75ff36113 100644 --- a/.pipeline/lib/clean.js +++ b/.pipeline/lib/clean.js @@ -1,5 +1,6 @@ "use strict"; const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); +const KeyCloakClient = require("./keycloak"); const getTargetPhases = (env, phases) => { let target_phase = []; @@ -22,11 +23,14 @@ module.exports = (settings) => { Object.assign({ namespace: phases.build.namespace }, options) ); const target_phases = getTargetPhases(options.env, phases); + const kc = new KeyCloakClient(settings, oc); target_phases.forEach((k) => { if (phases.hasOwnProperty(k)) { const phase = phases[k]; + if (k === "dev") kc.remmoveUris(); + let buildConfigs = oc.get("bc", { selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`, namespace: phase.namespace, diff --git a/.pipeline/lib/deploy.js b/.pipeline/lib/deploy.js index 45cb1a4e9..28a86a38d 100644 --- a/.pipeline/lib/deploy.js +++ b/.pipeline/lib/deploy.js @@ -3,6 +3,7 @@ const { OpenShiftClientX } = require("@bcgov/pipeline-cli"); const path = require("path"); const util = require("./utils"); +const KeyCloakClient = require("./keycloak"); module.exports = (settings) => { const phases = settings.phases; @@ -17,13 +18,15 @@ module.exports = (settings) => { path.resolve(__dirname, "../../openshift") ); var objects = []; - + const kc = new KeyCloakClient(settings, oc); const dbSecret = util.getSecret( oc, phases[phase].namespace, `${phases[phase].name}-db-${phases[phase].phase}` ); + kc.addUris(); + if (!dbSecret) { console.log("Adding Db postgresql secret"); diff --git a/.pipeline/lib/keycloak.js b/.pipeline/lib/keycloak.js new file mode 100644 index 000000000..7d4710dec --- /dev/null +++ b/.pipeline/lib/keycloak.js @@ -0,0 +1,130 @@ +"use strict"; +const axios = require("axios"); +const _ = require("lodash"); + +const util = require("./utils"); + +module.exports = class KeyCloakClient { + constructor(settings, oc) { + this.phases = settings.phases; + this.options = settings.options; + this.oc = oc; + this.appHost = this.phases.dev.host; + } + + async init() { + this.getSecrets(); + + this.apiTokenPath = `/auth/realms/${this.realmId}/protocol/openid-connect/token`; + this.appClientPath = `auth/admin/realms/${this.realmId}/clients/${this.appClientId}`; + this.api = axios.create({ + baseURL: `https://${this.ssoHost}`, + }); + + const token = await this.getAccessToken(); + + this.api.defaults.headers.common = { + Authorization: `Bearer ${token}`, + }; + } + + getSecrets() { + const secret = util.getSecret( + this.oc, + this.phases.build.namespace, + "keycloak-service-account" + ); + + this.clientId = Buffer.from(secret.clientId, "base64").toString(); + this.clientSecret = Buffer.from(secret.clientSecret, "base64").toString(); + this.appClientId = Buffer.from(secret.appClientId, "base64").toString(); + this.realmId = Buffer.from(secret.realmId, "base64").toString(); + this.ssoHost = Buffer.from(secret.host, "base64").toString(); + + if (!this.clientId || !this.clientSecret || !this.appClientId) + throw new Error( + "Unable to retrieve Keycloak service account info from OpenShift" + ); + } + + getAccessToken() { + return this.api + .post(this.apiTokenPath, "grant_type=client_credentials", { + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + auth: { + username: this.clientId, + password: this.clientSecret, + }, + }) + .then(function (response) { + if (!response.data.access_token) + throw new Error( + "Unable to retrieve Keycloak service account access token" + ); + + return Promise.resolve(response.data.access_token); + }); + } + + async getUris() { + const response = await this.api.get(this.appClientPath); + + const data = { ...response.data }; + const redirectUris = data.redirectUris; + + return { data, redirectUris }; + } + + async addUris() { + await this.init(); + + console.log("Attempting to add RedirectUri and WebOrigins"); + + const { data, redirectUris } = await this.getUris(); + const putData = { id: data.id, clientId: data.clientId }; + + const hasRedirectUris = redirectUris.find((item) => + item.includes(this.appHost) + ); + + if (!hasRedirectUris) { + redirectUris.push(`https://${this.appHost}/*`); + putData.redirectUris = redirectUris; + } + + if (!hasRedirectUris) { + this.api + .put(this.appClientPath, putData) + .then(() => console.log("RedirectUri and WebOrigins added.")); + } else { + console.log("RedirectUri and WebOrigins add skipped."); + } + } + + async remmoveUris() { + await this.init(); + + console.log("Attempting to remove RedirectUri and WebOrigins"); + + const { data, redirectUris } = await this.getUris(); + const putData = { id: data.id, clientId: data.clientId }; + + const hasRedirectUris = redirectUris.find((item) => + item.includes(this.appHost) + ); + + if (hasRedirectUris) { + putData.redirectUris = redirectUris.filter( + (item) => !item.includes(this.appHost) + ); + } + + if (hasRedirectUris) { + this.api + .put(this.appClientPath, putData) + .then(() => console.log("RedirectUri and WebOrigins removed.")); + } else { + console.log("RedirectUri and WebOrigins remove skipped."); + } + } +}; diff --git a/.pipeline/package-lock.json b/.pipeline/package-lock.json index 10aadbae1..518c1d893 100644 --- a/.pipeline/package-lock.json +++ b/.pipeline/package-lock.json @@ -17,6 +17,14 @@ "snakecase-keys": "^3.1.0" } }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -25,6 +33,11 @@ "ms": "^2.1.1" } }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" + }, "lodash.isempty": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", diff --git a/.pipeline/package.json b/.pipeline/package.json index c2f445d13..9fe5fbcdd 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,6 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "^1.0.1-0" + "@bcgov/pipeline-cli": "^1.0.1-0", + "axios": "^0.21.1" } } diff --git a/client/.env.development b/client/.env.development index 9e83b9429..ffd76e144 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,5 +1,5 @@ BROWSER=none REACT_APP_API_HOST=http://localhost:27238 -REACT_APP_SSO_CLIENT=hmcr-public-dev +REACT_APP_SSO_CLIENT=moti-idir-biz-dev REACT_APP_SSO_REALM=fygf50pt REACT_APP_SSO_HOST=https://dev.oidc.gov.bc.ca/auth diff --git a/client/nginx-start/start.sh b/client/nginx-start/start.sh index 0afa627a3..722b0e58d 100644 --- a/client/nginx-start/start.sh +++ b/client/nginx-start/start.sh @@ -1,13 +1,12 @@ #!/bin/sh -#echo "---> Setting window.RUNTIME_REACT_APP values ..." -#JS_PATH=~/js/env.config.js +echo "---> Setting window.RUNTIME_REACT_APP values ..." +JS_PATH=~/js/env.config.js -#echo "window.RUNTIME_REACT_APP_SSO_HOST='${REACT_APP_SSO_HOST}';" > $JS_PATH -#echo "window.RUNTIME_REACT_APP_SSO_REALM='${REACT_APP_SSO_REALM}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_SSO_CLIENT='${REACT_APP_SSO_CLIENT}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_API_HOST='${REACT_APP_API_HOST}';" >> $JS_PATH -#echo "window.RUNTIME_REACT_APP_DWPBI_URL='${REACT_APP_DWPBI_URL}';" >> $JS_PATH +echo "window.RUNTIME_REACT_APP_SSO_HOST='${REACT_APP_SSO_HOST}';" > $JS_PATH +echo "window.RUNTIME_REACT_APP_SSO_REALM='${REACT_APP_SSO_REALM}';" >> $JS_PATH +echo "window.RUNTIME_REACT_APP_SSO_CLIENT='${REACT_APP_SSO_CLIENT}';" >> $JS_PATH +echo "window.RUNTIME_REACT_APP_API_HOST='${REACT_APP_API_HOST}';" >> $JS_PATH echo "---> Creating nginx.conf ..." envsubst '${HETS_DEPLOY_SUFFIX}' < /tmp/src/nginx.conf.tmpl > /etc/nginx/nginx.conf \ No newline at end of file diff --git a/client/public/index.html b/client/public/index.html index fdf3af75e..7ee04666e 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -5,16 +5,14 @@ - + + - - - - - diff --git a/Server/HetsData/Model/Counter.cs b/Server/HetsData/Entities/Counter.cs similarity index 91% rename from Server/HetsData/Model/Counter.cs rename to Server/HetsData/Entities/Counter.cs index 07915e650..10a7611ea 100644 --- a/Server/HetsData/Model/Counter.cs +++ b/Server/HetsData/Entities/Counter.cs @@ -3,7 +3,7 @@ #nullable disable -namespace HetsData.Model +namespace HetsData.Entities { public partial class Counter { diff --git a/Server/HetsData/Entities/DbAppContext.cs b/Server/HetsData/Entities/DbAppContext.cs new file mode 100644 index 000000000..cac2cfc6e --- /dev/null +++ b/Server/HetsData/Entities/DbAppContext.cs @@ -0,0 +1,5552 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class DbAppContext : DbContext + { + public DbAppContext() + { + } + + public DbAppContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet HetBatchReports { get; set; } + public virtual DbSet HetBusinesses { get; set; } + public virtual DbSet HetBusinessUsers { get; set; } + public virtual DbSet HetBusinessUserRoles { get; set; } + public virtual DbSet HetConditionTypes { get; set; } + public virtual DbSet HetContacts { get; set; } + public virtual DbSet HetDigitalFiles { get; set; } + public virtual DbSet HetDistricts { get; set; } + public virtual DbSet HetDistrictEquipmentTypes { get; set; } + public virtual DbSet HetDistrictStatuses { get; set; } + public virtual DbSet HetEquipments { get; set; } + public virtual DbSet HetEquipmentAttachments { get; set; } + public virtual DbSet HetEquipmentAttachmentHists { get; set; } + public virtual DbSet HetEquipmentHists { get; set; } + public virtual DbSet HetEquipmentStatusTypes { get; set; } + public virtual DbSet HetEquipmentTypes { get; set; } + public virtual DbSet HetHistories { get; set; } + public virtual DbSet HetImportMaps { get; set; } + public virtual DbSet HetLocalAreas { get; set; } + public virtual DbSet HetLocalAreaRotationLists { get; set; } + public virtual DbSet HetMimeTypes { get; set; } + public virtual DbSet HetNotes { get; set; } + public virtual DbSet HetNoteHists { get; set; } + public virtual DbSet HetOwners { get; set; } + public virtual DbSet HetOwnerStatusTypes { get; set; } + public virtual DbSet HetPermissions { get; set; } + public virtual DbSet HetPeople { get; set; } + public virtual DbSet HetProjects { get; set; } + public virtual DbSet HetProjectStatusTypes { get; set; } + public virtual DbSet HetProvincialRateTypes { get; set; } + public virtual DbSet HetRatePeriodTypes { get; set; } + public virtual DbSet HetRegions { get; set; } + public virtual DbSet HetRentalAgreements { get; set; } + public virtual DbSet HetRentalAgreementConditions { get; set; } + public virtual DbSet HetRentalAgreementConditionHists { get; set; } + public virtual DbSet HetRentalAgreementHists { get; set; } + public virtual DbSet HetRentalAgreementRates { get; set; } + public virtual DbSet HetRentalAgreementRateHists { get; set; } + public virtual DbSet HetRentalAgreementStatusTypes { get; set; } + public virtual DbSet HetRentalRequests { get; set; } + public virtual DbSet HetRentalRequestAttachments { get; set; } + public virtual DbSet HetRentalRequestRotationLists { get; set; } + public virtual DbSet HetRentalRequestRotationListHists { get; set; } + public virtual DbSet HetRentalRequestStatusTypes { get; set; } + public virtual DbSet HetRoles { get; set; } + public virtual DbSet HetRolePermissions { get; set; } + public virtual DbSet HetRolloverProgresses { get; set; } + public virtual DbSet HetSeniorityAudits { get; set; } + public virtual DbSet HetServiceAreas { get; set; } + public virtual DbSet HetTimePeriodTypes { get; set; } + public virtual DbSet HetTimeRecords { get; set; } + public virtual DbSet HetTimeRecordHists { get; set; } + public virtual DbSet HetUsers { get; set; } + public virtual DbSet HetUserDistricts { get; set; } + public virtual DbSet HetUserFavourites { get; set; } + public virtual DbSet HetUserRoles { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.HasAnnotation("Relational:Collation", "en_US.utf8"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ReportId); + + entity.ToTable("HET_BATCH_REPORT"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_BATCH_REPORT_DISTRICT_ID"); + + entity.Property(e => e.ReportId) + .HasColumnName("REPORT_ID") + .HasDefaultValueSql("nextval('\"HET_BATCH_REPORT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Complete).HasColumnName("COMPLETE"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.ReportLink) + .HasMaxLength(500) + .HasColumnName("REPORT_LINK"); + + entity.Property(e => e.ReportName) + .HasMaxLength(100) + .HasColumnName("REPORT_NAME"); + + entity.Property(e => e.StartDate).HasColumnName("START_DATE"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetBatchReports) + .HasForeignKey(d => d.DistrictId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_BATCH_REPORT_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.BusinessId); + + entity.ToTable("HET_BUSINESS"); + + entity.HasIndex(e => e.BceidBusinessGuid, "HET_BUSINESS_GUID_UK") + .IsUnique(); + + entity.HasIndex(e => e.BceidBusinessGuid, "IX_HET_BUSINESS_BUSINESS_GUID"); + + entity.Property(e => e.BusinessId) + .HasColumnName("BUSINESS_ID") + .HasDefaultValueSql("nextval('\"HET_BUSINESS_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BceidBusinessGuid) + .HasMaxLength(50) + .HasColumnName("BCEID_BUSINESS_GUID"); + + entity.Property(e => e.BceidBusinessNumber) + .HasMaxLength(50) + .HasColumnName("BCEID_BUSINESS_NUMBER"); + + entity.Property(e => e.BceidDoingBusinessAs) + .HasMaxLength(150) + .HasColumnName("BCEID_DOING_BUSINESS_AS"); + + entity.Property(e => e.BceidLegalName) + .HasMaxLength(150) + .HasColumnName("BCEID_LEGAL_NAME"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.BusinessUserId); + + entity.ToTable("HET_BUSINESS_USER"); + + entity.HasIndex(e => e.BusinessId, "IX_HET_BUSINESS_USER_BUSINESS_ID"); + + entity.HasIndex(e => e.BceidGuid, "IX_HET_BUSINESS_USER_GUID"); + + entity.Property(e => e.BusinessUserId) + .HasColumnName("BUSINESS_USER_ID") + .HasDefaultValueSql("nextval('\"HET_BUSINESS_USER_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BceidDisplayName) + .HasMaxLength(150) + .HasColumnName("BCEID_DISPLAY_NAME"); + + entity.Property(e => e.BceidEmail) + .HasMaxLength(150) + .HasColumnName("BCEID_EMAIL"); + + entity.Property(e => e.BceidFirstName) + .HasMaxLength(150) + .HasColumnName("BCEID_FIRST_NAME"); + + entity.Property(e => e.BceidGuid) + .HasMaxLength(50) + .HasColumnName("BCEID_GUID"); + + entity.Property(e => e.BceidLastName) + .HasMaxLength(150) + .HasColumnName("BCEID_LAST_NAME"); + + entity.Property(e => e.BceidTelephone) + .HasMaxLength(150) + .HasColumnName("BCEID_TELEPHONE"); + + entity.Property(e => e.BceidUserId) + .HasMaxLength(150) + .HasColumnName("BCEID_USER_ID"); + + entity.Property(e => e.BusinessId).HasColumnName("BUSINESS_ID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.HasOne(d => d.Business) + .WithMany(p => p.HetBusinessUsers) + .HasForeignKey(d => d.BusinessId) + .HasConstraintName("FK_HET_BUSINESS_USER_BUSINESS_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.BusinessUserRoleId) + .HasName("PK_PK_HET_BUSINESS_USER_ROLE"); + + entity.ToTable("HET_BUSINESS_USER_ROLE"); + + entity.HasIndex(e => e.RoleId, "IX_HET_BUSINESS_USER_ROLE_ROLE_ID"); + + entity.HasIndex(e => e.BusinessUserId, "IX_HET_BUSINESS_USER_ROLE_USER_ID"); + + entity.Property(e => e.BusinessUserRoleId) + .HasColumnName("BUSINESS_USER_ROLE_ID") + .HasDefaultValueSql("nextval('\"HET_BUSINESS_USER_ROLE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BusinessUserId).HasColumnName("BUSINESS_USER_ID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.ExpiryDate).HasColumnName("EXPIRY_DATE"); + + entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); + + entity.HasOne(d => d.BusinessUser) + .WithMany(p => p.HetBusinessUserRoles) + .HasForeignKey(d => d.BusinessUserId) + .HasConstraintName("FK_HET_BUSINESS_USER_ROLE_USER_ID"); + + entity.HasOne(d => d.Role) + .WithMany(p => p.HetBusinessUserRoles) + .HasForeignKey(d => d.RoleId) + .HasConstraintName("FK_HET_BUSINESS_USER_ROLE_ROLE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ConditionTypeId); + + entity.ToTable("HET_CONDITION_TYPE"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_CONDITION_TYPE_DISTRICT_ID"); + + entity.Property(e => e.ConditionTypeId) + .HasColumnName("CONDITION_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_CONDITION_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.Active).HasColumnName("ACTIVE"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.ConditionTypeCode) + .HasMaxLength(20) + .HasColumnName("CONDITION_TYPE_CODE"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetConditionTypes) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_CONDITION_TYPE_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ContactId); + + entity.ToTable("HET_CONTACT"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_CONTACT_OWNER_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_CONTACT_PROJECT_ID"); + + entity.Property(e => e.ContactId) + .HasColumnName("CONTACT_ID") + .HasDefaultValueSql("nextval('\"HET_CONTACT_ID_seq\"'::regclass)"); + + entity.Property(e => e.Address1) + .HasMaxLength(80) + .HasColumnName("ADDRESS1"); + + entity.Property(e => e.Address2) + .HasMaxLength(80) + .HasColumnName("ADDRESS2"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.City) + .HasMaxLength(100) + .HasColumnName("CITY"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EmailAddress) + .HasMaxLength(255) + .HasColumnName("EMAIL_ADDRESS"); + + entity.Property(e => e.FaxPhoneNumber) + .HasMaxLength(20) + .HasColumnName("FAX_PHONE_NUMBER"); + + entity.Property(e => e.GivenName) + .HasMaxLength(50) + .HasColumnName("GIVEN_NAME"); + + entity.Property(e => e.MobilePhoneNumber) + .HasMaxLength(20) + .HasColumnName("MOBILE_PHONE_NUMBER"); + + entity.Property(e => e.Notes) + .HasMaxLength(512) + .HasColumnName("NOTES"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.PostalCode) + .HasMaxLength(15) + .HasColumnName("POSTAL_CODE"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.Province) + .HasMaxLength(50) + .HasColumnName("PROVINCE"); + + entity.Property(e => e.Role) + .HasMaxLength(100) + .HasColumnName("ROLE"); + + entity.Property(e => e.Surname) + .HasMaxLength(50) + .HasColumnName("SURNAME"); + + entity.Property(e => e.WorkPhoneNumber) + .HasMaxLength(20) + .HasColumnName("WORK_PHONE_NUMBER"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetContacts) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_CONTACT_OWNER_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetContacts) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_CONTACT_PROJECT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.DigitalFileId); + + entity.ToTable("HET_DIGITAL_FILE"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_DIGITAL_FILE_EQUIPMENT_ID"); + + entity.HasIndex(e => e.MimeTypeId, "IX_HET_DIGITAL_FILE_MIME_TYPE_ID"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_DIGITAL_FILE_OWNER_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_DIGITAL_FILE_PROJECT_ID"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_DIGITAL_FILE_RENTAL_REQUEST_ID"); + + entity.Property(e => e.DigitalFileId) + .HasColumnName("DIGITAL_FILE_ID") + .HasDefaultValueSql("nextval('\"HET_DIGITAL_FILE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.FileContents).HasColumnName("FILE_CONTENTS"); + + entity.Property(e => e.FileName) + .HasMaxLength(2048) + .HasColumnName("FILE_NAME"); + + entity.Property(e => e.MimeTypeId).HasColumnName("MIME_TYPE_ID"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.Type) + .HasMaxLength(255) + .HasColumnName("TYPE"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetDigitalFiles) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_DIGITAL_FILE_EQUIPMENT_ID"); + + entity.HasOne(d => d.MimeType) + .WithMany(p => p.HetDigitalFiles) + .HasForeignKey(d => d.MimeTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_DIGITAL_FILE_MIME_TYPE_ID"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetDigitalFiles) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_DIGITAL_FILE_OWNER_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetDigitalFiles) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_DIGITAL_FILE_PROJECT_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetDigitalFiles) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_DIGITAL_FILE_RENTAL_REQUEST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.DistrictId); + + entity.ToTable("HET_DISTRICT"); + + entity.HasIndex(e => e.RegionId, "IX_HET_DISTRICT_REGION_ID"); + + entity.Property(e => e.DistrictId) + .HasColumnName("DISTRICT_ID") + .HasDefaultValueSql("nextval('\"HET_DISTRICT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictNumber).HasColumnName("DISTRICT_NUMBER"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.MinistryDistrictId).HasColumnName("MINISTRY_DISTRICT_ID"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.RegionId).HasColumnName("REGION_ID"); + + entity.Property(e => e.StartDate).HasColumnName("START_DATE"); + + entity.HasOne(d => d.Region) + .WithMany(p => p.HetDistricts) + .HasForeignKey(d => d.RegionId) + .HasConstraintName("FK_HET_DISTRICT_REGION_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.DistrictEquipmentTypeId); + + entity.ToTable("HET_DISTRICT_EQUIPMENT_TYPE"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); + + entity.HasIndex(e => e.EquipmentTypeId, "IX_HET_DISTRICT_EQUIPMENT_TYPE_EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.DistrictEquipmentTypeId) + .HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_DISTRICT_EQUIPMENT_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Deleted).HasColumnName("DELETED"); + + entity.Property(e => e.DistrictEquipmentName) + .HasMaxLength(255) + .HasColumnName("DISTRICT_EQUIPMENT_NAME"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.EquipmentTypeId).HasColumnName("EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.ServiceAreaId).HasColumnName("SERVICE_AREA_ID"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetDistrictEquipmentTypes) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); + + entity.HasOne(d => d.EquipmentType) + .WithMany(p => p.HetDistrictEquipmentTypes) + .HasForeignKey(d => d.EquipmentTypeId) + .HasConstraintName("FK_HET_DISTRICT_EQUIPMENT_TYPE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasNoKey(); + + entity.ToTable("HET_DISTRICT_STATUS"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_DISTRICT_STATUS_DISTRICT_ID"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.CurrentFiscalYear).HasColumnName("CURRENT_FISCAL_YEAR"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DisplayRolloverMessage).HasColumnName("DISPLAY_ROLLOVER_MESSAGE"); + + entity.Property(e => e.DistrictEquipmentTypeCompleteCount).HasColumnName("DISTRICT_EQUIPMENT_TYPE_COMPLETE_COUNT"); + + entity.Property(e => e.DistrictEquipmentTypeCount).HasColumnName("DISTRICT_EQUIPMENT_TYPE_COUNT"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.LocalAreaCompleteCount).HasColumnName("LOCAL_AREA_COMPLETE_COUNT"); + + entity.Property(e => e.LocalAreaCount).HasColumnName("LOCAL_AREA_COUNT"); + + entity.Property(e => e.NextFiscalYear).HasColumnName("NEXT_FISCAL_YEAR"); + + entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); + + entity.Property(e => e.RolloverEndDate).HasColumnName("ROLLOVER_END_DATE"); + + entity.Property(e => e.RolloverStartDate).HasColumnName("ROLLOVER_START_DATE"); + + entity.HasOne(d => d.District) + .WithMany() + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_DISTRICT_STATUS_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentId); + + entity.ToTable("HET_EQUIPMENT"); + + entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_EQUIPMENT_DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.HasIndex(e => e.LocalAreaId, "IX_HET_EQUIPMENT_LOCAL_AREA_ID"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_EQUIPMENT_OWNER_ID"); + + entity.HasIndex(e => e.EquipmentStatusTypeId, "IX_HET_EQUIPMENT_STATUS_TYPE_ID"); + + entity.Property(e => e.EquipmentId) + .HasColumnName("EQUIPMENT_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ApprovedDate).HasColumnName("APPROVED_DATE"); + + entity.Property(e => e.ArchiveCode) + .HasMaxLength(50) + .HasColumnName("ARCHIVE_CODE"); + + entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); + + entity.Property(e => e.ArchiveReason) + .HasMaxLength(2048) + .HasColumnName("ARCHIVE_REASON"); + + entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.EquipmentCode) + .HasMaxLength(25) + .HasColumnName("EQUIPMENT_CODE"); + + entity.Property(e => e.EquipmentStatusTypeId).HasColumnName("EQUIPMENT_STATUS_TYPE_ID"); + + entity.Property(e => e.InformationUpdateNeededReason) + .HasMaxLength(2048) + .HasColumnName("INFORMATION_UPDATE_NEEDED_REASON"); + + entity.Property(e => e.IsInformationUpdateNeeded).HasColumnName("IS_INFORMATION_UPDATE_NEEDED"); + + entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); + + entity.Property(e => e.LastVerifiedDate).HasColumnName("LAST_VERIFIED_DATE"); + + entity.Property(e => e.LegalCapacity) + .HasMaxLength(150) + .HasColumnName("LEGAL_CAPACITY"); + + entity.Property(e => e.LicencePlate) + .HasMaxLength(20) + .HasColumnName("LICENCE_PLATE"); + + entity.Property(e => e.LicencedGvw) + .HasMaxLength(150) + .HasColumnName("LICENCED_GVW"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.Property(e => e.Make) + .HasMaxLength(50) + .HasColumnName("MAKE"); + + entity.Property(e => e.Model) + .HasMaxLength(50) + .HasColumnName("MODEL"); + + entity.Property(e => e.NumberInBlock).HasColumnName("NUMBER_IN_BLOCK"); + + entity.Property(e => e.Operator) + .HasMaxLength(255) + .HasColumnName("OPERATOR"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.PayRate).HasColumnName("PAY_RATE"); + + entity.Property(e => e.PupLegalCapacity) + .HasMaxLength(150) + .HasColumnName("PUP_LEGAL_CAPACITY"); + + entity.Property(e => e.ReceivedDate).HasColumnName("RECEIVED_DATE"); + + entity.Property(e => e.RefuseRate) + .HasMaxLength(255) + .HasColumnName("REFUSE_RATE"); + + entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); + + entity.Property(e => e.SeniorityEffectiveDate).HasColumnName("SENIORITY_EFFECTIVE_DATE"); + + entity.Property(e => e.SeniorityOverrideReason) + .HasMaxLength(2048) + .HasColumnName("SENIORITY_OVERRIDE_REASON"); + + entity.Property(e => e.SerialNumber) + .HasMaxLength(100) + .HasColumnName("SERIAL_NUMBER"); + + entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); + + entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); + + entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); + + entity.Property(e => e.Size) + .HasMaxLength(128) + .HasColumnName("SIZE"); + + entity.Property(e => e.StatusComment) + .HasMaxLength(255) + .HasColumnName("STATUS_COMMENT"); + + entity.Property(e => e.ToDate).HasColumnName("TO_DATE"); + + entity.Property(e => e.Type) + .HasMaxLength(50) + .HasColumnName("TYPE"); + + entity.Property(e => e.Year) + .HasMaxLength(15) + .HasColumnName("YEAR"); + + entity.Property(e => e.YearsOfService).HasColumnName("YEARS_OF_SERVICE"); + + entity.HasOne(d => d.DistrictEquipmentType) + .WithMany(p => p.HetEquipments) + .HasForeignKey(d => d.DistrictEquipmentTypeId) + .HasConstraintName("FK_HET_EQUIPMENT_DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.HasOne(d => d.EquipmentStatusType) + .WithMany(p => p.HetEquipments) + .HasForeignKey(d => d.EquipmentStatusTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_EQUIPMENT_STATUS_TYPE_ID"); + + entity.HasOne(d => d.LocalArea) + .WithMany(p => p.HetEquipments) + .HasForeignKey(d => d.LocalAreaId) + .HasConstraintName("FK_HET_EQUIPMENT_LOCAL_AREA_ID"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetEquipments) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_EQUIPMENT_OWNER_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentAttachmentId); + + entity.ToTable("HET_EQUIPMENT_ATTACHMENT"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_EQUIPMENT_ATTACHMENT_EQUIPMENT_ID"); + + entity.Property(e => e.EquipmentAttachmentId) + .HasColumnName("EQUIPMENT_ATTACHMENT_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ATTACHMENT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.TypeName) + .HasMaxLength(100) + .HasColumnName("TYPE_NAME"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetEquipmentAttachments) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_EQUIPMENT_ATTACHMENT_EQUIPMENT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentAttachmentHistId) + .HasName("HET_EQUIPMENT_ATTACHMENT_HIST_PK"); + + entity.ToTable("HET_EQUIPMENT_ATTACHMENT_HIST"); + + entity.Property(e => e.EquipmentAttachmentHistId) + .HasColumnName("EQUIPMENT_ATTACHMENT_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ATTACHMENT_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentAttachmentId).HasColumnName("EQUIPMENT_ATTACHMENT_ID"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.TypeName) + .HasMaxLength(100) + .HasColumnName("TYPE_NAME"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentHistId) + .HasName("HET_EQUIPMENT_HIST_PK"); + + entity.ToTable("HET_EQUIPMENT_HIST"); + + entity.Property(e => e.EquipmentHistId) + .HasColumnName("EQUIPMENT_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ApprovedDate).HasColumnName("APPROVED_DATE"); + + entity.Property(e => e.ArchiveCode) + .HasMaxLength(50) + .HasColumnName("ARCHIVE_CODE"); + + entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); + + entity.Property(e => e.ArchiveReason) + .HasMaxLength(2048) + .HasColumnName("ARCHIVE_REASON"); + + entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentCode) + .HasMaxLength(25) + .HasColumnName("EQUIPMENT_CODE"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.EquipmentStatusTypeId).HasColumnName("EQUIPMENT_STATUS_TYPE_ID"); + + entity.Property(e => e.InformationUpdateNeededReason) + .HasMaxLength(2048) + .HasColumnName("INFORMATION_UPDATE_NEEDED_REASON"); + + entity.Property(e => e.IsInformationUpdateNeeded).HasColumnName("IS_INFORMATION_UPDATE_NEEDED"); + + entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); + + entity.Property(e => e.LastVerifiedDate).HasColumnName("LAST_VERIFIED_DATE"); + + entity.Property(e => e.LegalCapacity) + .HasMaxLength(150) + .HasColumnName("LEGAL_CAPACITY"); + + entity.Property(e => e.LicencePlate) + .HasMaxLength(20) + .HasColumnName("LICENCE_PLATE"); + + entity.Property(e => e.LicencedGvw) + .HasMaxLength(150) + .HasColumnName("LICENCED_GVW"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.Property(e => e.Make) + .HasMaxLength(50) + .HasColumnName("MAKE"); + + entity.Property(e => e.Model) + .HasMaxLength(50) + .HasColumnName("MODEL"); + + entity.Property(e => e.NumberInBlock).HasColumnName("NUMBER_IN_BLOCK"); + + entity.Property(e => e.Operator) + .HasMaxLength(255) + .HasColumnName("OPERATOR"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.PayRate).HasColumnName("PAY_RATE"); + + entity.Property(e => e.PupLegalCapacity) + .HasMaxLength(150) + .HasColumnName("PUP_LEGAL_CAPACITY"); + + entity.Property(e => e.ReceivedDate).HasColumnName("RECEIVED_DATE"); + + entity.Property(e => e.RefuseRate) + .HasMaxLength(255) + .HasColumnName("REFUSE_RATE"); + + entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); + + entity.Property(e => e.SeniorityEffectiveDate).HasColumnName("SENIORITY_EFFECTIVE_DATE"); + + entity.Property(e => e.SeniorityOverrideReason) + .HasMaxLength(2048) + .HasColumnName("SENIORITY_OVERRIDE_REASON"); + + entity.Property(e => e.SerialNumber) + .HasMaxLength(100) + .HasColumnName("SERIAL_NUMBER"); + + entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); + + entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); + + entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); + + entity.Property(e => e.Size) + .HasMaxLength(128) + .HasColumnName("SIZE"); + + entity.Property(e => e.StatusComment) + .HasMaxLength(255) + .HasColumnName("STATUS_COMMENT"); + + entity.Property(e => e.ToDate).HasColumnName("TO_DATE"); + + entity.Property(e => e.Type) + .HasMaxLength(50) + .HasColumnName("TYPE"); + + entity.Property(e => e.Year) + .HasMaxLength(15) + .HasColumnName("YEAR"); + + entity.Property(e => e.YearsOfService).HasColumnName("YEARS_OF_SERVICE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentStatusTypeId); + + entity.ToTable("HET_EQUIPMENT_STATUS_TYPE"); + + entity.HasIndex(e => e.EquipmentStatusTypeCode, "UK_HET_EQUIPMENT_STATUS_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.EquipmentStatusTypeId) + .HasColumnName("EQUIPMENT_STATUS_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_STATUS_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.EquipmentStatusTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("EQUIPMENT_STATUS_TYPE_CODE"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.EquipmentTypeId); + + entity.ToTable("HET_EQUIPMENT_TYPE"); + + entity.Property(e => e.EquipmentTypeId) + .HasColumnName("EQUIPMENT_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BlueBookRateNumber).HasColumnName("BLUE_BOOK_RATE_NUMBER"); + + entity.Property(e => e.BlueBookSection).HasColumnName("BLUE_BOOK_SECTION"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.ExtendHours).HasColumnName("EXTEND_HOURS"); + + entity.Property(e => e.IsDumpTruck).HasColumnName("IS_DUMP_TRUCK"); + + entity.Property(e => e.MaxHoursSub).HasColumnName("MAX_HOURS_SUB"); + + entity.Property(e => e.MaximumHours).HasColumnName("MAXIMUM_HOURS"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.NumberOfBlocks).HasColumnName("NUMBER_OF_BLOCKS"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.HistoryId); + + entity.ToTable("HET_HISTORY"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_HISTORY_EQUIPMENT_ID"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_HISTORY_OWNER_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_HISTORY_PROJECT_ID"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_HISTORY_RENTAL_REQUEST_ID"); + + entity.Property(e => e.HistoryId) + .HasColumnName("HISTORY_ID") + .HasDefaultValueSql("nextval('\"HET_HISTORY_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.CreatedDate).HasColumnName("CREATED_DATE"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.HistoryText) + .HasMaxLength(2048) + .HasColumnName("HISTORY_TEXT"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetHistories) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_HISTORY_EQUIPMENT_ID"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetHistories) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_HISTORY_OWNER_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetHistories) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_HISTORY_PROJECT_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetHistories) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_HISTORY_RENTAL_REQUEST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ImportMapId); + + entity.ToTable("HET_IMPORT_MAP"); + + entity.Property(e => e.ImportMapId) + .HasColumnName("IMPORT_MAP_ID") + .HasDefaultValueSql("nextval('\"HET_IMPORT_MAP_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.NewKey).HasColumnName("NEW_KEY"); + + entity.Property(e => e.NewTable).HasColumnName("NEW_TABLE"); + + entity.Property(e => e.OldKey) + .HasMaxLength(250) + .HasColumnName("OLD_KEY"); + + entity.Property(e => e.OldTable).HasColumnName("OLD_TABLE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.LocalAreaId); + + entity.ToTable("HET_LOCAL_AREA"); + + entity.HasIndex(e => e.LocalAreaNumber, "HET_LOCAL_AREA_NUMBER_UK") + .IsUnique(); + + entity.HasIndex(e => e.ServiceAreaId, "IX_HET_LOCAL_AREA_SERVICE_AREA_ID"); + + entity.Property(e => e.LocalAreaId) + .HasColumnName("LOCAL_AREA_ID") + .HasDefaultValueSql("nextval('\"HET_LOCAL_AREA_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.LocalAreaNumber).HasColumnName("LOCAL_AREA_NUMBER"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.ServiceAreaId).HasColumnName("SERVICE_AREA_ID"); + + entity.Property(e => e.StartDate) + .HasColumnName("START_DATE") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.HasOne(d => d.ServiceArea) + .WithMany(p => p.HetLocalAreas) + .HasForeignKey(d => d.ServiceAreaId) + .HasConstraintName("FK_HET_LOCAL_AREA_SERVICE_AREA_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.LocalAreaRotationListId); + + entity.ToTable("HET_LOCAL_AREA_ROTATION_LIST"); + + entity.HasIndex(e => e.AskNextBlock1Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); + + entity.HasIndex(e => e.AskNextBlock2Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); + + entity.HasIndex(e => e.AskNextBlockOpenId, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); + + entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.HasIndex(e => e.LocalAreaId, "IX_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); + + entity.Property(e => e.LocalAreaRotationListId) + .HasColumnName("LOCAL_AREA_ROTATION_LIST_ID") + .HasDefaultValueSql("nextval('\"HET_LOCAL_AREA_ROTATION_LIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.AskNextBlock1Id).HasColumnName("ASK_NEXT_BLOCK1_ID"); + + entity.Property(e => e.AskNextBlock1Seniority).HasColumnName("ASK_NEXT_BLOCK1_SENIORITY"); + + entity.Property(e => e.AskNextBlock2Id).HasColumnName("ASK_NEXT_BLOCK2_ID"); + + entity.Property(e => e.AskNextBlock2Seniority).HasColumnName("ASK_NEXT_BLOCK2_SENIORITY"); + + entity.Property(e => e.AskNextBlockOpenId).HasColumnName("ASK_NEXT_BLOCK_OPEN_ID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.HasOne(d => d.AskNextBlock1) + .WithMany(p => p.HetLocalAreaRotationListAskNextBlock1s) + .HasForeignKey(d => d.AskNextBlock1Id) + .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); + + entity.HasOne(d => d.AskNextBlock2) + .WithMany(p => p.HetLocalAreaRotationListAskNextBlock2s) + .HasForeignKey(d => d.AskNextBlock2Id) + .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); + + entity.HasOne(d => d.AskNextBlockOpen) + .WithMany(p => p.HetLocalAreaRotationListAskNextBlockOpens) + .HasForeignKey(d => d.AskNextBlockOpenId) + .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); + + entity.HasOne(d => d.DistrictEquipmentType) + .WithMany(p => p.HetLocalAreaRotationLists) + .HasForeignKey(d => d.DistrictEquipmentTypeId) + .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.HasOne(d => d.LocalArea) + .WithMany(p => p.HetLocalAreaRotationLists) + .HasForeignKey(d => d.LocalAreaId) + .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.MimeTypeId); + + entity.ToTable("HET_MIME_TYPE"); + + entity.HasIndex(e => e.MimeTypeCode, "UK_HET_MIME_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.MimeTypeId) + .HasColumnName("MIME_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_MIME_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.MimeTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("MIME_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.NoteId); + + entity.ToTable("HET_NOTE"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_NOTE_EQUIPMENT_ID"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_NOTE_OWNER_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_NOTE_PROJECT_ID"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_NOTE_RENTAL_REQUEST_ID"); + + entity.Property(e => e.NoteId) + .HasColumnName("NOTE_ID") + .HasDefaultValueSql("nextval('\"HET_NOTE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.IsNoLongerRelevant).HasColumnName("IS_NO_LONGER_RELEVANT"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.Text) + .HasMaxLength(2048) + .HasColumnName("TEXT"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetNotes) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_NOTE_EQUIPMENT_ID"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetNotes) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_NOTE_OWNER_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetNotes) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_NOTE_PROJECT_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetNotes) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_NOTE_RENTAL_REQUEST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.NoteHistId) + .HasName("HET_NOTE_HIST_PK"); + + entity.ToTable("HET_NOTE_HIST"); + + entity.Property(e => e.NoteHistId) + .HasColumnName("NOTE_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_NOTE_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.IsNoLongerRelevant).HasColumnName("IS_NO_LONGER_RELEVANT"); + + entity.Property(e => e.NoteId).HasColumnName("NOTE_ID"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.Text) + .HasMaxLength(2048) + .HasColumnName("TEXT"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.OwnerId); + + entity.ToTable("HET_OWNER"); + + entity.HasIndex(e => e.BusinessId, "IX_HET_OWNER_BUSINESS_ID"); + + entity.HasIndex(e => e.LocalAreaId, "IX_HET_OWNER_LOCAL_AREA_ID"); + + entity.HasIndex(e => e.PrimaryContactId, "IX_HET_OWNER_PRIMARY_CONTACT_ID"); + + entity.HasIndex(e => e.OwnerStatusTypeId, "IX_HET_OWNER_STATUS_TYPE_ID"); + + entity.Property(e => e.OwnerId) + .HasColumnName("OWNER_ID") + .HasDefaultValueSql("nextval('\"HET_OWNER_ID_seq\"'::regclass)"); + + entity.Property(e => e.Address1) + .HasMaxLength(80) + .HasColumnName("ADDRESS1"); + + entity.Property(e => e.Address2) + .HasMaxLength(80) + .HasColumnName("ADDRESS2"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ArchiveCode) + .HasMaxLength(50) + .HasColumnName("ARCHIVE_CODE"); + + entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); + + entity.Property(e => e.ArchiveReason) + .HasMaxLength(2048) + .HasColumnName("ARCHIVE_REASON"); + + entity.Property(e => e.BusinessId).HasColumnName("BUSINESS_ID"); + + entity.Property(e => e.CglCompany) + .HasMaxLength(255) + .HasColumnName("CGL_COMPANY"); + + entity.Property(e => e.CglPolicyNumber) + .HasMaxLength(50) + .HasColumnName("CGL_POLICY_NUMBER"); + + entity.Property(e => e.CglendDate).HasColumnName("CGLEND_DATE"); + + entity.Property(e => e.City) + .HasMaxLength(100) + .HasColumnName("CITY"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DoingBusinessAs) + .HasMaxLength(150) + .HasColumnName("DOING_BUSINESS_AS"); + + entity.Property(e => e.GivenName) + .HasMaxLength(50) + .HasColumnName("GIVEN_NAME"); + + entity.Property(e => e.IsMaintenanceContractor).HasColumnName("IS_MAINTENANCE_CONTRACTOR"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.Property(e => e.MeetsResidency).HasColumnName("MEETS_RESIDENCY"); + + entity.Property(e => e.OrganizationName) + .HasMaxLength(150) + .HasColumnName("ORGANIZATION_NAME"); + + entity.Property(e => e.OwnerCode) + .HasMaxLength(20) + .HasColumnName("OWNER_CODE"); + + entity.Property(e => e.OwnerStatusTypeId).HasColumnName("OWNER_STATUS_TYPE_ID"); + + entity.Property(e => e.PostalCode) + .HasMaxLength(15) + .HasColumnName("POSTAL_CODE"); + + entity.Property(e => e.PrimaryContactId).HasColumnName("PRIMARY_CONTACT_ID"); + + entity.Property(e => e.Province) + .HasMaxLength(50) + .HasColumnName("PROVINCE"); + + entity.Property(e => e.RegisteredCompanyNumber) + .HasMaxLength(150) + .HasColumnName("REGISTERED_COMPANY_NUMBER"); + + entity.Property(e => e.SharedKey) + .HasMaxLength(50) + .HasColumnName("SHARED_KEY"); + + entity.Property(e => e.StatusComment) + .HasMaxLength(255) + .HasColumnName("STATUS_COMMENT"); + + entity.Property(e => e.Surname) + .HasMaxLength(50) + .HasColumnName("SURNAME"); + + entity.Property(e => e.WorkSafeBcexpiryDate).HasColumnName("WORK_SAFE_BCEXPIRY_DATE"); + + entity.Property(e => e.WorkSafeBcpolicyNumber) + .HasMaxLength(50) + .HasColumnName("WORK_SAFE_BCPOLICY_NUMBER"); + + entity.HasOne(d => d.Business) + .WithMany(p => p.HetOwners) + .HasForeignKey(d => d.BusinessId) + .HasConstraintName("FK_HET_OWNER_BUSINESS_ID"); + + entity.HasOne(d => d.LocalArea) + .WithMany(p => p.HetOwners) + .HasForeignKey(d => d.LocalAreaId) + .HasConstraintName("FK_HET_OWNER_LOCAL_AREA_ID"); + + entity.HasOne(d => d.OwnerStatusType) + .WithMany(p => p.HetOwners) + .HasForeignKey(d => d.OwnerStatusTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_OWNER_STATUS_TYPE_ID"); + + entity.HasOne(d => d.PrimaryContact) + .WithMany(p => p.HetOwners) + .HasForeignKey(d => d.PrimaryContactId) + .HasConstraintName("FK_HET_OWNER_PRIMARY_CONTACT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.OwnerStatusTypeId); + + entity.ToTable("HET_OWNER_STATUS_TYPE"); + + entity.HasIndex(e => e.OwnerStatusTypeCode, "UK_HET_OWNER_STATUS_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.OwnerStatusTypeId) + .HasColumnName("OWNER_STATUS_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_OWNER_STATUS_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.OwnerStatusTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("OWNER_STATUS_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.PermissionId); + + entity.ToTable("HET_PERMISSION"); + + entity.HasIndex(e => e.Code, "HET_PRM_CODE_UK") + .IsUnique(); + + entity.HasIndex(e => e.Name, "HET_PRM_NAME_UK") + .IsUnique(); + + entity.Property(e => e.PermissionId) + .HasColumnName("PERMISSION_ID") + .HasDefaultValueSql("nextval('\"HET_PERMISSION_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Code) + .HasMaxLength(50) + .HasColumnName("CODE"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.PersonId); + + entity.ToTable("HET_PERSON"); + + entity.Property(e => e.PersonId) + .HasColumnName("PERSON_ID") + .HasDefaultValueSql("nextval('\"HET_PERSON_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.FirstName) + .HasMaxLength(50) + .HasColumnName("FIRST_NAME"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.MiddleNames) + .HasMaxLength(200) + .HasColumnName("MIDDLE_NAMES"); + + entity.Property(e => e.NameSuffix) + .HasMaxLength(50) + .HasColumnName("NAME_SUFFIX"); + + entity.Property(e => e.Surname) + .IsRequired() + .HasMaxLength(50) + .HasColumnName("SURNAME"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ProjectId); + + entity.ToTable("HET_PROJECT"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_PROJECT_DISTRICT_ID"); + + entity.HasIndex(e => e.PrimaryContactId, "IX_HET_PROJECT_PRIMARY_CONTACT_ID"); + + entity.HasIndex(e => e.ProjectStatusTypeId, "IX_HET_PROJECT_STATUS_TYPE_ID"); + + entity.Property(e => e.ProjectId) + .HasColumnName("PROJECT_ID") + .HasDefaultValueSql("nextval('\"HET_PROJECT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BusinessFunction) + .HasMaxLength(255) + .HasColumnName("BUSINESS_FUNCTION"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.CostType) + .HasMaxLength(255) + .HasColumnName("COST_TYPE"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.FiscalYear) + .IsRequired() + .HasMaxLength(10) + .HasColumnName("FISCAL_YEAR") + .HasDefaultValueSql("'2018/2019'::character varying"); + + entity.Property(e => e.Information) + .HasMaxLength(2048) + .HasColumnName("INFORMATION"); + + entity.Property(e => e.Name) + .HasMaxLength(100) + .HasColumnName("NAME"); + + entity.Property(e => e.PrimaryContactId).HasColumnName("PRIMARY_CONTACT_ID"); + + entity.Property(e => e.Product) + .HasMaxLength(255) + .HasColumnName("PRODUCT"); + + entity.Property(e => e.ProjectStatusTypeId).HasColumnName("PROJECT_STATUS_TYPE_ID"); + + entity.Property(e => e.ProvincialProjectNumber) + .HasMaxLength(150) + .HasColumnName("PROVINCIAL_PROJECT_NUMBER"); + + entity.Property(e => e.ResponsibilityCentre) + .HasMaxLength(255) + .HasColumnName("RESPONSIBILITY_CENTRE"); + + entity.Property(e => e.ServiceLine) + .HasMaxLength(255) + .HasColumnName("SERVICE_LINE"); + + entity.Property(e => e.Stob) + .HasMaxLength(255) + .HasColumnName("STOB"); + + entity.Property(e => e.WorkActivity) + .HasMaxLength(255) + .HasColumnName("WORK_ACTIVITY"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetProjects) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_PROJECT_DISTRICT_ID"); + + entity.HasOne(d => d.PrimaryContact) + .WithMany(p => p.HetProjects) + .HasForeignKey(d => d.PrimaryContactId) + .HasConstraintName("FK_HET_PROJECT_PRIMARY_CONTACT_ID"); + + entity.HasOne(d => d.ProjectStatusType) + .WithMany(p => p.HetProjects) + .HasForeignKey(d => d.ProjectStatusTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_PROJECT_HET_PROJECT_STATUS_TYPE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ProjectStatusTypeId); + + entity.ToTable("HET_PROJECT_STATUS_TYPE"); + + entity.HasIndex(e => e.ProjectStatusTypeCode, "UK_HET_PROJECT_STATUS_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.ProjectStatusTypeId) + .HasColumnName("PROJECT_STATUS_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_PROJECT_STATUS_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.ProjectStatusTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("PROJECT_STATUS_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RateType); + + entity.ToTable("HET_PROVINCIAL_RATE_TYPE"); + + entity.Property(e => e.RateType) + .HasMaxLength(20) + .HasColumnName("RATE_TYPE"); + + entity.Property(e => e.Active).HasColumnName("ACTIVE"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(200) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.IsInTotalEditable).HasColumnName("IS_IN_TOTAL_EDITABLE"); + + entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); + + entity.Property(e => e.IsPercentRate).HasColumnName("IS_PERCENT_RATE"); + + entity.Property(e => e.IsRateEditable).HasColumnName("IS_RATE_EDITABLE"); + + entity.Property(e => e.Overtime).HasColumnName("OVERTIME"); + + entity.Property(e => e.PeriodType) + .HasMaxLength(20) + .HasColumnName("PERIOD_TYPE"); + + entity.Property(e => e.Rate).HasColumnName("RATE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RatePeriodTypeId); + + entity.ToTable("HET_RATE_PERIOD_TYPE"); + + entity.HasIndex(e => e.RatePeriodTypeCode, "UK_HET_RATE_PERIOD_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.RatePeriodTypeId) + .HasColumnName("RATE_PERIOD_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_RATE_PERIOD_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.RatePeriodTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("RATE_PERIOD_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RegionId); + + entity.ToTable("HET_REGION"); + + entity.Property(e => e.RegionId) + .HasColumnName("REGION_ID") + .HasDefaultValueSql("nextval('\"HET_REGION_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.MinistryRegionId).HasColumnName("MINISTRY_REGION_ID"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.RegionNumber).HasColumnName("REGION_NUMBER"); + + entity.Property(e => e.StartDate).HasColumnName("START_DATE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementId); + + entity.ToTable("HET_RENTAL_AGREEMENT"); + + entity.HasIndex(e => e.Number, "HET_RNTAG_NUMBER_UK") + .IsUnique(); + + entity.HasIndex(e => e.DistrictId, "IX_HET_RENTAL_AGREEMENT_DISTRICT_ID"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_RENTAL_AGREEMENT_EQUIPMENT_ID"); + + entity.HasIndex(e => e.RatePeriodTypeId, "IX_HET_RENTAL_AGREEMENT_HET_RATE_PERIOD_TYPE_ID"); + + entity.HasIndex(e => e.RentalAgreementStatusTypeId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_AGREEMENT_STATUS_TYPE_ID"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_REQUEST_ID"); + + entity.HasIndex(e => e.RentalRequestRotationListId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_REQUEST_ROTATION_LIST_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_RENTAL_AGREEMENT_PROJECT_ID"); + + entity.Property(e => e.RentalAgreementId) + .HasColumnName("RENTAL_AGREEMENT_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AgreementCity) + .HasMaxLength(255) + .HasColumnName("AGREEMENT_CITY"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DatedOn).HasColumnName("DATED_ON"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.EquipmentRate).HasColumnName("EQUIPMENT_RATE"); + + entity.Property(e => e.EstimateHours).HasColumnName("ESTIMATE_HOURS"); + + entity.Property(e => e.EstimateStartWork).HasColumnName("ESTIMATE_START_WORK"); + + entity.Property(e => e.Note) + .HasMaxLength(2048) + .HasColumnName("NOTE"); + + entity.Property(e => e.Number) + .HasMaxLength(30) + .HasColumnName("NUMBER"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RateComment) + .HasMaxLength(2048) + .HasColumnName("RATE_COMMENT"); + + entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); + + entity.Property(e => e.RentalAgreementStatusTypeId).HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.RentalRequestRotationListId).HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_DISTRICT_ID"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_EQUIPMENT_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_PROJECT_ID"); + + entity.HasOne(d => d.RatePeriodType) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.RatePeriodTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_PERIOD_TYPE_ID"); + + entity.HasOne(d => d.RentalAgreementStatusType) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.RentalAgreementStatusTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_STATUS_TYPE_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RENTAL_REQUEST_ID"); + + entity.HasOne(d => d.RentalRequestRotationList) + .WithMany(p => p.HetRentalAgreements) + .HasForeignKey(d => d.RentalRequestRotationListId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RENTAL_REQUEST_ROTATION_LIST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementConditionId); + + entity.ToTable("HET_RENTAL_AGREEMENT_CONDITION"); + + entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_AGREEMENT_CONDITION_RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementConditionId) + .HasColumnName("RENTAL_AGREEMENT_CONDITION_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_CONDITION_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Comment) + .HasMaxLength(2048) + .HasColumnName("COMMENT"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.ConditionName) + .HasMaxLength(150) + .HasColumnName("CONDITION_NAME"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.HasOne(d => d.RentalAgreement) + .WithMany(p => p.HetRentalAgreementConditions) + .HasForeignKey(d => d.RentalAgreementId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_CONDITION_RENTAL_AGREEMENT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementConditionHistId) + .HasName("HET_RENTAL_AGREEMENT_CONDITION_HIST_PK"); + + entity.ToTable("HET_RENTAL_AGREEMENT_CONDITION_HIST"); + + entity.Property(e => e.RentalAgreementConditionHistId) + .HasColumnName("RENTAL_AGREEMENT_CONDITION_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_CONDITION_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Comment) + .HasMaxLength(2048) + .HasColumnName("COMMENT"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.ConditionName) + .HasMaxLength(150) + .HasColumnName("CONDITION_NAME"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.RentalAgreementConditionId).HasColumnName("RENTAL_AGREEMENT_CONDITION_ID"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementHistId) + .HasName("HET_RENTAL_AGREEMENT_HIST_PK"); + + entity.ToTable("HET_RENTAL_AGREEMENT_HIST"); + + entity.Property(e => e.RentalAgreementHistId) + .HasColumnName("RENTAL_AGREEMENT_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AgreementCity) + .HasMaxLength(255) + .HasColumnName("AGREEMENT_CITY"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DatedOn).HasColumnName("DATED_ON"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.EquipmentRate).HasColumnName("EQUIPMENT_RATE"); + + entity.Property(e => e.EstimateHours).HasColumnName("ESTIMATE_HOURS"); + + entity.Property(e => e.EstimateStartWork).HasColumnName("ESTIMATE_START_WORK"); + + entity.Property(e => e.Note) + .HasMaxLength(2048) + .HasColumnName("NOTE"); + + entity.Property(e => e.Number) + .HasMaxLength(30) + .HasColumnName("NUMBER"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RateComment) + .HasMaxLength(2048) + .HasColumnName("RATE_COMMENT"); + + entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementStatusTypeId).HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementRateId); + + entity.ToTable("HET_RENTAL_AGREEMENT_RATE"); + + entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_AGREEMENT_RATE_RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementRateId) + .HasColumnName("RENTAL_AGREEMENT_RATE_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_RATE_ID_seq\"'::regclass)"); + + entity.Property(e => e.Active) + .HasColumnName("ACTIVE") + .HasDefaultValueSql("false"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Comment) + .HasMaxLength(2048) + .HasColumnName("COMMENT"); + + entity.Property(e => e.ComponentName) + .HasMaxLength(150) + .HasColumnName("COMPONENT_NAME"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); + + entity.Property(e => e.Overtime) + .HasColumnName("OVERTIME") + .HasDefaultValueSql("false"); + + entity.Property(e => e.Rate).HasColumnName("RATE"); + + entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.Set) + .HasColumnName("SET") + .HasDefaultValueSql("false"); + + entity.HasOne(d => d.RatePeriodType) + .WithMany(p => p.HetRentalAgreementRates) + .HasForeignKey(d => d.RatePeriodTypeId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_PERIOD_TYPE_ID"); + + entity.HasOne(d => d.RentalAgreement) + .WithMany(p => p.HetRentalAgreementRates) + .HasForeignKey(d => d.RentalAgreementId) + .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_AGREEMENT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementRateHistId) + .HasName("HET_RENTAL_AGREEMENT_RATE_HIST_PK"); + + entity.ToTable("HET_RENTAL_AGREEMENT_RATE_HIST"); + + entity.Property(e => e.RentalAgreementRateHistId) + .HasColumnName("RENTAL_AGREEMENT_RATE_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_RATE_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.Active) + .HasColumnName("ACTIVE") + .HasDefaultValueSql("false"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Comment) + .HasMaxLength(2048) + .HasColumnName("COMMENT"); + + entity.Property(e => e.ComponentName) + .HasMaxLength(150) + .HasColumnName("COMPONENT_NAME"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); + + entity.Property(e => e.Overtime) + .HasColumnName("OVERTIME") + .HasDefaultValueSql("false"); + + entity.Property(e => e.Rate).HasColumnName("RATE"); + + entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); + + entity.Property(e => e.Set).HasColumnName("SET"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalAgreementStatusTypeId); + + entity.ToTable("HET_RENTAL_AGREEMENT_STATUS_TYPE"); + + entity.HasIndex(e => e.RentalAgreementStatusTypeCode, "UK_HET_RENTAL_AGREEMENT_STATUS_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.RentalAgreementStatusTypeId) + .HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_STATUS_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.RentalAgreementStatusTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalRequestId); + + entity.ToTable("HET_RENTAL_REQUEST"); + + entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_RENTAL_REQUEST_DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.HasIndex(e => e.FirstOnRotationListId, "IX_HET_RENTAL_REQUEST_FIRST_ON_ROTATION_LIST_ID"); + + entity.HasIndex(e => e.LocalAreaId, "IX_HET_RENTAL_REQUEST_LOCAL_AREA_ID"); + + entity.HasIndex(e => e.ProjectId, "IX_HET_RENTAL_REQUEST_PROJECT_ID"); + + entity.HasIndex(e => e.RentalRequestStatusTypeId, "IX_HET_RENTAL_REQUEST_STATUS_TYPE_ID"); + + entity.Property(e => e.RentalRequestId) + .HasColumnName("RENTAL_REQUEST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); + + entity.Property(e => e.EquipmentCount).HasColumnName("EQUIPMENT_COUNT"); + + entity.Property(e => e.ExpectedEndDate).HasColumnName("EXPECTED_END_DATE"); + + entity.Property(e => e.ExpectedHours).HasColumnName("EXPECTED_HOURS"); + + entity.Property(e => e.ExpectedStartDate).HasColumnName("EXPECTED_START_DATE"); + + entity.Property(e => e.FirstOnRotationListId).HasColumnName("FIRST_ON_ROTATION_LIST_ID"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); + + entity.Property(e => e.RentalRequestStatusTypeId).HasColumnName("RENTAL_REQUEST_STATUS_TYPE_ID"); + + entity.HasOne(d => d.DistrictEquipmentType) + .WithMany(p => p.HetRentalRequests) + .HasForeignKey(d => d.DistrictEquipmentTypeId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); + + entity.HasOne(d => d.FirstOnRotationList) + .WithMany(p => p.HetRentalRequests) + .HasForeignKey(d => d.FirstOnRotationListId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_FIRST_ON_ROTATION_LIST_ID"); + + entity.HasOne(d => d.LocalArea) + .WithMany(p => p.HetRentalRequests) + .HasForeignKey(d => d.LocalAreaId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_LOCAL_AREA_ID"); + + entity.HasOne(d => d.Project) + .WithMany(p => p.HetRentalRequests) + .HasForeignKey(d => d.ProjectId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_PROJECT_ID"); + + entity.HasOne(d => d.RentalRequestStatusType) + .WithMany(p => p.HetRentalRequests) + .HasForeignKey(d => d.RentalRequestStatusTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_RENTAL_REQUEST_STATUS_TYPE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalRequestAttachmentId); + + entity.ToTable("HET_RENTAL_REQUEST_ATTACHMENT"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_REQUEST_ATTACHMENT_RENTAL_REQUEST_ID"); + + entity.Property(e => e.RentalRequestAttachmentId) + .HasColumnName("RENTAL_REQUEST_ATTACHMENT_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ATTACHMENT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.Attachment) + .HasMaxLength(150) + .HasColumnName("ATTACHMENT"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetRentalRequestAttachments) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_ATTACHMENT_RENTAL_REQUEST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalRequestRotationListId); + + entity.ToTable("HET_RENTAL_REQUEST_ROTATION_LIST"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_EQUIPMENT_ID"); + + entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_AGREEMENT_ID"); + + entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_REQUEST_ID"); + + entity.Property(e => e.RentalRequestRotationListId) + .HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ROTATION_LIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.AskedDateTime).HasColumnName("ASKED_DATE_TIME"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.IsForceHire).HasColumnName("IS_FORCE_HIRE"); + + entity.Property(e => e.Note) + .HasMaxLength(2048) + .HasColumnName("NOTE"); + + entity.Property(e => e.OfferRefusalReason) + .HasMaxLength(50) + .HasColumnName("OFFER_REFUSAL_REASON"); + + entity.Property(e => e.OfferResponse).HasColumnName("OFFER_RESPONSE"); + + entity.Property(e => e.OfferResponseDatetime).HasColumnName("OFFER_RESPONSE_DATETIME"); + + entity.Property(e => e.OfferResponseNote) + .HasMaxLength(2048) + .HasColumnName("OFFER_RESPONSE_NOTE"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.RotationListSortOrder).HasColumnName("ROTATION_LIST_SORT_ORDER"); + + entity.Property(e => e.WasAsked).HasColumnName("WAS_ASKED"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetRentalRequestRotationLists) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_EQUIPMENT_ID"); + + entity.HasOne(d => d.RentalAgreement) + .WithMany(p => p.HetRentalRequestRotationLists) + .HasForeignKey(d => d.RentalAgreementId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_AGREEMENT_ID"); + + entity.HasOne(d => d.RentalRequest) + .WithMany(p => p.HetRentalRequestRotationLists) + .HasForeignKey(d => d.RentalRequestId) + .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_REQUEST_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalRequestRotationListHistId) + .HasName("HET_RENTAL_REQUEST_ROTATION_LIST_HIST_PK"); + + entity.ToTable("HET_RENTAL_REQUEST_ROTATION_LIST_HIST"); + + entity.Property(e => e.RentalRequestRotationListHistId) + .HasColumnName("RENTAL_REQUEST_ROTATION_LIST_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ROTATION_LIST_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.AskedDateTime).HasColumnName("ASKED_DATE_TIME"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.IsForceHire).HasColumnName("IS_FORCE_HIRE"); + + entity.Property(e => e.Note) + .HasMaxLength(2048) + .HasColumnName("NOTE"); + + entity.Property(e => e.OfferRefusalReason) + .HasMaxLength(50) + .HasColumnName("OFFER_REFUSAL_REASON"); + + entity.Property(e => e.OfferResponse).HasColumnName("OFFER_RESPONSE"); + + entity.Property(e => e.OfferResponseDatetime).HasColumnName("OFFER_RESPONSE_DATETIME"); + + entity.Property(e => e.OfferResponseNote) + .HasMaxLength(2048) + .HasColumnName("OFFER_RESPONSE_NOTE"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); + + entity.Property(e => e.RentalRequestRotationListId).HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID"); + + entity.Property(e => e.RotationListSortOrder).HasColumnName("ROTATION_LIST_SORT_ORDER"); + + entity.Property(e => e.WasAsked).HasColumnName("WAS_ASKED"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RentalRequestStatusTypeId); + + entity.ToTable("HET_RENTAL_REQUEST_STATUS_TYPE"); + + entity.HasIndex(e => e.RentalRequestStatusTypeCode, "UK_HET_RENTAL_REQUEST_STATUS_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.RentalRequestStatusTypeId) + .HasColumnName("RENTAL_REQUEST_STATUS_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_STATUS_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.RentalRequestStatusTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("RENTAL_REQUEST_STATUS_TYPE_CODE"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RoleId); + + entity.ToTable("HET_ROLE"); + + entity.HasIndex(e => e.Name, "HET_ROLE_NAME_UK") + .IsUnique(); + + entity.Property(e => e.RoleId) + .HasColumnName("ROLE_ID") + .HasDefaultValueSql("nextval('\"HET_ROLE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.Name) + .HasMaxLength(255) + .HasColumnName("NAME"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.RolePermissionId); + + entity.ToTable("HET_ROLE_PERMISSION"); + + entity.HasIndex(e => e.PermissionId, "IX_HET_ROLE_PERMISSION_PERMISSION_ID"); + + entity.HasIndex(e => e.RoleId, "IX_HET_ROLE_PERMISSION_ROLE_ID"); + + entity.Property(e => e.RolePermissionId) + .HasColumnName("ROLE_PERMISSION_ID") + .HasDefaultValueSql("nextval('\"HET_ROLE_PERMISSION_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.PermissionId).HasColumnName("PERMISSION_ID"); + + entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); + + entity.HasOne(d => d.Permission) + .WithMany(p => p.HetRolePermissions) + .HasForeignKey(d => d.PermissionId) + .HasConstraintName("FK_HET_ROLE_PERMISSION_PERMISSION_ID"); + + entity.HasOne(d => d.Role) + .WithMany(p => p.HetRolePermissions) + .HasForeignKey(d => d.RoleId) + .HasConstraintName("FK_HET_ROLE_PERMISSION_ROLE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.DistrictId); + + entity.ToTable("HET_ROLLOVER_PROGRESS"); + + entity.Property(e => e.DistrictId) + .ValueGeneratedNever() + .HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); + + entity.HasOne(d => d.District) + .WithOne(p => p.HetRolloverProgress) + .HasForeignKey(d => d.DistrictId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.SeniorityAuditId); + + entity.ToTable("HET_SENIORITY_AUDIT"); + + entity.HasIndex(e => e.EquipmentId, "IX_HET_SENIORITY_AUDIT_EQUIPMENT_ID"); + + entity.HasIndex(e => e.LocalAreaId, "IX_HET_SENIORITY_AUDIT_LOCAL_AREA_ID"); + + entity.HasIndex(e => e.OwnerId, "IX_HET_SENIORITY_AUDIT_OWNER_ID"); + + entity.Property(e => e.SeniorityAuditId) + .HasColumnName("SENIORITY_AUDIT_ID") + .HasDefaultValueSql("nextval('\"HET_SENIORITY_AUDIT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); + + entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); + + entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); + + entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); + + entity.Property(e => e.OwnerOrganizationName) + .HasMaxLength(150) + .HasColumnName("OWNER_ORGANIZATION_NAME"); + + entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); + + entity.Property(e => e.SeniorityOverrideReason) + .HasMaxLength(2048) + .HasColumnName("SENIORITY_OVERRIDE_REASON"); + + entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); + + entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); + + entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); + + entity.Property(e => e.StartDate).HasColumnName("START_DATE"); + + entity.HasOne(d => d.Equipment) + .WithMany(p => p.HetSeniorityAudits) + .HasForeignKey(d => d.EquipmentId) + .HasConstraintName("FK_HET_SENIORITY_AUDIT_EQUIPMENT_ID"); + + entity.HasOne(d => d.LocalArea) + .WithMany(p => p.HetSeniorityAudits) + .HasForeignKey(d => d.LocalAreaId) + .HasConstraintName("FK_HET_SENIORITY_AUDIT_LOCAL_AREA_ID"); + + entity.HasOne(d => d.Owner) + .WithMany(p => p.HetSeniorityAudits) + .HasForeignKey(d => d.OwnerId) + .HasConstraintName("FK_HET_SENIORITY_AUDIT_OWNER_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.ServiceAreaId); + + entity.ToTable("HET_SERVICE_AREA"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_SERVICE_AREA_DISTRICT_ID"); + + entity.Property(e => e.ServiceAreaId) + .HasColumnName("SERVICE_AREA_ID") + .HasDefaultValueSql("nextval('\"HET_SERVICE_AREA_ID_seq\"'::regclass)"); + + entity.Property(e => e.Address) + .HasMaxLength(255) + .HasColumnName("ADDRESS"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.AreaNumber).HasColumnName("AREA_NUMBER"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.Fax) + .HasMaxLength(50) + .HasColumnName("FAX"); + + entity.Property(e => e.FiscalEndDate).HasColumnName("FISCAL_END_DATE"); + + entity.Property(e => e.FiscalStartDate).HasColumnName("FISCAL_START_DATE"); + + entity.Property(e => e.MinistryServiceAreaId).HasColumnName("MINISTRY_SERVICE_AREA_ID"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.Phone) + .HasMaxLength(50) + .HasColumnName("PHONE"); + + entity.Property(e => e.SupportingDocuments) + .HasMaxLength(500) + .HasColumnName("SUPPORTING_DOCUMENTS"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetServiceAreas) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_SERVICE_AREA_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.TimePeriodTypeId); + + entity.ToTable("HET_TIME_PERIOD_TYPE"); + + entity.HasIndex(e => e.TimePeriodTypeCode, "UK_HET_TIME_PERIOD_TYPE_CODE") + .IsUnique(); + + entity.Property(e => e.TimePeriodTypeId) + .HasColumnName("TIME_PERIOD_TYPE_ID") + .HasDefaultValueSql("nextval('\"HET_TIME_PERIOD_TYPE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.Description) + .IsRequired() + .HasMaxLength(2048) + .HasColumnName("DESCRIPTION"); + + entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); + + entity.Property(e => e.IsActive) + .IsRequired() + .HasColumnName("IS_ACTIVE") + .HasDefaultValueSql("true"); + + entity.Property(e => e.ScreenLabel) + .HasMaxLength(200) + .HasColumnName("SCREEN_LABEL"); + + entity.Property(e => e.TimePeriodTypeCode) + .IsRequired() + .HasMaxLength(20) + .HasColumnName("TIME_PERIOD_TYPE_CODE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.TimeRecordId); + + entity.ToTable("HET_TIME_RECORD"); + + entity.HasIndex(e => e.RentalAgreementId, "IX_HET_TIME_RECORD_RENTAL_AGREEMENT_ID"); + + entity.HasIndex(e => e.RentalAgreementRateId, "IX_HET_TIME_RECORD_RENTAL_AGREEMENT_RATE_ID"); + + entity.HasIndex(e => e.TimePeriodTypeId, "IX_HET_TIME_RECORD_TIME_PERIOD_TYPE_ID"); + + entity.Property(e => e.TimeRecordId) + .HasColumnName("TIME_RECORD_ID") + .HasDefaultValueSql("nextval('\"HET_TIME_RECORD_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EnteredDate).HasColumnName("ENTERED_DATE"); + + entity.Property(e => e.Hours).HasColumnName("HOURS"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); + + entity.Property(e => e.TimePeriodTypeId).HasColumnName("TIME_PERIOD_TYPE_ID"); + + entity.Property(e => e.WorkedDate).HasColumnName("WORKED_DATE"); + + entity.HasOne(d => d.RentalAgreement) + .WithMany(p => p.HetTimeRecords) + .HasForeignKey(d => d.RentalAgreementId) + .HasConstraintName("FK_HET_TIME_RECORD_RENTAL_AGREEMENT_ID"); + + entity.HasOne(d => d.RentalAgreementRate) + .WithMany(p => p.HetTimeRecords) + .HasForeignKey(d => d.RentalAgreementRateId) + .HasConstraintName("FK_HET_TIME_RECORD_RENTAL_AGREEMENT_RATE_ID"); + + entity.HasOne(d => d.TimePeriodType) + .WithMany(p => p.HetTimeRecords) + .HasForeignKey(d => d.TimePeriodTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_HET_TIME_RECORD_TIME_PERIOD_TYPE_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.TimeRecordHistId) + .HasName("HET_TIME_RECORD_HIST_PK"); + + entity.ToTable("HET_TIME_RECORD_HIST"); + + entity.Property(e => e.TimeRecordHistId) + .HasColumnName("TIME_RECORD_HIST_ID") + .HasDefaultValueSql("nextval('\"HET_TIME_RECORD_HIST_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.EndDate).HasColumnName("END_DATE"); + + entity.Property(e => e.EnteredDate).HasColumnName("ENTERED_DATE"); + + entity.Property(e => e.Hours).HasColumnName("HOURS"); + + entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); + + entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); + + entity.Property(e => e.TimePeriodTypeId).HasColumnName("TIME_PERIOD_TYPE_ID"); + + entity.Property(e => e.TimeRecordId).HasColumnName("TIME_RECORD_ID"); + + entity.Property(e => e.WorkedDate).HasColumnName("WORKED_DATE"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.UserId); + + entity.ToTable("HET_USER"); + + entity.HasIndex(e => e.Guid, "HET_USR_GUID_UK") + .IsUnique(); + + entity.HasIndex(e => e.DistrictId, "IX_HET_USER_DISTRICT_ID"); + + entity.Property(e => e.UserId) + .HasColumnName("USER_ID") + .HasDefaultValueSql("nextval('\"HET_USER_ID_seq\"'::regclass)"); + + entity.Property(e => e.Active).HasColumnName("ACTIVE"); + + entity.Property(e => e.AgreementCity) + .HasMaxLength(255) + .HasColumnName("AGREEMENT_CITY"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.Email) + .HasMaxLength(255) + .HasColumnName("EMAIL"); + + entity.Property(e => e.GivenName) + .HasMaxLength(50) + .HasColumnName("GIVEN_NAME"); + + entity.Property(e => e.Guid) + .HasMaxLength(255) + .HasColumnName("GUID"); + + entity.Property(e => e.Initials) + .HasMaxLength(10) + .HasColumnName("INITIALS"); + + entity.Property(e => e.SmAuthorizationDirectory) + .HasMaxLength(255) + .HasColumnName("SM_AUTHORIZATION_DIRECTORY"); + + entity.Property(e => e.SmUserId) + .HasMaxLength(255) + .HasColumnName("SM_USER_ID"); + + entity.Property(e => e.Surname) + .HasMaxLength(50) + .HasColumnName("SURNAME"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetUsers) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_USER_DISTRICT_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.UserDistrictId); + + entity.ToTable("HET_USER_DISTRICT"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_USER_DISTRICT_DISTRICT_ID"); + + entity.HasIndex(e => e.UserId, "IX_HET_USER_DISTRICT_USER_ID"); + + entity.Property(e => e.UserDistrictId) + .HasColumnName("USER_DISTRICT_ID") + .HasDefaultValueSql("nextval('\"HET_USER_DISTRICT_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.IsPrimary).HasColumnName("IS_PRIMARY"); + + entity.Property(e => e.UserId).HasColumnName("USER_ID"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetUserDistricts) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_USER_DISTRICT_DISTRICT_ID"); + + entity.HasOne(d => d.User) + .WithMany(p => p.HetUserDistricts) + .HasForeignKey(d => d.UserId) + .HasConstraintName("FK_HET_USER_DISTRICT_USER_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.UserFavouriteId); + + entity.ToTable("HET_USER_FAVOURITE"); + + entity.HasIndex(e => e.DistrictId, "IX_HET_USER_FAVOURITE_DISTRICT_ID"); + + entity.HasIndex(e => e.UserId, "IX_HET_USER_FAVOURITE_USER_ID"); + + entity.Property(e => e.UserFavouriteId) + .HasColumnName("USER_FAVOURITE_ID") + .HasDefaultValueSql("nextval('\"HET_USER_FAVOURITE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); + + entity.Property(e => e.IsDefault).HasColumnName("IS_DEFAULT"); + + entity.Property(e => e.Name) + .HasMaxLength(150) + .HasColumnName("NAME"); + + entity.Property(e => e.Type) + .HasMaxLength(150) + .HasColumnName("TYPE"); + + entity.Property(e => e.UserId).HasColumnName("USER_ID"); + + entity.Property(e => e.Value) + .HasMaxLength(2048) + .HasColumnName("VALUE"); + + entity.HasOne(d => d.District) + .WithMany(p => p.HetUserFavourites) + .HasForeignKey(d => d.DistrictId) + .HasConstraintName("FK_HET_USER_FAVOURITE_DISTRICT_ID"); + + entity.HasOne(d => d.User) + .WithMany(p => p.HetUserFavourites) + .HasForeignKey(d => d.UserId) + .HasConstraintName("FK_HET_USER_FAVOURITE_USER_ID"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.UserRoleId); + + entity.ToTable("HET_USER_ROLE"); + + entity.HasIndex(e => e.RoleId, "IX_HET_USER_ROLE_ROLE_ID"); + + entity.HasIndex(e => e.UserId, "IX_HET_USER_ROLE_USER_ID"); + + entity.Property(e => e.UserRoleId) + .HasColumnName("USER_ROLE_ID") + .HasDefaultValueSql("nextval('\"HET_USER_ROLE_ID_seq\"'::regclass)"); + + entity.Property(e => e.AppCreateTimestamp) + .HasColumnName("APP_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppCreateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_CREATE_USER_DIRECTORY"); + + entity.Property(e => e.AppCreateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USER_GUID"); + + entity.Property(e => e.AppCreateUserid) + .HasMaxLength(255) + .HasColumnName("APP_CREATE_USERID"); + + entity.Property(e => e.AppLastUpdateTimestamp) + .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.AppLastUpdateUserDirectory) + .HasMaxLength(50) + .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); + + entity.Property(e => e.AppLastUpdateUserGuid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USER_GUID"); + + entity.Property(e => e.AppLastUpdateUserid) + .HasMaxLength(255) + .HasColumnName("APP_LAST_UPDATE_USERID"); + + entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); + + entity.Property(e => e.DbCreateTimestamp) + .HasColumnName("DB_CREATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbCreateUserId) + .HasMaxLength(63) + .HasColumnName("DB_CREATE_USER_ID"); + + entity.Property(e => e.DbLastUpdateTimestamp) + .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") + .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); + + entity.Property(e => e.DbLastUpdateUserId) + .HasMaxLength(63) + .HasColumnName("DB_LAST_UPDATE_USER_ID"); + + entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); + + entity.Property(e => e.ExpiryDate).HasColumnName("EXPIRY_DATE"); + + entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); + + entity.Property(e => e.UserId).HasColumnName("USER_ID"); + + entity.HasOne(d => d.Role) + .WithMany(p => p.HetUserRoles) + .HasForeignKey(d => d.RoleId) + .HasConstraintName("FK_HET_USER_ROLE_ROLE_ID"); + + entity.HasOne(d => d.User) + .WithMany(p => p.HetUserRoles) + .HasForeignKey(d => d.UserId) + .HasConstraintName("FK_HET_USER_ROLE_USER_ID"); + }); + + modelBuilder.HasSequence("counter_id_seq"); + + modelBuilder.HasSequence("hash_id_seq"); + + modelBuilder.HasSequence("HET_BATCH_REPORT_ID_seq"); + + modelBuilder.HasSequence("HET_BUSINESS_ID_seq"); + + modelBuilder.HasSequence("HET_BUSINESS_USER_ID_seq"); + + modelBuilder.HasSequence("HET_BUSINESS_USER_ROLE_ID_seq"); + + modelBuilder.HasSequence("HET_CONDITION_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_CONTACT_ID_seq"); + + modelBuilder.HasSequence("HET_DIGITAL_FILE_ID_seq"); + + modelBuilder.HasSequence("HET_DISTRICT_EQUIPMENT_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_DISTRICT_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_ATTACHMENT_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_ATTACHMENT_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_STATUS_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_EQUIPMENT_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_HISTORY_ID_seq"); + + modelBuilder.HasSequence("HET_IMPORT_MAP_ID_seq"); + + modelBuilder.HasSequence("HET_LOCAL_AREA_ID_seq"); + + modelBuilder.HasSequence("HET_LOCAL_AREA_ROTATION_LIST_ID_seq"); + + modelBuilder.HasSequence("HET_MIME_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_NOTE_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_NOTE_ID_seq"); + + modelBuilder.HasSequence("HET_OWNER_ID_seq"); + + modelBuilder.HasSequence("HET_OWNER_STATUS_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_PERMISSION_ID_seq"); + + modelBuilder.HasSequence("HET_PERSON_ID_seq"); + + modelBuilder.HasSequence("HET_PROJECT_ID_seq"); + + modelBuilder.HasSequence("HET_PROJECT_STATUS_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_RATE_PERIOD_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_REGION_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_CONDITION_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_CONDITION_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_RATE_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_RATE_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_STATUS_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_REQUEST_ATTACHMENT_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_REQUEST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_REQUEST_ROTATION_LIST_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_REQUEST_ROTATION_LIST_ID_seq"); + + modelBuilder.HasSequence("HET_RENTAL_REQUEST_STATUS_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_ROLE_ID_seq"); + + modelBuilder.HasSequence("HET_ROLE_PERMISSION_ID_seq"); + + modelBuilder.HasSequence("HET_SENIORITY_AUDIT_ID_seq"); + + modelBuilder.HasSequence("HET_SERVICE_AREA_ID_seq"); + + modelBuilder.HasSequence("HET_TIME_PERIOD_TYPE_ID_seq"); + + modelBuilder.HasSequence("HET_TIME_RECORD_HIST_ID_seq"); + + modelBuilder.HasSequence("HET_TIME_RECORD_ID_seq"); + + modelBuilder.HasSequence("HET_USER_DISTRICT_ID_seq"); + + modelBuilder.HasSequence("HET_USER_FAVOURITE_ID_seq"); + + modelBuilder.HasSequence("HET_USER_ID_seq"); + + modelBuilder.HasSequence("HET_USER_ROLE_ID_seq"); + + modelBuilder.HasSequence("job_id_seq"); + + modelBuilder.HasSequence("jobparameter_id_seq"); + + modelBuilder.HasSequence("jobqueue_id_seq"); + + modelBuilder.HasSequence("list_id_seq"); + + modelBuilder.HasSequence("set_id_seq"); + + modelBuilder.HasSequence("state_id_seq"); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + } +} diff --git a/Server/HetsData/Model/DbAppContextExtension.cs b/Server/HetsData/Entities/DbAppContextExtension.cs similarity index 99% rename from Server/HetsData/Model/DbAppContextExtension.cs rename to Server/HetsData/Entities/DbAppContextExtension.cs index c0bcfcadd..b1ff23e63 100644 --- a/Server/HetsData/Model/DbAppContextExtension.cs +++ b/Server/HetsData/Entities/DbAppContextExtension.cs @@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; -namespace HetsData.Model +namespace HetsData.Entities { public partial class DbAppContext { diff --git a/Server/HetsData/Model/DbAppMonitorContext.cs b/Server/HetsData/Entities/DbAppMonitorContext.cs similarity index 89% rename from Server/HetsData/Model/DbAppMonitorContext.cs rename to Server/HetsData/Entities/DbAppMonitorContext.cs index 4ceda8bf8..349a90bf6 100644 --- a/Server/HetsData/Model/DbAppMonitorContext.cs +++ b/Server/HetsData/Entities/DbAppMonitorContext.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore; -namespace HetsData.Model +namespace HetsData.Entities { public partial class DbAppMonitorContext : DbAppContext { diff --git a/Server/HetsData/Entities/HetBatchReport.cs b/Server/HetsData/Entities/HetBatchReport.cs new file mode 100644 index 000000000..4504482f3 --- /dev/null +++ b/Server/HetsData/Entities/HetBatchReport.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetBatchReport + { + public int ReportId { get; set; } + public string ReportName { get; set; } + public string ReportLink { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public bool? Complete { get; set; } + public int DistrictId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetBusiness.cs b/Server/HetsData/Entities/HetBusiness.cs new file mode 100644 index 000000000..ee3bccf8a --- /dev/null +++ b/Server/HetsData/Entities/HetBusiness.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetBusiness + { + public HetBusiness() + { + HetBusinessUsers = new HashSet(); + HetOwners = new HashSet(); + } + + public int BusinessId { get; set; } + public string BceidLegalName { get; set; } + public string BceidDoingBusinessAs { get; set; } + public string BceidBusinessNumber { get; set; } + public string BceidBusinessGuid { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetBusinessUsers { get; set; } + public virtual ICollection HetOwners { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetBusinessUser.cs b/Server/HetsData/Entities/HetBusinessUser.cs new file mode 100644 index 000000000..fdeee23c4 --- /dev/null +++ b/Server/HetsData/Entities/HetBusinessUser.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetBusinessUser + { + public HetBusinessUser() + { + HetBusinessUserRoles = new HashSet(); + } + + public int BusinessUserId { get; set; } + public string BceidUserId { get; set; } + public string BceidGuid { get; set; } + public string BceidDisplayName { get; set; } + public string BceidFirstName { get; set; } + public string BceidLastName { get; set; } + public string BceidEmail { get; set; } + public string BceidTelephone { get; set; } + public int? BusinessId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetBusiness Business { get; set; } + public virtual ICollection HetBusinessUserRoles { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetBusinessUserRole.cs b/Server/HetsData/Entities/HetBusinessUserRole.cs new file mode 100644 index 000000000..c01d1209f --- /dev/null +++ b/Server/HetsData/Entities/HetBusinessUserRole.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetBusinessUserRole + { + public int BusinessUserRoleId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? ExpiryDate { get; set; } + public int? BusinessUserId { get; set; } + public int? RoleId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetBusinessUser BusinessUser { get; set; } + public virtual HetRole Role { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetConditionType.cs b/Server/HetsData/Entities/HetConditionType.cs new file mode 100644 index 000000000..d8828cef8 --- /dev/null +++ b/Server/HetsData/Entities/HetConditionType.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetConditionType + { + public int ConditionTypeId { get; set; } + public int? DistrictId { get; set; } + public string ConditionTypeCode { get; set; } + public string Description { get; set; } + public bool Active { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetContact.cs b/Server/HetsData/Entities/HetContact.cs new file mode 100644 index 000000000..aa40af41e --- /dev/null +++ b/Server/HetsData/Entities/HetContact.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetContact + { + public HetContact() + { + HetOwners = new HashSet(); + HetProjects = new HashSet(); + } + + public int ContactId { get; set; } + public string Surname { get; set; } + public string GivenName { get; set; } + public string Role { get; set; } + public string Notes { get; set; } + public string EmailAddress { get; set; } + public string MobilePhoneNumber { get; set; } + public string WorkPhoneNumber { get; set; } + public string FaxPhoneNumber { get; set; } + public string Address1 { get; set; } + public string Address2 { get; set; } + public string City { get; set; } + public string PostalCode { get; set; } + public string Province { get; set; } + public int? OwnerId { get; set; } + public int? ProjectId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetOwner Owner { get; set; } + public virtual HetProject Project { get; set; } + public virtual ICollection HetOwners { get; set; } + public virtual ICollection HetProjects { get; set; } + } +} diff --git a/Server/HetsData/Model/HetDbConcurrencyException.cs b/Server/HetsData/Entities/HetDbConcurrencyException.cs similarity index 95% rename from Server/HetsData/Model/HetDbConcurrencyException.cs rename to Server/HetsData/Entities/HetDbConcurrencyException.cs index 46c4b3a72..28d31bc4a 100644 --- a/Server/HetsData/Model/HetDbConcurrencyException.cs +++ b/Server/HetsData/Entities/HetDbConcurrencyException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace HetsData.Model +namespace HetsData.Entities { [Serializable] public class HetsDbConcurrencyException : Exception diff --git a/Server/HetsData/Entities/HetDigitalFile.cs b/Server/HetsData/Entities/HetDigitalFile.cs new file mode 100644 index 000000000..bb88f7095 --- /dev/null +++ b/Server/HetsData/Entities/HetDigitalFile.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetDigitalFile + { + public int DigitalFileId { get; set; } + public string Description { get; set; } + public string FileName { get; set; } + public string Type { get; set; } + public int MimeTypeId { get; set; } + public byte[] FileContents { get; set; } + public int? EquipmentId { get; set; } + public int? OwnerId { get; set; } + public int? ProjectId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + public virtual HetMimeType MimeType { get; set; } + public virtual HetOwner Owner { get; set; } + public virtual HetProject Project { get; set; } + public virtual HetRentalRequest RentalRequest { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetDistrict.cs b/Server/HetsData/Entities/HetDistrict.cs new file mode 100644 index 000000000..5acbd09c5 --- /dev/null +++ b/Server/HetsData/Entities/HetDistrict.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetDistrict + { + public HetDistrict() + { + HetBatchReports = new HashSet(); + HetConditionTypes = new HashSet(); + HetDistrictEquipmentTypes = new HashSet(); + HetProjects = new HashSet(); + HetRentalAgreements = new HashSet(); + HetServiceAreas = new HashSet(); + HetUserDistricts = new HashSet(); + HetUserFavourites = new HashSet(); + HetUsers = new HashSet(); + } + + public int DistrictId { get; set; } + public int? DistrictNumber { get; set; } + public string Name { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public int MinistryDistrictId { get; set; } + public int? RegionId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetRegion Region { get; set; } + public virtual HetRolloverProgress HetRolloverProgress { get; set; } + public virtual ICollection HetBatchReports { get; set; } + public virtual ICollection HetConditionTypes { get; set; } + public virtual ICollection HetDistrictEquipmentTypes { get; set; } + public virtual ICollection HetProjects { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + public virtual ICollection HetServiceAreas { get; set; } + public virtual ICollection HetUserDistricts { get; set; } + public virtual ICollection HetUserFavourites { get; set; } + public virtual ICollection HetUsers { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetDistrictEquipmentType.cs b/Server/HetsData/Entities/HetDistrictEquipmentType.cs new file mode 100644 index 000000000..dde01ca63 --- /dev/null +++ b/Server/HetsData/Entities/HetDistrictEquipmentType.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetDistrictEquipmentType + { + public HetDistrictEquipmentType() + { + HetEquipments = new HashSet(); + HetLocalAreaRotationLists = new HashSet(); + HetRentalRequests = new HashSet(); + } + + public int DistrictEquipmentTypeId { get; set; } + public string DistrictEquipmentName { get; set; } + public int? DistrictId { get; set; } + public int? EquipmentTypeId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public bool Deleted { get; set; } + public int? ServiceAreaId { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual HetEquipmentType EquipmentType { get; set; } + public virtual ICollection HetEquipments { get; set; } + public virtual ICollection HetLocalAreaRotationLists { get; set; } + public virtual ICollection HetRentalRequests { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetDistrictStatus.cs b/Server/HetsData/Entities/HetDistrictStatus.cs new file mode 100644 index 000000000..981c3ffac --- /dev/null +++ b/Server/HetsData/Entities/HetDistrictStatus.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetDistrictStatus + { + public int? DistrictId { get; set; } + public int? CurrentFiscalYear { get; set; } + public int? NextFiscalYear { get; set; } + public DateTime? RolloverStartDate { get; set; } + public DateTime? RolloverEndDate { get; set; } + public int? LocalAreaCount { get; set; } + public int? DistrictEquipmentTypeCount { get; set; } + public int? LocalAreaCompleteCount { get; set; } + public int? DistrictEquipmentTypeCompleteCount { get; set; } + public int? ProgressPercentage { get; set; } + public bool DisplayRolloverMessage { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipment.cs b/Server/HetsData/Entities/HetEquipment.cs new file mode 100644 index 000000000..b51c5068a --- /dev/null +++ b/Server/HetsData/Entities/HetEquipment.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipment + { + public HetEquipment() + { + HetDigitalFiles = new HashSet(); + HetEquipmentAttachments = new HashSet(); + HetHistories = new HashSet(); + HetLocalAreaRotationListAskNextBlock1s = new HashSet(); + HetLocalAreaRotationListAskNextBlock2s = new HashSet(); + HetLocalAreaRotationListAskNextBlockOpens = new HashSet(); + HetNotes = new HashSet(); + HetRentalAgreements = new HashSet(); + HetRentalRequestRotationLists = new HashSet(); + HetRentalRequests = new HashSet(); + HetSeniorityAudits = new HashSet(); + } + + public int EquipmentId { get; set; } + public string Type { get; set; } + public string EquipmentCode { get; set; } + public string Make { get; set; } + public string Model { get; set; } + public string Year { get; set; } + public DateTime ReceivedDate { get; set; } + public float? YearsOfService { get; set; } + public string LicencePlate { get; set; } + public string SerialNumber { get; set; } + public string Size { get; set; } + public float? Seniority { get; set; } + public DateTime? SeniorityEffectiveDate { get; set; } + public DateTime? ToDate { get; set; } + public int? NumberInBlock { get; set; } + public int? BlockNumber { get; set; } + public float? ServiceHoursLastYear { get; set; } + public float? ServiceHoursThreeYearsAgo { get; set; } + public float? ServiceHoursTwoYearsAgo { get; set; } + public bool? IsSeniorityOverridden { get; set; } + public string SeniorityOverrideReason { get; set; } + public DateTime? ApprovedDate { get; set; } + public int EquipmentStatusTypeId { get; set; } + public string StatusComment { get; set; } + public DateTime? ArchiveDate { get; set; } + public string ArchiveCode { get; set; } + public string ArchiveReason { get; set; } + public DateTime LastVerifiedDate { get; set; } + public string InformationUpdateNeededReason { get; set; } + public bool? IsInformationUpdateNeeded { get; set; } + public int? DistrictEquipmentTypeId { get; set; } + public int? LocalAreaId { get; set; } + public string Operator { get; set; } + public int? OwnerId { get; set; } + public float? PayRate { get; set; } + public string RefuseRate { get; set; } + public string LegalCapacity { get; set; } + public string LicencedGvw { get; set; } + public string PupLegalCapacity { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } + public virtual HetEquipmentStatusType EquipmentStatusType { get; set; } + public virtual HetLocalArea LocalArea { get; set; } + public virtual HetOwner Owner { get; set; } + public virtual ICollection HetDigitalFiles { get; set; } + public virtual ICollection HetEquipmentAttachments { get; set; } + public virtual ICollection HetHistories { get; set; } + public virtual ICollection HetLocalAreaRotationListAskNextBlock1s { get; set; } + public virtual ICollection HetLocalAreaRotationListAskNextBlock2s { get; set; } + public virtual ICollection HetLocalAreaRotationListAskNextBlockOpens { get; set; } + public virtual ICollection HetNotes { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + public virtual ICollection HetRentalRequestRotationLists { get; set; } + public virtual ICollection HetRentalRequests { get; set; } + public virtual ICollection HetSeniorityAudits { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipmentAttachment.cs b/Server/HetsData/Entities/HetEquipmentAttachment.cs new file mode 100644 index 000000000..89522328e --- /dev/null +++ b/Server/HetsData/Entities/HetEquipmentAttachment.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipmentAttachment + { + public int EquipmentAttachmentId { get; set; } + public string TypeName { get; set; } + public string Description { get; set; } + public int? EquipmentId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipmentAttachmentHist.cs b/Server/HetsData/Entities/HetEquipmentAttachmentHist.cs new file mode 100644 index 000000000..0f487712f --- /dev/null +++ b/Server/HetsData/Entities/HetEquipmentAttachmentHist.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipmentAttachmentHist + { + public int EquipmentAttachmentHistId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public int EquipmentAttachmentId { get; set; } + public string TypeName { get; set; } + public string Description { get; set; } + public int? EquipmentId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipmentHist.cs b/Server/HetsData/Entities/HetEquipmentHist.cs new file mode 100644 index 000000000..2e291a56e --- /dev/null +++ b/Server/HetsData/Entities/HetEquipmentHist.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipmentHist + { + public int EquipmentHistId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public int EquipmentId { get; set; } + public string Type { get; set; } + public string EquipmentCode { get; set; } + public string Make { get; set; } + public string Model { get; set; } + public string Year { get; set; } + public DateTime ReceivedDate { get; set; } + public float? YearsOfService { get; set; } + public string LicencePlate { get; set; } + public string SerialNumber { get; set; } + public string Size { get; set; } + public float? Seniority { get; set; } + public DateTime? SeniorityEffectiveDate { get; set; } + public DateTime? ToDate { get; set; } + public int? NumberInBlock { get; set; } + public int? BlockNumber { get; set; } + public float? ServiceHoursLastYear { get; set; } + public float? ServiceHoursThreeYearsAgo { get; set; } + public float? ServiceHoursTwoYearsAgo { get; set; } + public bool? IsSeniorityOverridden { get; set; } + public string SeniorityOverrideReason { get; set; } + public DateTime? ApprovedDate { get; set; } + public int EquipmentStatusTypeId { get; set; } + public string StatusComment { get; set; } + public DateTime? ArchiveDate { get; set; } + public string ArchiveCode { get; set; } + public string ArchiveReason { get; set; } + public DateTime LastVerifiedDate { get; set; } + public string InformationUpdateNeededReason { get; set; } + public bool? IsInformationUpdateNeeded { get; set; } + public int? DistrictEquipmentTypeId { get; set; } + public int? LocalAreaId { get; set; } + public string Operator { get; set; } + public int? OwnerId { get; set; } + public float? PayRate { get; set; } + public string RefuseRate { get; set; } + public string LegalCapacity { get; set; } + public string LicencedGvw { get; set; } + public string PupLegalCapacity { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipmentStatusType.cs b/Server/HetsData/Entities/HetEquipmentStatusType.cs new file mode 100644 index 000000000..c1778bb09 --- /dev/null +++ b/Server/HetsData/Entities/HetEquipmentStatusType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipmentStatusType + { + public HetEquipmentStatusType() + { + HetEquipments = new HashSet(); + } + + public int EquipmentStatusTypeId { get; set; } + public string EquipmentStatusTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetEquipments { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetEquipmentType.cs b/Server/HetsData/Entities/HetEquipmentType.cs new file mode 100644 index 000000000..0a015ed71 --- /dev/null +++ b/Server/HetsData/Entities/HetEquipmentType.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetEquipmentType + { + public HetEquipmentType() + { + HetDistrictEquipmentTypes = new HashSet(); + } + + public int EquipmentTypeId { get; set; } + public string Name { get; set; } + public float? BlueBookRateNumber { get; set; } + public float? BlueBookSection { get; set; } + public bool IsDumpTruck { get; set; } + public int NumberOfBlocks { get; set; } + public float? ExtendHours { get; set; } + public float? MaximumHours { get; set; } + public float? MaxHoursSub { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetDistrictEquipmentTypes { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetHistory.cs b/Server/HetsData/Entities/HetHistory.cs new file mode 100644 index 000000000..c0c243fc2 --- /dev/null +++ b/Server/HetsData/Entities/HetHistory.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetHistory + { + public int HistoryId { get; set; } + public DateTime? CreatedDate { get; set; } + public string HistoryText { get; set; } + public int? EquipmentId { get; set; } + public int? OwnerId { get; set; } + public int? ProjectId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + public virtual HetOwner Owner { get; set; } + public virtual HetProject Project { get; set; } + public virtual HetRentalRequest RentalRequest { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetImportMap.cs b/Server/HetsData/Entities/HetImportMap.cs new file mode 100644 index 000000000..6446af2a4 --- /dev/null +++ b/Server/HetsData/Entities/HetImportMap.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetImportMap + { + public int ImportMapId { get; set; } + public string OldTable { get; set; } + public string OldKey { get; set; } + public string NewTable { get; set; } + public int NewKey { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetLocalArea.cs b/Server/HetsData/Entities/HetLocalArea.cs new file mode 100644 index 000000000..99ecf6ddd --- /dev/null +++ b/Server/HetsData/Entities/HetLocalArea.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetLocalArea + { + public HetLocalArea() + { + HetEquipments = new HashSet(); + HetLocalAreaRotationLists = new HashSet(); + HetOwners = new HashSet(); + HetRentalRequests = new HashSet(); + HetSeniorityAudits = new HashSet(); + } + + public int LocalAreaId { get; set; } + public int LocalAreaNumber { get; set; } + public string Name { get; set; } + public DateTime? EndDate { get; set; } + public DateTime StartDate { get; set; } + public int? ServiceAreaId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetServiceArea ServiceArea { get; set; } + public virtual ICollection HetEquipments { get; set; } + public virtual ICollection HetLocalAreaRotationLists { get; set; } + public virtual ICollection HetOwners { get; set; } + public virtual ICollection HetRentalRequests { get; set; } + public virtual ICollection HetSeniorityAudits { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetLocalAreaRotationList.cs b/Server/HetsData/Entities/HetLocalAreaRotationList.cs new file mode 100644 index 000000000..72a47da37 --- /dev/null +++ b/Server/HetsData/Entities/HetLocalAreaRotationList.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetLocalAreaRotationList + { + public int LocalAreaRotationListId { get; set; } + public int? LocalAreaId { get; set; } + public int? DistrictEquipmentTypeId { get; set; } + public int? AskNextBlock1Id { get; set; } + public float? AskNextBlock1Seniority { get; set; } + public int? AskNextBlock2Id { get; set; } + public float? AskNextBlock2Seniority { get; set; } + public int? AskNextBlockOpenId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment AskNextBlock1 { get; set; } + public virtual HetEquipment AskNextBlock2 { get; set; } + public virtual HetEquipment AskNextBlockOpen { get; set; } + public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } + public virtual HetLocalArea LocalArea { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetMimeType.cs b/Server/HetsData/Entities/HetMimeType.cs new file mode 100644 index 000000000..c6dc14f25 --- /dev/null +++ b/Server/HetsData/Entities/HetMimeType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetMimeType + { + public HetMimeType() + { + HetDigitalFiles = new HashSet(); + } + + public int MimeTypeId { get; set; } + public string MimeTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetDigitalFiles { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetNote.cs b/Server/HetsData/Entities/HetNote.cs new file mode 100644 index 000000000..ef0adadc9 --- /dev/null +++ b/Server/HetsData/Entities/HetNote.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetNote + { + public int NoteId { get; set; } + public string Text { get; set; } + public bool? IsNoLongerRelevant { get; set; } + public int? EquipmentId { get; set; } + public int? OwnerId { get; set; } + public int? ProjectId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + public virtual HetOwner Owner { get; set; } + public virtual HetProject Project { get; set; } + public virtual HetRentalRequest RentalRequest { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetNoteHist.cs b/Server/HetsData/Entities/HetNoteHist.cs new file mode 100644 index 000000000..35eeed910 --- /dev/null +++ b/Server/HetsData/Entities/HetNoteHist.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetNoteHist + { + public int NoteHistId { get; set; } + public int NoteId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public string Text { get; set; } + public bool? IsNoLongerRelevant { get; set; } + public int? EquipmentId { get; set; } + public int? OwnerId { get; set; } + public int? ProjectId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetOwner.cs b/Server/HetsData/Entities/HetOwner.cs new file mode 100644 index 000000000..b8d86c5e3 --- /dev/null +++ b/Server/HetsData/Entities/HetOwner.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetOwner + { + public HetOwner() + { + HetContacts = new HashSet(); + HetDigitalFiles = new HashSet(); + HetEquipments = new HashSet(); + HetHistories = new HashSet(); + HetNotes = new HashSet(); + HetSeniorityAudits = new HashSet(); + } + + public int OwnerId { get; set; } + public string OrganizationName { get; set; } + public string OwnerCode { get; set; } + public string DoingBusinessAs { get; set; } + public string Surname { get; set; } + public string GivenName { get; set; } + public string RegisteredCompanyNumber { get; set; } + public string Address1 { get; set; } + public string Address2 { get; set; } + public string City { get; set; } + public string PostalCode { get; set; } + public string Province { get; set; } + public int OwnerStatusTypeId { get; set; } + public string StatusComment { get; set; } + public DateTime? ArchiveDate { get; set; } + public string ArchiveCode { get; set; } + public string ArchiveReason { get; set; } + public int? LocalAreaId { get; set; } + public int? PrimaryContactId { get; set; } + public string CglCompany { get; set; } + public string CglPolicyNumber { get; set; } + public DateTime? CglendDate { get; set; } + public string WorkSafeBcpolicyNumber { get; set; } + public DateTime? WorkSafeBcexpiryDate { get; set; } + public bool? IsMaintenanceContractor { get; set; } + public bool MeetsResidency { get; set; } + public int? BusinessId { get; set; } + public string SharedKey { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetBusiness Business { get; set; } + public virtual HetLocalArea LocalArea { get; set; } + public virtual HetOwnerStatusType OwnerStatusType { get; set; } + public virtual HetContact PrimaryContact { get; set; } + public virtual ICollection HetContacts { get; set; } + public virtual ICollection HetDigitalFiles { get; set; } + public virtual ICollection HetEquipments { get; set; } + public virtual ICollection HetHistories { get; set; } + public virtual ICollection HetNotes { get; set; } + public virtual ICollection HetSeniorityAudits { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetOwnerStatusType.cs b/Server/HetsData/Entities/HetOwnerStatusType.cs new file mode 100644 index 000000000..9c665e7d6 --- /dev/null +++ b/Server/HetsData/Entities/HetOwnerStatusType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetOwnerStatusType + { + public HetOwnerStatusType() + { + HetOwners = new HashSet(); + } + + public int OwnerStatusTypeId { get; set; } + public string OwnerStatusTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetOwners { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetPermission.cs b/Server/HetsData/Entities/HetPermission.cs new file mode 100644 index 000000000..914dc1347 --- /dev/null +++ b/Server/HetsData/Entities/HetPermission.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetPermission + { + public HetPermission() + { + HetRolePermissions = new HashSet(); + } + + public int PermissionId { get; set; } + public string Code { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetRolePermissions { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetPerson.cs b/Server/HetsData/Entities/HetPerson.cs new file mode 100644 index 000000000..d1d990fb2 --- /dev/null +++ b/Server/HetsData/Entities/HetPerson.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetPerson + { + public int PersonId { get; set; } + public string Surname { get; set; } + public string FirstName { get; set; } + public string MiddleNames { get; set; } + public string NameSuffix { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetProject.cs b/Server/HetsData/Entities/HetProject.cs new file mode 100644 index 000000000..0590ac460 --- /dev/null +++ b/Server/HetsData/Entities/HetProject.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetProject + { + public HetProject() + { + HetContacts = new HashSet(); + HetDigitalFiles = new HashSet(); + HetHistories = new HashSet(); + HetNotes = new HashSet(); + HetRentalAgreements = new HashSet(); + HetRentalRequests = new HashSet(); + } + + public int ProjectId { get; set; } + public string ProvincialProjectNumber { get; set; } + public string Name { get; set; } + public int ProjectStatusTypeId { get; set; } + public string Information { get; set; } + public int? DistrictId { get; set; } + public int? PrimaryContactId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public string FiscalYear { get; set; } + public string ResponsibilityCentre { get; set; } + public string ServiceLine { get; set; } + public string Stob { get; set; } + public string Product { get; set; } + public string BusinessFunction { get; set; } + public string WorkActivity { get; set; } + public string CostType { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual HetContact PrimaryContact { get; set; } + public virtual HetProjectStatusType ProjectStatusType { get; set; } + public virtual ICollection HetContacts { get; set; } + public virtual ICollection HetDigitalFiles { get; set; } + public virtual ICollection HetHistories { get; set; } + public virtual ICollection HetNotes { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + public virtual ICollection HetRentalRequests { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetProjectStatusType.cs b/Server/HetsData/Entities/HetProjectStatusType.cs new file mode 100644 index 000000000..63df8c7d5 --- /dev/null +++ b/Server/HetsData/Entities/HetProjectStatusType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetProjectStatusType + { + public HetProjectStatusType() + { + HetProjects = new HashSet(); + } + + public int ProjectStatusTypeId { get; set; } + public string ProjectStatusTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetProjects { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetProvincialRateType.cs b/Server/HetsData/Entities/HetProvincialRateType.cs new file mode 100644 index 000000000..34db37608 --- /dev/null +++ b/Server/HetsData/Entities/HetProvincialRateType.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetProvincialRateType + { + public string RateType { get; set; } + public bool Active { get; set; } + public string Description { get; set; } + public string PeriodType { get; set; } + public float? Rate { get; set; } + public bool Overtime { get; set; } + public bool IsIncludedInTotal { get; set; } + public bool IsPercentRate { get; set; } + public bool IsRateEditable { get; set; } + public bool IsInTotalEditable { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRatePeriodType.cs b/Server/HetsData/Entities/HetRatePeriodType.cs new file mode 100644 index 000000000..b7d04c4da --- /dev/null +++ b/Server/HetsData/Entities/HetRatePeriodType.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRatePeriodType + { + public HetRatePeriodType() + { + HetRentalAgreementRates = new HashSet(); + HetRentalAgreements = new HashSet(); + } + + public int RatePeriodTypeId { get; set; } + public string RatePeriodTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetRentalAgreementRates { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRegion.cs b/Server/HetsData/Entities/HetRegion.cs new file mode 100644 index 000000000..826711390 --- /dev/null +++ b/Server/HetsData/Entities/HetRegion.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRegion + { + public HetRegion() + { + HetDistricts = new HashSet(); + } + + public int RegionId { get; set; } + public string Name { get; set; } + public int? RegionNumber { get; set; } + public int MinistryRegionId { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetDistricts { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreement.cs b/Server/HetsData/Entities/HetRentalAgreement.cs new file mode 100644 index 000000000..d1fec711c --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreement.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreement + { + public HetRentalAgreement() + { + HetRentalAgreementConditions = new HashSet(); + HetRentalAgreementRates = new HashSet(); + HetRentalRequestRotationLists = new HashSet(); + HetTimeRecords = new HashSet(); + } + + public int RentalAgreementId { get; set; } + public string Number { get; set; } + public int? EstimateHours { get; set; } + public DateTime? EstimateStartWork { get; set; } + public string Note { get; set; } + public float? EquipmentRate { get; set; } + public string RateComment { get; set; } + public int RatePeriodTypeId { get; set; } + public DateTime? DatedOn { get; set; } + public int RentalAgreementStatusTypeId { get; set; } + public int? EquipmentId { get; set; } + public int? ProjectId { get; set; } + public int? DistrictId { get; set; } + public int? RentalRequestId { get; set; } + public int? RentalRequestRotationListId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public string AgreementCity { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual HetEquipment Equipment { get; set; } + public virtual HetProject Project { get; set; } + public virtual HetRatePeriodType RatePeriodType { get; set; } + public virtual HetRentalAgreementStatusType RentalAgreementStatusType { get; set; } + public virtual HetRentalRequest RentalRequest { get; set; } + public virtual HetRentalRequestRotationList RentalRequestRotationList { get; set; } + public virtual ICollection HetRentalAgreementConditions { get; set; } + public virtual ICollection HetRentalAgreementRates { get; set; } + public virtual ICollection HetRentalRequestRotationLists { get; set; } + public virtual ICollection HetTimeRecords { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementCondition.cs b/Server/HetsData/Entities/HetRentalAgreementCondition.cs new file mode 100644 index 000000000..a13b2fafe --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementCondition.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementCondition + { + public int RentalAgreementConditionId { get; set; } + public string Comment { get; set; } + public string ConditionName { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetRentalAgreement RentalAgreement { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementConditionHist.cs b/Server/HetsData/Entities/HetRentalAgreementConditionHist.cs new file mode 100644 index 000000000..1ea9f5377 --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementConditionHist.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementConditionHist + { + public int RentalAgreementConditionHistId { get; set; } + public int RentalAgreementConditionId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public string Comment { get; set; } + public string ConditionName { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementHist.cs b/Server/HetsData/Entities/HetRentalAgreementHist.cs new file mode 100644 index 000000000..fbb9abd12 --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementHist.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementHist + { + public int RentalAgreementHistId { get; set; } + public int RentalAgreementId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public string Number { get; set; } + public int? EstimateHours { get; set; } + public DateTime? EstimateStartWork { get; set; } + public string Note { get; set; } + public float? EquipmentRate { get; set; } + public string RateComment { get; set; } + public int RatePeriodTypeId { get; set; } + public DateTime? DatedOn { get; set; } + public int RentalAgreementStatusTypeId { get; set; } + public int? EquipmentId { get; set; } + public int? ProjectId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public string AgreementCity { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementRate.cs b/Server/HetsData/Entities/HetRentalAgreementRate.cs new file mode 100644 index 000000000..4d842e00e --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementRate.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementRate + { + public HetRentalAgreementRate() + { + HetTimeRecords = new HashSet(); + } + + public int RentalAgreementRateId { get; set; } + public string Comment { get; set; } + public string ComponentName { get; set; } + public float? Rate { get; set; } + public bool? Overtime { get; set; } + public bool? Active { get; set; } + public bool IsIncludedInTotal { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public bool? Set { get; set; } + public int? RatePeriodTypeId { get; set; } + + public virtual HetRatePeriodType RatePeriodType { get; set; } + public virtual HetRentalAgreement RentalAgreement { get; set; } + public virtual ICollection HetTimeRecords { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementRateHist.cs b/Server/HetsData/Entities/HetRentalAgreementRateHist.cs new file mode 100644 index 000000000..479bc8a43 --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementRateHist.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementRateHist + { + public int RentalAgreementRateHistId { get; set; } + public int RentalAgreementRateId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public string Comment { get; set; } + public string ComponentName { get; set; } + public float? Rate { get; set; } + public bool? Overtime { get; set; } + public bool? Active { get; set; } + public bool IsIncludedInTotal { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + public bool? Set { get; set; } + public int? RatePeriodTypeId { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalAgreementStatusType.cs b/Server/HetsData/Entities/HetRentalAgreementStatusType.cs new file mode 100644 index 000000000..5436a1e8b --- /dev/null +++ b/Server/HetsData/Entities/HetRentalAgreementStatusType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalAgreementStatusType + { + public HetRentalAgreementStatusType() + { + HetRentalAgreements = new HashSet(); + } + + public int RentalAgreementStatusTypeId { get; set; } + public string RentalAgreementStatusTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetRentalAgreements { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalRequest.cs b/Server/HetsData/Entities/HetRentalRequest.cs new file mode 100644 index 000000000..e46d01b28 --- /dev/null +++ b/Server/HetsData/Entities/HetRentalRequest.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalRequest + { + public HetRentalRequest() + { + HetDigitalFiles = new HashSet(); + HetHistories = new HashSet(); + HetNotes = new HashSet(); + HetRentalAgreements = new HashSet(); + HetRentalRequestAttachments = new HashSet(); + HetRentalRequestRotationLists = new HashSet(); + } + + public int RentalRequestId { get; set; } + public int EquipmentCount { get; set; } + public DateTime? ExpectedStartDate { get; set; } + public DateTime? ExpectedEndDate { get; set; } + public int? ExpectedHours { get; set; } + public int? FirstOnRotationListId { get; set; } + public int RentalRequestStatusTypeId { get; set; } + public int? DistrictEquipmentTypeId { get; set; } + public int? LocalAreaId { get; set; } + public int? ProjectId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } + public virtual HetEquipment FirstOnRotationList { get; set; } + public virtual HetLocalArea LocalArea { get; set; } + public virtual HetProject Project { get; set; } + public virtual HetRentalRequestStatusType RentalRequestStatusType { get; set; } + public virtual ICollection HetDigitalFiles { get; set; } + public virtual ICollection HetHistories { get; set; } + public virtual ICollection HetNotes { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + public virtual ICollection HetRentalRequestAttachments { get; set; } + public virtual ICollection HetRentalRequestRotationLists { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalRequestAttachment.cs b/Server/HetsData/Entities/HetRentalRequestAttachment.cs new file mode 100644 index 000000000..6df67a9cb --- /dev/null +++ b/Server/HetsData/Entities/HetRentalRequestAttachment.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalRequestAttachment + { + public int RentalRequestAttachmentId { get; set; } + public string Attachment { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetRentalRequest RentalRequest { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalRequestRotationList.cs b/Server/HetsData/Entities/HetRentalRequestRotationList.cs new file mode 100644 index 000000000..dda97ae1b --- /dev/null +++ b/Server/HetsData/Entities/HetRentalRequestRotationList.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalRequestRotationList + { + public HetRentalRequestRotationList() + { + HetRentalAgreements = new HashSet(); + } + + public int RentalRequestRotationListId { get; set; } + public int RotationListSortOrder { get; set; } + public DateTime? AskedDateTime { get; set; } + public bool? WasAsked { get; set; } + public string OfferResponse { get; set; } + public string OfferResponseNote { get; set; } + public string OfferRefusalReason { get; set; } + public DateTime? OfferResponseDatetime { get; set; } + public bool? IsForceHire { get; set; } + public string Note { get; set; } + public int? EquipmentId { get; set; } + public int? RentalAgreementId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + public virtual HetRentalAgreement RentalAgreement { get; set; } + public virtual HetRentalRequest RentalRequest { get; set; } + public virtual ICollection HetRentalAgreements { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalRequestRotationListHist.cs b/Server/HetsData/Entities/HetRentalRequestRotationListHist.cs new file mode 100644 index 000000000..883987f71 --- /dev/null +++ b/Server/HetsData/Entities/HetRentalRequestRotationListHist.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalRequestRotationListHist + { + public int RentalRequestRotationListHistId { get; set; } + public int RentalRequestRotationListId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public int RotationListSortOrder { get; set; } + public DateTime? AskedDateTime { get; set; } + public bool? WasAsked { get; set; } + public string OfferResponse { get; set; } + public string OfferResponseNote { get; set; } + public string OfferRefusalReason { get; set; } + public DateTime? OfferResponseDatetime { get; set; } + public bool? IsForceHire { get; set; } + public string Note { get; set; } + public int? EquipmentId { get; set; } + public int? RentalAgreementId { get; set; } + public int? RentalRequestId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRentalRequestStatusType.cs b/Server/HetsData/Entities/HetRentalRequestStatusType.cs new file mode 100644 index 000000000..c5a8de0db --- /dev/null +++ b/Server/HetsData/Entities/HetRentalRequestStatusType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRentalRequestStatusType + { + public HetRentalRequestStatusType() + { + HetRentalRequests = new HashSet(); + } + + public int RentalRequestStatusTypeId { get; set; } + public string RentalRequestStatusTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetRentalRequests { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRole.cs b/Server/HetsData/Entities/HetRole.cs new file mode 100644 index 000000000..c74a80fd0 --- /dev/null +++ b/Server/HetsData/Entities/HetRole.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRole + { + public HetRole() + { + HetBusinessUserRoles = new HashSet(); + HetRolePermissions = new HashSet(); + HetUserRoles = new HashSet(); + } + + public int RoleId { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetBusinessUserRoles { get; set; } + public virtual ICollection HetRolePermissions { get; set; } + public virtual ICollection HetUserRoles { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRolePermission.cs b/Server/HetsData/Entities/HetRolePermission.cs new file mode 100644 index 000000000..a3d4b033e --- /dev/null +++ b/Server/HetsData/Entities/HetRolePermission.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRolePermission + { + public int RolePermissionId { get; set; } + public int? PermissionId { get; set; } + public int? RoleId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetPermission Permission { get; set; } + public virtual HetRole Role { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetRolloverProgress.cs b/Server/HetsData/Entities/HetRolloverProgress.cs new file mode 100644 index 000000000..d8b37b11c --- /dev/null +++ b/Server/HetsData/Entities/HetRolloverProgress.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetRolloverProgress + { + public int DistrictId { get; set; } + public int? ProgressPercentage { get; set; } + + public virtual HetDistrict District { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetSeniorityAudit.cs b/Server/HetsData/Entities/HetSeniorityAudit.cs new file mode 100644 index 000000000..22820c924 --- /dev/null +++ b/Server/HetsData/Entities/HetSeniorityAudit.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetSeniorityAudit + { + public int SeniorityAuditId { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + public string OwnerOrganizationName { get; set; } + public float? Seniority { get; set; } + public int? BlockNumber { get; set; } + public bool? IsSeniorityOverridden { get; set; } + public string SeniorityOverrideReason { get; set; } + public float? ServiceHoursLastYear { get; set; } + public float? ServiceHoursThreeYearsAgo { get; set; } + public float? ServiceHoursTwoYearsAgo { get; set; } + public int? EquipmentId { get; set; } + public int? LocalAreaId { get; set; } + public int? OwnerId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetEquipment Equipment { get; set; } + public virtual HetLocalArea LocalArea { get; set; } + public virtual HetOwner Owner { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetServiceArea.cs b/Server/HetsData/Entities/HetServiceArea.cs new file mode 100644 index 000000000..c4772bf52 --- /dev/null +++ b/Server/HetsData/Entities/HetServiceArea.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetServiceArea + { + public HetServiceArea() + { + HetLocalAreas = new HashSet(); + } + + public int ServiceAreaId { get; set; } + public string Name { get; set; } + public int? AreaNumber { get; set; } + public int MinistryServiceAreaId { get; set; } + public DateTime FiscalStartDate { get; set; } + public DateTime? FiscalEndDate { get; set; } + public string Address { get; set; } + public string Phone { get; set; } + public string Fax { get; set; } + public string SupportingDocuments { get; set; } + public int? DistrictId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual ICollection HetLocalAreas { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetTimePeriodType.cs b/Server/HetsData/Entities/HetTimePeriodType.cs new file mode 100644 index 000000000..53145ec99 --- /dev/null +++ b/Server/HetsData/Entities/HetTimePeriodType.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetTimePeriodType + { + public HetTimePeriodType() + { + HetTimeRecords = new HashSet(); + } + + public int TimePeriodTypeId { get; set; } + public string TimePeriodTypeCode { get; set; } + public string Description { get; set; } + public string ScreenLabel { get; set; } + public int? DisplayOrder { get; set; } + public bool? IsActive { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual ICollection HetTimeRecords { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetTimeRecord.cs b/Server/HetsData/Entities/HetTimeRecord.cs new file mode 100644 index 000000000..154d7f926 --- /dev/null +++ b/Server/HetsData/Entities/HetTimeRecord.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetTimeRecord + { + public int TimeRecordId { get; set; } + public DateTime? EnteredDate { get; set; } + public DateTime WorkedDate { get; set; } + public int TimePeriodTypeId { get; set; } + public float? Hours { get; set; } + public int? RentalAgreementRateId { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetRentalAgreement RentalAgreement { get; set; } + public virtual HetRentalAgreementRate RentalAgreementRate { get; set; } + public virtual HetTimePeriodType TimePeriodType { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetTimeRecordHist.cs b/Server/HetsData/Entities/HetTimeRecordHist.cs new file mode 100644 index 000000000..5ee1e80f9 --- /dev/null +++ b/Server/HetsData/Entities/HetTimeRecordHist.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetTimeRecordHist + { + public int TimeRecordHistId { get; set; } + public int TimeRecordId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? EndDate { get; set; } + public DateTime? EnteredDate { get; set; } + public DateTime WorkedDate { get; set; } + public int TimePeriodTypeId { get; set; } + public float? Hours { get; set; } + public int? RentalAgreementRateId { get; set; } + public int? RentalAgreementId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetUser.cs b/Server/HetsData/Entities/HetUser.cs new file mode 100644 index 000000000..63359edbc --- /dev/null +++ b/Server/HetsData/Entities/HetUser.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetUser + { + public HetUser() + { + HetUserDistricts = new HashSet(); + HetUserFavourites = new HashSet(); + HetUserRoles = new HashSet(); + } + + public int UserId { get; set; } + public string Surname { get; set; } + public string GivenName { get; set; } + public string Initials { get; set; } + public string SmUserId { get; set; } + public string SmAuthorizationDirectory { get; set; } + public string Guid { get; set; } + public string Email { get; set; } + public string AgreementCity { get; set; } + public bool Active { get; set; } + public int? DistrictId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual ICollection HetUserDistricts { get; set; } + public virtual ICollection HetUserFavourites { get; set; } + public virtual ICollection HetUserRoles { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetUserDistrict.cs b/Server/HetsData/Entities/HetUserDistrict.cs new file mode 100644 index 000000000..77d468001 --- /dev/null +++ b/Server/HetsData/Entities/HetUserDistrict.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetUserDistrict + { + public int UserDistrictId { get; set; } + public bool IsPrimary { get; set; } + public int? UserId { get; set; } + public int? DistrictId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual HetUser User { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetUserFavourite.cs b/Server/HetsData/Entities/HetUserFavourite.cs new file mode 100644 index 000000000..f777ec32b --- /dev/null +++ b/Server/HetsData/Entities/HetUserFavourite.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetUserFavourite + { + public int UserFavouriteId { get; set; } + public string Type { get; set; } + public string Name { get; set; } + public string Value { get; set; } + public bool? IsDefault { get; set; } + public int? UserId { get; set; } + public int? DistrictId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetDistrict District { get; set; } + public virtual HetUser User { get; set; } + } +} diff --git a/Server/HetsData/Entities/HetUserRole.cs b/Server/HetsData/Entities/HetUserRole.cs new file mode 100644 index 000000000..a8fc29d60 --- /dev/null +++ b/Server/HetsData/Entities/HetUserRole.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace HetsData.Entities +{ + public partial class HetUserRole + { + public int UserRoleId { get; set; } + public DateTime EffectiveDate { get; set; } + public DateTime? ExpiryDate { get; set; } + public int? UserId { get; set; } + public int? RoleId { get; set; } + public string AppCreateUserDirectory { get; set; } + public string AppCreateUserGuid { get; set; } + public string AppCreateUserid { get; set; } + public DateTime AppCreateTimestamp { get; set; } + public string AppLastUpdateUserDirectory { get; set; } + public string AppLastUpdateUserGuid { get; set; } + public string AppLastUpdateUserid { get; set; } + public DateTime AppLastUpdateTimestamp { get; set; } + public string DbCreateUserId { get; set; } + public DateTime DbCreateTimestamp { get; set; } + public DateTime DbLastUpdateTimestamp { get; set; } + public string DbLastUpdateUserId { get; set; } + public int ConcurrencyControlNumber { get; set; } + + public virtual HetRole Role { get; set; } + public virtual HetUser User { get; set; } + } +} diff --git a/Server/HetsData/Extension/HetAttachmentExtension.cs b/Server/HetsData/Extension/HetAttachmentExtension.cs index b1d19e2bb..77f311e66 100644 --- a/Server/HetsData/Extension/HetAttachmentExtension.cs +++ b/Server/HetsData/Extension/HetAttachmentExtension.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetDigitalFile { diff --git a/Server/HetsData/Extension/HetBusinessUserExtension.cs b/Server/HetsData/Extension/HetBusinessUserExtension.cs index 693d010ef..efc56d79b 100644 --- a/Server/HetsData/Extension/HetBusinessUserExtension.cs +++ b/Server/HetsData/Extension/HetBusinessUserExtension.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Security.Claims; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetBusinessUser { diff --git a/Server/HetsData/Extension/HetDistrictEquipmentTypeExtension.cs b/Server/HetsData/Extension/HetDistrictEquipmentTypeExtension.cs index d1c7742b3..2aadcf3c4 100644 --- a/Server/HetsData/Extension/HetDistrictEquipmentTypeExtension.cs +++ b/Server/HetsData/Extension/HetDistrictEquipmentTypeExtension.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetDistrictEquipmentType { diff --git a/Server/HetsData/Extension/HetEquipmentExtension.cs b/Server/HetsData/Extension/HetEquipmentExtension.cs index 1fc00227a..1fe9bad19 100644 --- a/Server/HetsData/Extension/HetEquipmentExtension.cs +++ b/Server/HetsData/Extension/HetEquipmentExtension.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetEquipment { diff --git a/Server/HetsData/Extension/HetOwnerExtension.cs b/Server/HetsData/Extension/HetOwnerExtension.cs index 897dda480..40505d049 100644 --- a/Server/HetsData/Extension/HetOwnerExtension.cs +++ b/Server/HetsData/Extension/HetOwnerExtension.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetOwner { diff --git a/Server/HetsData/Extension/HetPermissionExtension.cs b/Server/HetsData/Extension/HetPermissionExtension.cs index a5664f063..d4f07af7f 100644 --- a/Server/HetsData/Extension/HetPermissionExtension.cs +++ b/Server/HetsData/Extension/HetPermissionExtension.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace HetsData.Model +namespace HetsData.Entities { /// /// Permission Database Model Extension diff --git a/Server/HetsData/Extension/HetProjectExtension.cs b/Server/HetsData/Extension/HetProjectExtension.cs index bc71be6f9..1f655e33a 100644 --- a/Server/HetsData/Extension/HetProjectExtension.cs +++ b/Server/HetsData/Extension/HetProjectExtension.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { /// /// Rental Request Database Model Extension diff --git a/Server/HetsData/Extension/HetProvincialRateTypeExtension.cs b/Server/HetsData/Extension/HetProvincialRateTypeExtension.cs index e42984fd1..633b7c8e0 100644 --- a/Server/HetsData/Extension/HetProvincialRateTypeExtension.cs +++ b/Server/HetsData/Extension/HetProvincialRateTypeExtension.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { /// /// Provincial Rate Type Database Model Extension diff --git a/Server/HetsData/Extension/HetRatePeriodTypeExtension.cs b/Server/HetsData/Extension/HetRatePeriodTypeExtension.cs index cab7eaffa..f96ac03d9 100644 --- a/Server/HetsData/Extension/HetRatePeriodTypeExtension.cs +++ b/Server/HetsData/Extension/HetRatePeriodTypeExtension.cs @@ -1,4 +1,4 @@ -namespace HetsData.Model +namespace HetsData.Entities { /// /// Rate Period Type Database Model Extension diff --git a/Server/HetsData/Extension/HetRentalAgreementExtension.cs b/Server/HetsData/Extension/HetRentalAgreementExtension.cs index fc389cdf5..da46efd30 100644 --- a/Server/HetsData/Extension/HetRentalAgreementExtension.cs +++ b/Server/HetsData/Extension/HetRentalAgreementExtension.cs @@ -2,7 +2,7 @@ using System.ComponentModel.DataAnnotations.Schema; using Newtonsoft.Json; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetRentalAgreement { diff --git a/Server/HetsData/Extension/HetRentalAgreementRateExtension.cs b/Server/HetsData/Extension/HetRentalAgreementRateExtension.cs index 3bede3215..953958caf 100644 --- a/Server/HetsData/Extension/HetRentalAgreementRateExtension.cs +++ b/Server/HetsData/Extension/HetRentalAgreementRateExtension.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetRentalAgreementRate { diff --git a/Server/HetsData/Extension/HetRentalRequestExtension.cs b/Server/HetsData/Extension/HetRentalRequestExtension.cs index d3418faff..f3e3d1d5b 100644 --- a/Server/HetsData/Extension/HetRentalRequestExtension.cs +++ b/Server/HetsData/Extension/HetRentalRequestExtension.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { /// /// Rental Request Database Model Extension diff --git a/Server/HetsData/Extension/HetRentalRequestRotationListExtension.cs b/Server/HetsData/Extension/HetRentalRequestRotationListExtension.cs index 6266ea789..d9b7b4463 100644 --- a/Server/HetsData/Extension/HetRentalRequestRotationListExtension.cs +++ b/Server/HetsData/Extension/HetRentalRequestRotationListExtension.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { /// /// Rental Request Rotation List Database Model Extension diff --git a/Server/HetsData/Extension/HetTimePeriodTypeExtension.cs b/Server/HetsData/Extension/HetTimePeriodTypeExtension.cs index b9082dc19..0947cb2ef 100644 --- a/Server/HetsData/Extension/HetTimePeriodTypeExtension.cs +++ b/Server/HetsData/Extension/HetTimePeriodTypeExtension.cs @@ -1,5 +1,5 @@  -namespace HetsData.Model +namespace HetsData.Entities { /// /// Time Period Type Database Model Extension diff --git a/Server/HetsData/Extension/HetTimeRecordExtension.cs b/Server/HetsData/Extension/HetTimeRecordExtension.cs index 848836c4f..315a6287c 100644 --- a/Server/HetsData/Extension/HetTimeRecordExtension.cs +++ b/Server/HetsData/Extension/HetTimeRecordExtension.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetTimeRecord { diff --git a/Server/HetsData/Extension/HetUserExtension.cs b/Server/HetsData/Extension/HetUserExtension.cs index 8d01bea1c..fd363c3db 100644 --- a/Server/HetsData/Extension/HetUserExtension.cs +++ b/Server/HetsData/Extension/HetUserExtension.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Security.Claims; -namespace HetsData.Model +namespace HetsData.Entities { public partial class HetUser { diff --git a/Server/HetsData/Hangfire/AnnualRollover.cs b/Server/HetsData/Hangfire/AnnualRollover.cs index aea681a78..f361b8f03 100644 --- a/Server/HetsData/Hangfire/AnnualRollover.cs +++ b/Server/HetsData/Hangfire/AnnualRollover.cs @@ -1,7 +1,7 @@ using Hangfire; using HetsApi.Helpers; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using HetsData.Dtos; using Microsoft.EntityFrameworkCore; using System; diff --git a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs index 52bd03540..aad48eb2b 100644 --- a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs +++ b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs @@ -1,5 +1,5 @@ using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; diff --git a/Server/HetsData/Hangfire/SeniorityCalculator.cs b/Server/HetsData/Hangfire/SeniorityCalculator.cs index 22fbbf764..7a22dea7c 100644 --- a/Server/HetsData/Hangfire/SeniorityCalculator.cs +++ b/Server/HetsData/Hangfire/SeniorityCalculator.cs @@ -1,6 +1,6 @@ using Hangfire; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using System; using System.Collections.Generic; using System.Linq; diff --git a/Server/HetsData/Helpers/EquipmentHelper.cs b/Server/HetsData/Helpers/EquipmentHelper.cs index 26721dd1e..b78fc6eed 100644 --- a/Server/HetsData/Helpers/EquipmentHelper.cs +++ b/Server/HetsData/Helpers/EquipmentHelper.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using HetsData.Model; +using HetsData.Entities; using Hangfire.Server; using Hangfire.Console; using HetsApi.Helpers; diff --git a/Server/HetsData/Helpers/OwnerHelper.cs b/Server/HetsData/Helpers/OwnerHelper.cs index c9ba5d876..c42d387e5 100644 --- a/Server/HetsData/Helpers/OwnerHelper.cs +++ b/Server/HetsData/Helpers/OwnerHelper.cs @@ -4,7 +4,7 @@ using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using HetsData.Model; +using HetsData.Entities; using HetsData.Dtos; namespace HetsData.Helpers diff --git a/Server/HetsData/Helpers/PermissionHelper.cs b/Server/HetsData/Helpers/PermissionHelper.cs index 215f8940c..28a9261ae 100644 --- a/Server/HetsData/Helpers/PermissionHelper.cs +++ b/Server/HetsData/Helpers/PermissionHelper.cs @@ -1,4 +1,4 @@ -using HetsData.Model; +using HetsData.Entities; namespace HetsData.Helpers { diff --git a/Server/HetsData/Helpers/ProjectHelper.cs b/Server/HetsData/Helpers/ProjectHelper.cs index 6d88f5c7c..bc5cda377 100644 --- a/Server/HetsData/Helpers/ProjectHelper.cs +++ b/Server/HetsData/Helpers/ProjectHelper.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using HetsData.Dtos; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; namespace HetsData.Helpers diff --git a/Server/HetsData/Helpers/RentalAgreementHelper.cs b/Server/HetsData/Helpers/RentalAgreementHelper.cs index 4ea76ea52..5ee95eaea 100644 --- a/Server/HetsData/Helpers/RentalAgreementHelper.cs +++ b/Server/HetsData/Helpers/RentalAgreementHelper.cs @@ -4,7 +4,7 @@ using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using HetsData.Model; +using HetsData.Entities; using HetsData.Dtos; namespace HetsData.Helpers diff --git a/Server/HetsData/Helpers/RentalRequestHelper.cs b/Server/HetsData/Helpers/RentalRequestHelper.cs index 5e03b6087..2c199814f 100644 --- a/Server/HetsData/Helpers/RentalRequestHelper.cs +++ b/Server/HetsData/Helpers/RentalRequestHelper.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text.RegularExpressions; using HetsData.Dtos; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/Server/HetsData/Helpers/SeniorityListHelper.cs b/Server/HetsData/Helpers/SeniorityListHelper.cs index f6b1fb9e4..84ffa9b65 100644 --- a/Server/HetsData/Helpers/SeniorityListHelper.cs +++ b/Server/HetsData/Helpers/SeniorityListHelper.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; -using HetsData.Model; +using HetsData.Entities; namespace HetsData.Helpers { diff --git a/Server/HetsData/Helpers/StatusHelper.cs b/Server/HetsData/Helpers/StatusHelper.cs index f491c6969..a61a9594e 100644 --- a/Server/HetsData/Helpers/StatusHelper.cs +++ b/Server/HetsData/Helpers/StatusHelper.cs @@ -1,5 +1,5 @@ using System.Linq; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; namespace HetsData.Helpers diff --git a/Server/HetsData/Helpers/TimeRecordHelper.cs b/Server/HetsData/Helpers/TimeRecordHelper.cs index b91066989..17db576dd 100644 --- a/Server/HetsData/Helpers/TimeRecordHelper.cs +++ b/Server/HetsData/Helpers/TimeRecordHelper.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using HetsData.Dtos; -using HetsData.Model; +using HetsData.Entities; namespace HetsData.Helpers { diff --git a/Server/HetsData/Helpers/UserHelper.cs b/Server/HetsData/Helpers/UserHelper.cs index 465aaccb7..7be1dc731 100644 --- a/Server/HetsData/Helpers/UserHelper.cs +++ b/Server/HetsData/Helpers/UserHelper.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; namespace HetsData.Helpers diff --git a/Server/HetsData/Mappings/DtoToEntityProfile.cs b/Server/HetsData/Mappings/DtoToEntityProfile.cs index cdaf7a775..24c2fbcf2 100644 --- a/Server/HetsData/Mappings/DtoToEntityProfile.cs +++ b/Server/HetsData/Mappings/DtoToEntityProfile.cs @@ -1,6 +1,6 @@ using AutoMapper; using HetsData.Dtos; -using HetsData.Model; +using HetsData.Entities; namespace HetsData.Mappings { diff --git a/Server/HetsData/Mappings/EntityToDtoProfile.cs b/Server/HetsData/Mappings/EntityToDtoProfile.cs index 9de2546d1..348368849 100644 --- a/Server/HetsData/Mappings/EntityToDtoProfile.cs +++ b/Server/HetsData/Mappings/EntityToDtoProfile.cs @@ -1,5 +1,5 @@ using AutoMapper; -using HetsData.Model; +using HetsData.Entities; using HetsData.Dtos; namespace HetsData.Mappings diff --git a/Server/HetsData/Repositories/EquipmentRepository.cs b/Server/HetsData/Repositories/EquipmentRepository.cs index 6916fde4d..5ace1ff27 100644 --- a/Server/HetsData/Repositories/EquipmentRepository.cs +++ b/Server/HetsData/Repositories/EquipmentRepository.cs @@ -1,7 +1,7 @@ using AutoMapper; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; diff --git a/Server/HetsData/Repositories/OwnerRepository.cs b/Server/HetsData/Repositories/OwnerRepository.cs index 5c56db79e..3390e94cf 100644 --- a/Server/HetsData/Repositories/OwnerRepository.cs +++ b/Server/HetsData/Repositories/OwnerRepository.cs @@ -1,7 +1,7 @@ using AutoMapper; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; diff --git a/Server/HetsData/Repositories/ProjectRepository.cs b/Server/HetsData/Repositories/ProjectRepository.cs index 49a953845..374b0f09a 100644 --- a/Server/HetsData/Repositories/ProjectRepository.cs +++ b/Server/HetsData/Repositories/ProjectRepository.cs @@ -1,7 +1,7 @@ using AutoMapper; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using System; using System.Linq; diff --git a/Server/HetsData/Repositories/RentalAgreementRepository.cs b/Server/HetsData/Repositories/RentalAgreementRepository.cs index 7dc0c2651..136cbcf5e 100644 --- a/Server/HetsData/Repositories/RentalAgreementRepository.cs +++ b/Server/HetsData/Repositories/RentalAgreementRepository.cs @@ -1,7 +1,7 @@ using AutoMapper; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; diff --git a/Server/HetsData/Repositories/RentalRequestRepository.cs b/Server/HetsData/Repositories/RentalRequestRepository.cs index d247a1c4e..f33bf724e 100644 --- a/Server/HetsData/Repositories/RentalRequestRepository.cs +++ b/Server/HetsData/Repositories/RentalRequestRepository.cs @@ -1,7 +1,7 @@ using AutoMapper; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; diff --git a/Server/HetsData/Repositories/UserRepository.cs b/Server/HetsData/Repositories/UserRepository.cs index bf0ef322f..23b5db65a 100644 --- a/Server/HetsData/Repositories/UserRepository.cs +++ b/Server/HetsData/Repositories/UserRepository.cs @@ -1,6 +1,6 @@ using AutoMapper; using HetsData.Dtos; -using HetsData.Model; +using HetsData.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; diff --git a/Server/HetsData/Scaffold.txt b/Server/HetsData/Scaffold.txt index b28524e9e..785fe3754 100644 --- a/Server/HetsData/Scaffold.txt +++ b/Server/HetsData/Scaffold.txt @@ -1,7 +1,7 @@ ******************************************** Step 1: Generate / Update Model: ******************************************** -Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Model -Force -Project "HetsData" -Verbose -Context "DbAppContext" -Schema "public" +Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Entities -Force -Project "HetsData" -Verbose -Context "DbAppContext" -Schema "public" ******************************************** Step 2: Update Context diff --git a/Server/HetsReport/MailingLabel.cs b/Server/HetsReport/MailingLabel.cs index af0961988..a126f746b 100644 --- a/Server/HetsReport/MailingLabel.cs +++ b/Server/HetsReport/MailingLabel.cs @@ -5,7 +5,7 @@ using System.IO; using System.Reflection; using System.IO.Packaging; -using HetsData.Model; +using HetsData.Entities; using HetsReport.Helpers; namespace HetsReport diff --git a/Server/HetsReport/OwnerVerification.cs b/Server/HetsReport/OwnerVerification.cs index 435ce2982..5b43ec5e3 100644 --- a/Server/HetsReport/OwnerVerification.cs +++ b/Server/HetsReport/OwnerVerification.cs @@ -9,7 +9,7 @@ using DocumentFormat.OpenXml.Wordprocessing; using HetsData.Dtos; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using HetsReport.Helpers; namespace HetsReport diff --git a/Server/HetsReport/RentalAgreement.cs b/Server/HetsReport/RentalAgreement.cs index dd3a68ee3..c54013984 100644 --- a/Server/HetsReport/RentalAgreement.cs +++ b/Server/HetsReport/RentalAgreement.cs @@ -7,7 +7,7 @@ using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using HetsData.Helpers; -using HetsData.Model; +using HetsData.Entities; using HetsReport.Helpers; namespace HetsReport From c3dc8088db834a3152559be275e12d511025d42a Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Mon, 19 Jul 2021 14:04:55 -0700 Subject: [PATCH 131/352] Removed Model folder --- Server/HetsData/Model/DbAppContext.cs | 5552 ----------------- Server/HetsData/Model/HetBatchReport.cs | 33 - Server/HetsData/Model/HetBusiness.cs | 38 - Server/HetsData/Model/HetBusinessUser.cs | 41 - Server/HetsData/Model/HetBusinessUserRole.cs | 32 - Server/HetsData/Model/HetConditionType.cs | 31 - Server/HetsData/Model/HetContact.cs | 51 - Server/HetsData/Model/HetDigitalFile.cs | 40 - Server/HetsData/Model/HetDistrict.cs | 56 - .../Model/HetDistrictEquipmentType.cs | 43 - Server/HetsData/Model/HetDistrictStatus.cs | 37 - Server/HetsData/Model/HetEquipment.cs | 94 - .../HetsData/Model/HetEquipmentAttachment.cs | 30 - .../Model/HetEquipmentAttachmentHist.cs | 31 - Server/HetsData/Model/HetEquipmentHist.cs | 66 - .../HetsData/Model/HetEquipmentStatusType.cs | 37 - Server/HetsData/Model/HetEquipmentType.cs | 40 - Server/HetsData/Model/HetHistory.cs | 36 - Server/HetsData/Model/HetImportMap.cs | 29 - Server/HetsData/Model/HetLocalArea.cs | 46 - .../Model/HetLocalAreaRotationList.cs | 38 - Server/HetsData/Model/HetMimeType.cs | 37 - Server/HetsData/Model/HetNote.cs | 36 - Server/HetsData/Model/HetNoteHist.cs | 34 - Server/HetsData/Model/HetOwner.cs | 73 - Server/HetsData/Model/HetOwnerStatusType.cs | 37 - Server/HetsData/Model/HetPermission.cs | 35 - Server/HetsData/Model/HetPerson.cs | 30 - Server/HetsData/Model/HetProject.cs | 59 - Server/HetsData/Model/HetProjectStatusType.cs | 37 - .../HetsData/Model/HetProvincialRateType.cs | 34 - Server/HetsData/Model/HetRatePeriodType.cs | 39 - Server/HetsData/Model/HetRegion.cs | 37 - Server/HetsData/Model/HetRentalAgreement.cs | 60 - .../Model/HetRentalAgreementCondition.cs | 30 - .../Model/HetRentalAgreementConditionHist.cs | 31 - .../HetsData/Model/HetRentalAgreementHist.cs | 40 - .../HetsData/Model/HetRentalAgreementRate.cs | 43 - .../Model/HetRentalAgreementRateHist.cs | 37 - .../Model/HetRentalAgreementStatusType.cs | 37 - Server/HetsData/Model/HetRentalRequest.cs | 56 - .../Model/HetRentalRequestAttachment.cs | 29 - .../Model/HetRentalRequestRotationList.cs | 47 - .../Model/HetRentalRequestRotationListHist.cs | 40 - .../Model/HetRentalRequestStatusType.cs | 37 - Server/HetsData/Model/HetRole.cs | 38 - Server/HetsData/Model/HetRolePermission.cs | 30 - Server/HetsData/Model/HetRolloverProgress.cs | 15 - Server/HetsData/Model/HetSeniorityAudit.cs | 42 - Server/HetsData/Model/HetServiceArea.cs | 43 - Server/HetsData/Model/HetTimePeriodType.cs | 37 - Server/HetsData/Model/HetTimeRecord.cs | 35 - Server/HetsData/Model/HetTimeRecordHist.cs | 34 - Server/HetsData/Model/HetUser.cs | 47 - Server/HetsData/Model/HetUserDistrict.cs | 31 - Server/HetsData/Model/HetUserFavourite.cs | 34 - Server/HetsData/Model/HetUserRole.cs | 32 - 57 files changed, 7794 deletions(-) delete mode 100644 Server/HetsData/Model/DbAppContext.cs delete mode 100644 Server/HetsData/Model/HetBatchReport.cs delete mode 100644 Server/HetsData/Model/HetBusiness.cs delete mode 100644 Server/HetsData/Model/HetBusinessUser.cs delete mode 100644 Server/HetsData/Model/HetBusinessUserRole.cs delete mode 100644 Server/HetsData/Model/HetConditionType.cs delete mode 100644 Server/HetsData/Model/HetContact.cs delete mode 100644 Server/HetsData/Model/HetDigitalFile.cs delete mode 100644 Server/HetsData/Model/HetDistrict.cs delete mode 100644 Server/HetsData/Model/HetDistrictEquipmentType.cs delete mode 100644 Server/HetsData/Model/HetDistrictStatus.cs delete mode 100644 Server/HetsData/Model/HetEquipment.cs delete mode 100644 Server/HetsData/Model/HetEquipmentAttachment.cs delete mode 100644 Server/HetsData/Model/HetEquipmentAttachmentHist.cs delete mode 100644 Server/HetsData/Model/HetEquipmentHist.cs delete mode 100644 Server/HetsData/Model/HetEquipmentStatusType.cs delete mode 100644 Server/HetsData/Model/HetEquipmentType.cs delete mode 100644 Server/HetsData/Model/HetHistory.cs delete mode 100644 Server/HetsData/Model/HetImportMap.cs delete mode 100644 Server/HetsData/Model/HetLocalArea.cs delete mode 100644 Server/HetsData/Model/HetLocalAreaRotationList.cs delete mode 100644 Server/HetsData/Model/HetMimeType.cs delete mode 100644 Server/HetsData/Model/HetNote.cs delete mode 100644 Server/HetsData/Model/HetNoteHist.cs delete mode 100644 Server/HetsData/Model/HetOwner.cs delete mode 100644 Server/HetsData/Model/HetOwnerStatusType.cs delete mode 100644 Server/HetsData/Model/HetPermission.cs delete mode 100644 Server/HetsData/Model/HetPerson.cs delete mode 100644 Server/HetsData/Model/HetProject.cs delete mode 100644 Server/HetsData/Model/HetProjectStatusType.cs delete mode 100644 Server/HetsData/Model/HetProvincialRateType.cs delete mode 100644 Server/HetsData/Model/HetRatePeriodType.cs delete mode 100644 Server/HetsData/Model/HetRegion.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreement.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementCondition.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementConditionHist.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementHist.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementRate.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementRateHist.cs delete mode 100644 Server/HetsData/Model/HetRentalAgreementStatusType.cs delete mode 100644 Server/HetsData/Model/HetRentalRequest.cs delete mode 100644 Server/HetsData/Model/HetRentalRequestAttachment.cs delete mode 100644 Server/HetsData/Model/HetRentalRequestRotationList.cs delete mode 100644 Server/HetsData/Model/HetRentalRequestRotationListHist.cs delete mode 100644 Server/HetsData/Model/HetRentalRequestStatusType.cs delete mode 100644 Server/HetsData/Model/HetRole.cs delete mode 100644 Server/HetsData/Model/HetRolePermission.cs delete mode 100644 Server/HetsData/Model/HetRolloverProgress.cs delete mode 100644 Server/HetsData/Model/HetSeniorityAudit.cs delete mode 100644 Server/HetsData/Model/HetServiceArea.cs delete mode 100644 Server/HetsData/Model/HetTimePeriodType.cs delete mode 100644 Server/HetsData/Model/HetTimeRecord.cs delete mode 100644 Server/HetsData/Model/HetTimeRecordHist.cs delete mode 100644 Server/HetsData/Model/HetUser.cs delete mode 100644 Server/HetsData/Model/HetUserDistrict.cs delete mode 100644 Server/HetsData/Model/HetUserFavourite.cs delete mode 100644 Server/HetsData/Model/HetUserRole.cs diff --git a/Server/HetsData/Model/DbAppContext.cs b/Server/HetsData/Model/DbAppContext.cs deleted file mode 100644 index 4ffa43a95..000000000 --- a/Server/HetsData/Model/DbAppContext.cs +++ /dev/null @@ -1,5552 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; - -#nullable disable - -namespace HetsData.Model -{ - public partial class DbAppContext : DbContext - { - public DbAppContext() - { - } - - public DbAppContext(DbContextOptions options) - : base(options) - { - } - - public virtual DbSet HetBatchReports { get; set; } - public virtual DbSet HetBusinesses { get; set; } - public virtual DbSet HetBusinessUsers { get; set; } - public virtual DbSet HetBusinessUserRoles { get; set; } - public virtual DbSet HetConditionTypes { get; set; } - public virtual DbSet HetContacts { get; set; } - public virtual DbSet HetDigitalFiles { get; set; } - public virtual DbSet HetDistricts { get; set; } - public virtual DbSet HetDistrictEquipmentTypes { get; set; } - public virtual DbSet HetDistrictStatuses { get; set; } - public virtual DbSet HetEquipments { get; set; } - public virtual DbSet HetEquipmentAttachments { get; set; } - public virtual DbSet HetEquipmentAttachmentHists { get; set; } - public virtual DbSet HetEquipmentHists { get; set; } - public virtual DbSet HetEquipmentStatusTypes { get; set; } - public virtual DbSet HetEquipmentTypes { get; set; } - public virtual DbSet HetHistories { get; set; } - public virtual DbSet HetImportMaps { get; set; } - public virtual DbSet HetLocalAreas { get; set; } - public virtual DbSet HetLocalAreaRotationLists { get; set; } - public virtual DbSet HetMimeTypes { get; set; } - public virtual DbSet HetNotes { get; set; } - public virtual DbSet HetNoteHists { get; set; } - public virtual DbSet HetOwners { get; set; } - public virtual DbSet HetOwnerStatusTypes { get; set; } - public virtual DbSet HetPermissions { get; set; } - public virtual DbSet HetPeople { get; set; } - public virtual DbSet HetProjects { get; set; } - public virtual DbSet HetProjectStatusTypes { get; set; } - public virtual DbSet HetProvincialRateTypes { get; set; } - public virtual DbSet HetRatePeriodTypes { get; set; } - public virtual DbSet HetRegions { get; set; } - public virtual DbSet HetRentalAgreements { get; set; } - public virtual DbSet HetRentalAgreementConditions { get; set; } - public virtual DbSet HetRentalAgreementConditionHists { get; set; } - public virtual DbSet HetRentalAgreementHists { get; set; } - public virtual DbSet HetRentalAgreementRates { get; set; } - public virtual DbSet HetRentalAgreementRateHists { get; set; } - public virtual DbSet HetRentalAgreementStatusTypes { get; set; } - public virtual DbSet HetRentalRequests { get; set; } - public virtual DbSet HetRentalRequestAttachments { get; set; } - public virtual DbSet HetRentalRequestRotationLists { get; set; } - public virtual DbSet HetRentalRequestRotationListHists { get; set; } - public virtual DbSet HetRentalRequestStatusTypes { get; set; } - public virtual DbSet HetRoles { get; set; } - public virtual DbSet HetRolePermissions { get; set; } - public virtual DbSet HetRolloverProgresses { get; set; } - public virtual DbSet HetSeniorityAudits { get; set; } - public virtual DbSet HetServiceAreas { get; set; } - public virtual DbSet HetTimePeriodTypes { get; set; } - public virtual DbSet HetTimeRecords { get; set; } - public virtual DbSet HetTimeRecordHists { get; set; } - public virtual DbSet HetUsers { get; set; } - public virtual DbSet HetUserDistricts { get; set; } - public virtual DbSet HetUserFavourites { get; set; } - public virtual DbSet HetUserRoles { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.HasAnnotation("Relational:Collation", "en_US.utf8"); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ReportId); - - entity.ToTable("HET_BATCH_REPORT"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_BATCH_REPORT_DISTRICT_ID"); - - entity.Property(e => e.ReportId) - .HasColumnName("REPORT_ID") - .HasDefaultValueSql("nextval('\"HET_BATCH_REPORT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Complete).HasColumnName("COMPLETE"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.ReportLink) - .HasMaxLength(500) - .HasColumnName("REPORT_LINK"); - - entity.Property(e => e.ReportName) - .HasMaxLength(100) - .HasColumnName("REPORT_NAME"); - - entity.Property(e => e.StartDate).HasColumnName("START_DATE"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetBatchReports) - .HasForeignKey(d => d.DistrictId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_BATCH_REPORT_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.BusinessId); - - entity.ToTable("HET_BUSINESS"); - - entity.HasIndex(e => e.BceidBusinessGuid, "HET_BUSINESS_GUID_UK") - .IsUnique(); - - entity.HasIndex(e => e.BceidBusinessGuid, "IX_HET_BUSINESS_BUSINESS_GUID"); - - entity.Property(e => e.BusinessId) - .HasColumnName("BUSINESS_ID") - .HasDefaultValueSql("nextval('\"HET_BUSINESS_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BceidBusinessGuid) - .HasMaxLength(50) - .HasColumnName("BCEID_BUSINESS_GUID"); - - entity.Property(e => e.BceidBusinessNumber) - .HasMaxLength(50) - .HasColumnName("BCEID_BUSINESS_NUMBER"); - - entity.Property(e => e.BceidDoingBusinessAs) - .HasMaxLength(150) - .HasColumnName("BCEID_DOING_BUSINESS_AS"); - - entity.Property(e => e.BceidLegalName) - .HasMaxLength(150) - .HasColumnName("BCEID_LEGAL_NAME"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.BusinessUserId); - - entity.ToTable("HET_BUSINESS_USER"); - - entity.HasIndex(e => e.BusinessId, "IX_HET_BUSINESS_USER_BUSINESS_ID"); - - entity.HasIndex(e => e.BceidGuid, "IX_HET_BUSINESS_USER_GUID"); - - entity.Property(e => e.BusinessUserId) - .HasColumnName("BUSINESS_USER_ID") - .HasDefaultValueSql("nextval('\"HET_BUSINESS_USER_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BceidDisplayName) - .HasMaxLength(150) - .HasColumnName("BCEID_DISPLAY_NAME"); - - entity.Property(e => e.BceidEmail) - .HasMaxLength(150) - .HasColumnName("BCEID_EMAIL"); - - entity.Property(e => e.BceidFirstName) - .HasMaxLength(150) - .HasColumnName("BCEID_FIRST_NAME"); - - entity.Property(e => e.BceidGuid) - .HasMaxLength(50) - .HasColumnName("BCEID_GUID"); - - entity.Property(e => e.BceidLastName) - .HasMaxLength(150) - .HasColumnName("BCEID_LAST_NAME"); - - entity.Property(e => e.BceidTelephone) - .HasMaxLength(150) - .HasColumnName("BCEID_TELEPHONE"); - - entity.Property(e => e.BceidUserId) - .HasMaxLength(150) - .HasColumnName("BCEID_USER_ID"); - - entity.Property(e => e.BusinessId).HasColumnName("BUSINESS_ID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.HasOne(d => d.Business) - .WithMany(p => p.HetBusinessUsers) - .HasForeignKey(d => d.BusinessId) - .HasConstraintName("FK_HET_BUSINESS_USER_BUSINESS_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.BusinessUserRoleId) - .HasName("PK_PK_HET_BUSINESS_USER_ROLE"); - - entity.ToTable("HET_BUSINESS_USER_ROLE"); - - entity.HasIndex(e => e.RoleId, "IX_HET_BUSINESS_USER_ROLE_ROLE_ID"); - - entity.HasIndex(e => e.BusinessUserId, "IX_HET_BUSINESS_USER_ROLE_USER_ID"); - - entity.Property(e => e.BusinessUserRoleId) - .HasColumnName("BUSINESS_USER_ROLE_ID") - .HasDefaultValueSql("nextval('\"HET_BUSINESS_USER_ROLE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BusinessUserId).HasColumnName("BUSINESS_USER_ID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.ExpiryDate).HasColumnName("EXPIRY_DATE"); - - entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); - - entity.HasOne(d => d.BusinessUser) - .WithMany(p => p.HetBusinessUserRoles) - .HasForeignKey(d => d.BusinessUserId) - .HasConstraintName("FK_HET_BUSINESS_USER_ROLE_USER_ID"); - - entity.HasOne(d => d.Role) - .WithMany(p => p.HetBusinessUserRoles) - .HasForeignKey(d => d.RoleId) - .HasConstraintName("FK_HET_BUSINESS_USER_ROLE_ROLE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ConditionTypeId); - - entity.ToTable("HET_CONDITION_TYPE"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_CONDITION_TYPE_DISTRICT_ID"); - - entity.Property(e => e.ConditionTypeId) - .HasColumnName("CONDITION_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_CONDITION_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.Active).HasColumnName("ACTIVE"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.ConditionTypeCode) - .HasMaxLength(20) - .HasColumnName("CONDITION_TYPE_CODE"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetConditionTypes) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_CONDITION_TYPE_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ContactId); - - entity.ToTable("HET_CONTACT"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_CONTACT_OWNER_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_CONTACT_PROJECT_ID"); - - entity.Property(e => e.ContactId) - .HasColumnName("CONTACT_ID") - .HasDefaultValueSql("nextval('\"HET_CONTACT_ID_seq\"'::regclass)"); - - entity.Property(e => e.Address1) - .HasMaxLength(80) - .HasColumnName("ADDRESS1"); - - entity.Property(e => e.Address2) - .HasMaxLength(80) - .HasColumnName("ADDRESS2"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.City) - .HasMaxLength(100) - .HasColumnName("CITY"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EmailAddress) - .HasMaxLength(255) - .HasColumnName("EMAIL_ADDRESS"); - - entity.Property(e => e.FaxPhoneNumber) - .HasMaxLength(20) - .HasColumnName("FAX_PHONE_NUMBER"); - - entity.Property(e => e.GivenName) - .HasMaxLength(50) - .HasColumnName("GIVEN_NAME"); - - entity.Property(e => e.MobilePhoneNumber) - .HasMaxLength(20) - .HasColumnName("MOBILE_PHONE_NUMBER"); - - entity.Property(e => e.Notes) - .HasMaxLength(512) - .HasColumnName("NOTES"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.PostalCode) - .HasMaxLength(15) - .HasColumnName("POSTAL_CODE"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.Province) - .HasMaxLength(50) - .HasColumnName("PROVINCE"); - - entity.Property(e => e.Role) - .HasMaxLength(100) - .HasColumnName("ROLE"); - - entity.Property(e => e.Surname) - .HasMaxLength(50) - .HasColumnName("SURNAME"); - - entity.Property(e => e.WorkPhoneNumber) - .HasMaxLength(20) - .HasColumnName("WORK_PHONE_NUMBER"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetContacts) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_CONTACT_OWNER_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetContacts) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_CONTACT_PROJECT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.DigitalFileId); - - entity.ToTable("HET_DIGITAL_FILE"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_DIGITAL_FILE_EQUIPMENT_ID"); - - entity.HasIndex(e => e.MimeTypeId, "IX_HET_DIGITAL_FILE_MIME_TYPE_ID"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_DIGITAL_FILE_OWNER_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_DIGITAL_FILE_PROJECT_ID"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_DIGITAL_FILE_RENTAL_REQUEST_ID"); - - entity.Property(e => e.DigitalFileId) - .HasColumnName("DIGITAL_FILE_ID") - .HasDefaultValueSql("nextval('\"HET_DIGITAL_FILE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.FileContents).HasColumnName("FILE_CONTENTS"); - - entity.Property(e => e.FileName) - .HasMaxLength(2048) - .HasColumnName("FILE_NAME"); - - entity.Property(e => e.MimeTypeId).HasColumnName("MIME_TYPE_ID"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.Type) - .HasMaxLength(255) - .HasColumnName("TYPE"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetDigitalFiles) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_DIGITAL_FILE_EQUIPMENT_ID"); - - entity.HasOne(d => d.MimeType) - .WithMany(p => p.HetDigitalFiles) - .HasForeignKey(d => d.MimeTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_DIGITAL_FILE_MIME_TYPE_ID"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetDigitalFiles) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_DIGITAL_FILE_OWNER_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetDigitalFiles) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_DIGITAL_FILE_PROJECT_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetDigitalFiles) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_DIGITAL_FILE_RENTAL_REQUEST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.DistrictId); - - entity.ToTable("HET_DISTRICT"); - - entity.HasIndex(e => e.RegionId, "IX_HET_DISTRICT_REGION_ID"); - - entity.Property(e => e.DistrictId) - .HasColumnName("DISTRICT_ID") - .HasDefaultValueSql("nextval('\"HET_DISTRICT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictNumber).HasColumnName("DISTRICT_NUMBER"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.MinistryDistrictId).HasColumnName("MINISTRY_DISTRICT_ID"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.RegionId).HasColumnName("REGION_ID"); - - entity.Property(e => e.StartDate).HasColumnName("START_DATE"); - - entity.HasOne(d => d.Region) - .WithMany(p => p.HetDistricts) - .HasForeignKey(d => d.RegionId) - .HasConstraintName("FK_HET_DISTRICT_REGION_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.DistrictEquipmentTypeId); - - entity.ToTable("HET_DISTRICT_EQUIPMENT_TYPE"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); - - entity.HasIndex(e => e.EquipmentTypeId, "IX_HET_DISTRICT_EQUIPMENT_TYPE_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId) - .HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_DISTRICT_EQUIPMENT_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Deleted).HasColumnName("DELETED"); - - entity.Property(e => e.DistrictEquipmentName) - .HasMaxLength(255) - .HasColumnName("DISTRICT_EQUIPMENT_NAME"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.EquipmentTypeId).HasColumnName("EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.ServiceAreaId).HasColumnName("SERVICE_AREA_ID"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetDistrictEquipmentTypes) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); - - entity.HasOne(d => d.EquipmentType) - .WithMany(p => p.HetDistrictEquipmentTypes) - .HasForeignKey(d => d.EquipmentTypeId) - .HasConstraintName("FK_HET_DISTRICT_EQUIPMENT_TYPE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("HET_DISTRICT_STATUS"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_DISTRICT_STATUS_DISTRICT_ID"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.CurrentFiscalYear).HasColumnName("CURRENT_FISCAL_YEAR"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DisplayRolloverMessage).HasColumnName("DISPLAY_ROLLOVER_MESSAGE"); - - entity.Property(e => e.DistrictEquipmentTypeCompleteCount).HasColumnName("DISTRICT_EQUIPMENT_TYPE_COMPLETE_COUNT"); - - entity.Property(e => e.DistrictEquipmentTypeCount).HasColumnName("DISTRICT_EQUIPMENT_TYPE_COUNT"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.LocalAreaCompleteCount).HasColumnName("LOCAL_AREA_COMPLETE_COUNT"); - - entity.Property(e => e.LocalAreaCount).HasColumnName("LOCAL_AREA_COUNT"); - - entity.Property(e => e.NextFiscalYear).HasColumnName("NEXT_FISCAL_YEAR"); - - entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); - - entity.Property(e => e.RolloverEndDate).HasColumnName("ROLLOVER_END_DATE"); - - entity.Property(e => e.RolloverStartDate).HasColumnName("ROLLOVER_START_DATE"); - - entity.HasOne(d => d.District) - .WithMany() - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_DISTRICT_STATUS_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentId); - - entity.ToTable("HET_EQUIPMENT"); - - entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_EQUIPMENT_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_EQUIPMENT_LOCAL_AREA_ID"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_EQUIPMENT_OWNER_ID"); - - entity.HasIndex(e => e.EquipmentStatusTypeId, "IX_HET_EQUIPMENT_STATUS_TYPE_ID"); - - entity.Property(e => e.EquipmentId) - .HasColumnName("EQUIPMENT_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ApprovedDate).HasColumnName("APPROVED_DATE"); - - entity.Property(e => e.ArchiveCode) - .HasMaxLength(50) - .HasColumnName("ARCHIVE_CODE"); - - entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); - - entity.Property(e => e.ArchiveReason) - .HasMaxLength(2048) - .HasColumnName("ARCHIVE_REASON"); - - entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.EquipmentCode) - .HasMaxLength(25) - .HasColumnName("EQUIPMENT_CODE"); - - entity.Property(e => e.EquipmentStatusTypeId).HasColumnName("EQUIPMENT_STATUS_TYPE_ID"); - - entity.Property(e => e.InformationUpdateNeededReason) - .HasMaxLength(2048) - .HasColumnName("INFORMATION_UPDATE_NEEDED_REASON"); - - entity.Property(e => e.IsInformationUpdateNeeded).HasColumnName("IS_INFORMATION_UPDATE_NEEDED"); - - entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); - - entity.Property(e => e.LastVerifiedDate).HasColumnName("LAST_VERIFIED_DATE"); - - entity.Property(e => e.LegalCapacity) - .HasMaxLength(150) - .HasColumnName("LEGAL_CAPACITY"); - - entity.Property(e => e.LicencePlate) - .HasMaxLength(20) - .HasColumnName("LICENCE_PLATE"); - - entity.Property(e => e.LicencedGvw) - .HasMaxLength(150) - .HasColumnName("LICENCED_GVW"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.Property(e => e.Make) - .HasMaxLength(50) - .HasColumnName("MAKE"); - - entity.Property(e => e.Model) - .HasMaxLength(50) - .HasColumnName("MODEL"); - - entity.Property(e => e.NumberInBlock).HasColumnName("NUMBER_IN_BLOCK"); - - entity.Property(e => e.Operator) - .HasMaxLength(255) - .HasColumnName("OPERATOR"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.PayRate).HasColumnName("PAY_RATE"); - - entity.Property(e => e.PupLegalCapacity) - .HasMaxLength(150) - .HasColumnName("PUP_LEGAL_CAPACITY"); - - entity.Property(e => e.ReceivedDate).HasColumnName("RECEIVED_DATE"); - - entity.Property(e => e.RefuseRate) - .HasMaxLength(255) - .HasColumnName("REFUSE_RATE"); - - entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); - - entity.Property(e => e.SeniorityEffectiveDate).HasColumnName("SENIORITY_EFFECTIVE_DATE"); - - entity.Property(e => e.SeniorityOverrideReason) - .HasMaxLength(2048) - .HasColumnName("SENIORITY_OVERRIDE_REASON"); - - entity.Property(e => e.SerialNumber) - .HasMaxLength(100) - .HasColumnName("SERIAL_NUMBER"); - - entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); - - entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); - - entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); - - entity.Property(e => e.Size) - .HasMaxLength(128) - .HasColumnName("SIZE"); - - entity.Property(e => e.StatusComment) - .HasMaxLength(255) - .HasColumnName("STATUS_COMMENT"); - - entity.Property(e => e.ToDate).HasColumnName("TO_DATE"); - - entity.Property(e => e.Type) - .HasMaxLength(50) - .HasColumnName("TYPE"); - - entity.Property(e => e.Year) - .HasMaxLength(15) - .HasColumnName("YEAR"); - - entity.Property(e => e.YearsOfService).HasColumnName("YEARS_OF_SERVICE"); - - entity.HasOne(d => d.DistrictEquipmentType) - .WithMany(p => p.HetEquipments) - .HasForeignKey(d => d.DistrictEquipmentTypeId) - .HasConstraintName("FK_HET_EQUIPMENT_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasOne(d => d.EquipmentStatusType) - .WithMany(p => p.HetEquipments) - .HasForeignKey(d => d.EquipmentStatusTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_EQUIPMENT_STATUS_TYPE_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetEquipments) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_EQUIPMENT_LOCAL_AREA_ID"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetEquipments) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_EQUIPMENT_OWNER_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentAttachmentId); - - entity.ToTable("HET_EQUIPMENT_ATTACHMENT"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_EQUIPMENT_ATTACHMENT_EQUIPMENT_ID"); - - entity.Property(e => e.EquipmentAttachmentId) - .HasColumnName("EQUIPMENT_ATTACHMENT_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ATTACHMENT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.TypeName) - .HasMaxLength(100) - .HasColumnName("TYPE_NAME"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetEquipmentAttachments) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_EQUIPMENT_ATTACHMENT_EQUIPMENT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentAttachmentHistId) - .HasName("HET_EQUIPMENT_ATTACHMENT_HIST_PK"); - - entity.ToTable("HET_EQUIPMENT_ATTACHMENT_HIST"); - - entity.Property(e => e.EquipmentAttachmentHistId) - .HasColumnName("EQUIPMENT_ATTACHMENT_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_ATTACHMENT_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentAttachmentId).HasColumnName("EQUIPMENT_ATTACHMENT_ID"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.TypeName) - .HasMaxLength(100) - .HasColumnName("TYPE_NAME"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentHistId) - .HasName("HET_EQUIPMENT_HIST_PK"); - - entity.ToTable("HET_EQUIPMENT_HIST"); - - entity.Property(e => e.EquipmentHistId) - .HasColumnName("EQUIPMENT_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ApprovedDate).HasColumnName("APPROVED_DATE"); - - entity.Property(e => e.ArchiveCode) - .HasMaxLength(50) - .HasColumnName("ARCHIVE_CODE"); - - entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); - - entity.Property(e => e.ArchiveReason) - .HasMaxLength(2048) - .HasColumnName("ARCHIVE_REASON"); - - entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentCode) - .HasMaxLength(25) - .HasColumnName("EQUIPMENT_CODE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.EquipmentStatusTypeId).HasColumnName("EQUIPMENT_STATUS_TYPE_ID"); - - entity.Property(e => e.InformationUpdateNeededReason) - .HasMaxLength(2048) - .HasColumnName("INFORMATION_UPDATE_NEEDED_REASON"); - - entity.Property(e => e.IsInformationUpdateNeeded).HasColumnName("IS_INFORMATION_UPDATE_NEEDED"); - - entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); - - entity.Property(e => e.LastVerifiedDate).HasColumnName("LAST_VERIFIED_DATE"); - - entity.Property(e => e.LegalCapacity) - .HasMaxLength(150) - .HasColumnName("LEGAL_CAPACITY"); - - entity.Property(e => e.LicencePlate) - .HasMaxLength(20) - .HasColumnName("LICENCE_PLATE"); - - entity.Property(e => e.LicencedGvw) - .HasMaxLength(150) - .HasColumnName("LICENCED_GVW"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.Property(e => e.Make) - .HasMaxLength(50) - .HasColumnName("MAKE"); - - entity.Property(e => e.Model) - .HasMaxLength(50) - .HasColumnName("MODEL"); - - entity.Property(e => e.NumberInBlock).HasColumnName("NUMBER_IN_BLOCK"); - - entity.Property(e => e.Operator) - .HasMaxLength(255) - .HasColumnName("OPERATOR"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.PayRate).HasColumnName("PAY_RATE"); - - entity.Property(e => e.PupLegalCapacity) - .HasMaxLength(150) - .HasColumnName("PUP_LEGAL_CAPACITY"); - - entity.Property(e => e.ReceivedDate).HasColumnName("RECEIVED_DATE"); - - entity.Property(e => e.RefuseRate) - .HasMaxLength(255) - .HasColumnName("REFUSE_RATE"); - - entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); - - entity.Property(e => e.SeniorityEffectiveDate).HasColumnName("SENIORITY_EFFECTIVE_DATE"); - - entity.Property(e => e.SeniorityOverrideReason) - .HasMaxLength(2048) - .HasColumnName("SENIORITY_OVERRIDE_REASON"); - - entity.Property(e => e.SerialNumber) - .HasMaxLength(100) - .HasColumnName("SERIAL_NUMBER"); - - entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); - - entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); - - entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); - - entity.Property(e => e.Size) - .HasMaxLength(128) - .HasColumnName("SIZE"); - - entity.Property(e => e.StatusComment) - .HasMaxLength(255) - .HasColumnName("STATUS_COMMENT"); - - entity.Property(e => e.ToDate).HasColumnName("TO_DATE"); - - entity.Property(e => e.Type) - .HasMaxLength(50) - .HasColumnName("TYPE"); - - entity.Property(e => e.Year) - .HasMaxLength(15) - .HasColumnName("YEAR"); - - entity.Property(e => e.YearsOfService).HasColumnName("YEARS_OF_SERVICE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentStatusTypeId); - - entity.ToTable("HET_EQUIPMENT_STATUS_TYPE"); - - entity.HasIndex(e => e.EquipmentStatusTypeCode, "UK_HET_EQUIPMENT_STATUS_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.EquipmentStatusTypeId) - .HasColumnName("EQUIPMENT_STATUS_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_STATUS_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.EquipmentStatusTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("EQUIPMENT_STATUS_TYPE_CODE"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.EquipmentTypeId); - - entity.ToTable("HET_EQUIPMENT_TYPE"); - - entity.Property(e => e.EquipmentTypeId) - .HasColumnName("EQUIPMENT_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_EQUIPMENT_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BlueBookRateNumber).HasColumnName("BLUE_BOOK_RATE_NUMBER"); - - entity.Property(e => e.BlueBookSection).HasColumnName("BLUE_BOOK_SECTION"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.ExtendHours).HasColumnName("EXTEND_HOURS"); - - entity.Property(e => e.IsDumpTruck).HasColumnName("IS_DUMP_TRUCK"); - - entity.Property(e => e.MaxHoursSub).HasColumnName("MAX_HOURS_SUB"); - - entity.Property(e => e.MaximumHours).HasColumnName("MAXIMUM_HOURS"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.NumberOfBlocks).HasColumnName("NUMBER_OF_BLOCKS"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.HistoryId); - - entity.ToTable("HET_HISTORY"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_HISTORY_EQUIPMENT_ID"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_HISTORY_OWNER_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_HISTORY_PROJECT_ID"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_HISTORY_RENTAL_REQUEST_ID"); - - entity.Property(e => e.HistoryId) - .HasColumnName("HISTORY_ID") - .HasDefaultValueSql("nextval('\"HET_HISTORY_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.CreatedDate).HasColumnName("CREATED_DATE"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.HistoryText) - .HasMaxLength(2048) - .HasColumnName("HISTORY_TEXT"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetHistories) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_HISTORY_EQUIPMENT_ID"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetHistories) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_HISTORY_OWNER_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetHistories) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_HISTORY_PROJECT_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetHistories) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_HISTORY_RENTAL_REQUEST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ImportMapId); - - entity.ToTable("HET_IMPORT_MAP"); - - entity.Property(e => e.ImportMapId) - .HasColumnName("IMPORT_MAP_ID") - .HasDefaultValueSql("nextval('\"HET_IMPORT_MAP_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.NewKey).HasColumnName("NEW_KEY"); - - entity.Property(e => e.NewTable).HasColumnName("NEW_TABLE"); - - entity.Property(e => e.OldKey) - .HasMaxLength(250) - .HasColumnName("OLD_KEY"); - - entity.Property(e => e.OldTable).HasColumnName("OLD_TABLE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.LocalAreaId); - - entity.ToTable("HET_LOCAL_AREA"); - - entity.HasIndex(e => e.LocalAreaNumber, "HET_LOCAL_AREA_NUMBER_UK") - .IsUnique(); - - entity.HasIndex(e => e.ServiceAreaId, "IX_HET_LOCAL_AREA_SERVICE_AREA_ID"); - - entity.Property(e => e.LocalAreaId) - .HasColumnName("LOCAL_AREA_ID") - .HasDefaultValueSql("nextval('\"HET_LOCAL_AREA_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.LocalAreaNumber).HasColumnName("LOCAL_AREA_NUMBER"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.ServiceAreaId).HasColumnName("SERVICE_AREA_ID"); - - entity.Property(e => e.StartDate) - .HasColumnName("START_DATE") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.HasOne(d => d.ServiceArea) - .WithMany(p => p.HetLocalAreas) - .HasForeignKey(d => d.ServiceAreaId) - .HasConstraintName("FK_HET_LOCAL_AREA_SERVICE_AREA_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.LocalAreaRotationListId); - - entity.ToTable("HET_LOCAL_AREA_ROTATION_LIST"); - - entity.HasIndex(e => e.AskNextBlock1Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); - - entity.HasIndex(e => e.AskNextBlock2Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); - - entity.HasIndex(e => e.AskNextBlockOpenId, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); - - entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); - - entity.Property(e => e.LocalAreaRotationListId) - .HasColumnName("LOCAL_AREA_ROTATION_LIST_ID") - .HasDefaultValueSql("nextval('\"HET_LOCAL_AREA_ROTATION_LIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.AskNextBlock1Id).HasColumnName("ASK_NEXT_BLOCK1_ID"); - - entity.Property(e => e.AskNextBlock1Seniority).HasColumnName("ASK_NEXT_BLOCK1_SENIORITY"); - - entity.Property(e => e.AskNextBlock2Id).HasColumnName("ASK_NEXT_BLOCK2_ID"); - - entity.Property(e => e.AskNextBlock2Seniority).HasColumnName("ASK_NEXT_BLOCK2_SENIORITY"); - - entity.Property(e => e.AskNextBlockOpenId).HasColumnName("ASK_NEXT_BLOCK_OPEN_ID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.HasOne(d => d.AskNextBlock1) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlock1s) - .HasForeignKey(d => d.AskNextBlock1Id) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); - - entity.HasOne(d => d.AskNextBlock2) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlock2s) - .HasForeignKey(d => d.AskNextBlock2Id) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); - - entity.HasOne(d => d.AskNextBlockOpen) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlockOpens) - .HasForeignKey(d => d.AskNextBlockOpenId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); - - entity.HasOne(d => d.DistrictEquipmentType) - .WithMany(p => p.HetLocalAreaRotationLists) - .HasForeignKey(d => d.DistrictEquipmentTypeId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetLocalAreaRotationLists) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.MimeTypeId); - - entity.ToTable("HET_MIME_TYPE"); - - entity.HasIndex(e => e.MimeTypeCode, "UK_HET_MIME_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.MimeTypeId) - .HasColumnName("MIME_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_MIME_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.MimeTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("MIME_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.NoteId); - - entity.ToTable("HET_NOTE"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_NOTE_EQUIPMENT_ID"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_NOTE_OWNER_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_NOTE_PROJECT_ID"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_NOTE_RENTAL_REQUEST_ID"); - - entity.Property(e => e.NoteId) - .HasColumnName("NOTE_ID") - .HasDefaultValueSql("nextval('\"HET_NOTE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.IsNoLongerRelevant).HasColumnName("IS_NO_LONGER_RELEVANT"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.Text) - .HasMaxLength(2048) - .HasColumnName("TEXT"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetNotes) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_NOTE_EQUIPMENT_ID"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetNotes) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_NOTE_OWNER_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetNotes) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_NOTE_PROJECT_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetNotes) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_NOTE_RENTAL_REQUEST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.NoteHistId) - .HasName("HET_NOTE_HIST_PK"); - - entity.ToTable("HET_NOTE_HIST"); - - entity.Property(e => e.NoteHistId) - .HasColumnName("NOTE_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_NOTE_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.IsNoLongerRelevant).HasColumnName("IS_NO_LONGER_RELEVANT"); - - entity.Property(e => e.NoteId).HasColumnName("NOTE_ID"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.Text) - .HasMaxLength(2048) - .HasColumnName("TEXT"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.OwnerId); - - entity.ToTable("HET_OWNER"); - - entity.HasIndex(e => e.BusinessId, "IX_HET_OWNER_BUSINESS_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_OWNER_LOCAL_AREA_ID"); - - entity.HasIndex(e => e.PrimaryContactId, "IX_HET_OWNER_PRIMARY_CONTACT_ID"); - - entity.HasIndex(e => e.OwnerStatusTypeId, "IX_HET_OWNER_STATUS_TYPE_ID"); - - entity.Property(e => e.OwnerId) - .HasColumnName("OWNER_ID") - .HasDefaultValueSql("nextval('\"HET_OWNER_ID_seq\"'::regclass)"); - - entity.Property(e => e.Address1) - .HasMaxLength(80) - .HasColumnName("ADDRESS1"); - - entity.Property(e => e.Address2) - .HasMaxLength(80) - .HasColumnName("ADDRESS2"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ArchiveCode) - .HasMaxLength(50) - .HasColumnName("ARCHIVE_CODE"); - - entity.Property(e => e.ArchiveDate).HasColumnName("ARCHIVE_DATE"); - - entity.Property(e => e.ArchiveReason) - .HasMaxLength(2048) - .HasColumnName("ARCHIVE_REASON"); - - entity.Property(e => e.BusinessId).HasColumnName("BUSINESS_ID"); - - entity.Property(e => e.CglCompany) - .HasMaxLength(255) - .HasColumnName("CGL_COMPANY"); - - entity.Property(e => e.CglPolicyNumber) - .HasMaxLength(50) - .HasColumnName("CGL_POLICY_NUMBER"); - - entity.Property(e => e.CglendDate).HasColumnName("CGLEND_DATE"); - - entity.Property(e => e.City) - .HasMaxLength(100) - .HasColumnName("CITY"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DoingBusinessAs) - .HasMaxLength(150) - .HasColumnName("DOING_BUSINESS_AS"); - - entity.Property(e => e.GivenName) - .HasMaxLength(50) - .HasColumnName("GIVEN_NAME"); - - entity.Property(e => e.IsMaintenanceContractor).HasColumnName("IS_MAINTENANCE_CONTRACTOR"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.Property(e => e.MeetsResidency).HasColumnName("MEETS_RESIDENCY"); - - entity.Property(e => e.OrganizationName) - .HasMaxLength(150) - .HasColumnName("ORGANIZATION_NAME"); - - entity.Property(e => e.OwnerCode) - .HasMaxLength(20) - .HasColumnName("OWNER_CODE"); - - entity.Property(e => e.OwnerStatusTypeId).HasColumnName("OWNER_STATUS_TYPE_ID"); - - entity.Property(e => e.PostalCode) - .HasMaxLength(15) - .HasColumnName("POSTAL_CODE"); - - entity.Property(e => e.PrimaryContactId).HasColumnName("PRIMARY_CONTACT_ID"); - - entity.Property(e => e.Province) - .HasMaxLength(50) - .HasColumnName("PROVINCE"); - - entity.Property(e => e.RegisteredCompanyNumber) - .HasMaxLength(150) - .HasColumnName("REGISTERED_COMPANY_NUMBER"); - - entity.Property(e => e.SharedKey) - .HasMaxLength(50) - .HasColumnName("SHARED_KEY"); - - entity.Property(e => e.StatusComment) - .HasMaxLength(255) - .HasColumnName("STATUS_COMMENT"); - - entity.Property(e => e.Surname) - .HasMaxLength(50) - .HasColumnName("SURNAME"); - - entity.Property(e => e.WorkSafeBcexpiryDate).HasColumnName("WORK_SAFE_BCEXPIRY_DATE"); - - entity.Property(e => e.WorkSafeBcpolicyNumber) - .HasMaxLength(50) - .HasColumnName("WORK_SAFE_BCPOLICY_NUMBER"); - - entity.HasOne(d => d.Business) - .WithMany(p => p.HetOwners) - .HasForeignKey(d => d.BusinessId) - .HasConstraintName("FK_HET_OWNER_BUSINESS_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetOwners) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_OWNER_LOCAL_AREA_ID"); - - entity.HasOne(d => d.OwnerStatusType) - .WithMany(p => p.HetOwners) - .HasForeignKey(d => d.OwnerStatusTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_OWNER_STATUS_TYPE_ID"); - - entity.HasOne(d => d.PrimaryContact) - .WithMany(p => p.HetOwners) - .HasForeignKey(d => d.PrimaryContactId) - .HasConstraintName("FK_HET_OWNER_PRIMARY_CONTACT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.OwnerStatusTypeId); - - entity.ToTable("HET_OWNER_STATUS_TYPE"); - - entity.HasIndex(e => e.OwnerStatusTypeCode, "UK_HET_OWNER_STATUS_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.OwnerStatusTypeId) - .HasColumnName("OWNER_STATUS_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_OWNER_STATUS_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.OwnerStatusTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("OWNER_STATUS_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.PermissionId); - - entity.ToTable("HET_PERMISSION"); - - entity.HasIndex(e => e.Code, "HET_PRM_CODE_UK") - .IsUnique(); - - entity.HasIndex(e => e.Name, "HET_PRM_NAME_UK") - .IsUnique(); - - entity.Property(e => e.PermissionId) - .HasColumnName("PERMISSION_ID") - .HasDefaultValueSql("nextval('\"HET_PERMISSION_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Code) - .HasMaxLength(50) - .HasColumnName("CODE"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.PersonId); - - entity.ToTable("HET_PERSON"); - - entity.Property(e => e.PersonId) - .HasColumnName("PERSON_ID") - .HasDefaultValueSql("nextval('\"HET_PERSON_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.FirstName) - .HasMaxLength(50) - .HasColumnName("FIRST_NAME"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.MiddleNames) - .HasMaxLength(200) - .HasColumnName("MIDDLE_NAMES"); - - entity.Property(e => e.NameSuffix) - .HasMaxLength(50) - .HasColumnName("NAME_SUFFIX"); - - entity.Property(e => e.Surname) - .IsRequired() - .HasMaxLength(50) - .HasColumnName("SURNAME"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ProjectId); - - entity.ToTable("HET_PROJECT"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_PROJECT_DISTRICT_ID"); - - entity.HasIndex(e => e.PrimaryContactId, "IX_HET_PROJECT_PRIMARY_CONTACT_ID"); - - entity.HasIndex(e => e.ProjectStatusTypeId, "IX_HET_PROJECT_STATUS_TYPE_ID"); - - entity.Property(e => e.ProjectId) - .HasColumnName("PROJECT_ID") - .HasDefaultValueSql("nextval('\"HET_PROJECT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BusinessFunction) - .HasMaxLength(255) - .HasColumnName("BUSINESS_FUNCTION"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.CostType) - .HasMaxLength(255) - .HasColumnName("COST_TYPE"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.FiscalYear) - .IsRequired() - .HasMaxLength(10) - .HasColumnName("FISCAL_YEAR") - .HasDefaultValueSql("'2018/2019'::character varying"); - - entity.Property(e => e.Information) - .HasMaxLength(2048) - .HasColumnName("INFORMATION"); - - entity.Property(e => e.Name) - .HasMaxLength(100) - .HasColumnName("NAME"); - - entity.Property(e => e.PrimaryContactId).HasColumnName("PRIMARY_CONTACT_ID"); - - entity.Property(e => e.Product) - .HasMaxLength(255) - .HasColumnName("PRODUCT"); - - entity.Property(e => e.ProjectStatusTypeId).HasColumnName("PROJECT_STATUS_TYPE_ID"); - - entity.Property(e => e.ProvincialProjectNumber) - .HasMaxLength(150) - .HasColumnName("PROVINCIAL_PROJECT_NUMBER"); - - entity.Property(e => e.ResponsibilityCentre) - .HasMaxLength(255) - .HasColumnName("RESPONSIBILITY_CENTRE"); - - entity.Property(e => e.ServiceLine) - .HasMaxLength(255) - .HasColumnName("SERVICE_LINE"); - - entity.Property(e => e.Stob) - .HasMaxLength(255) - .HasColumnName("STOB"); - - entity.Property(e => e.WorkActivity) - .HasMaxLength(255) - .HasColumnName("WORK_ACTIVITY"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetProjects) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_PROJECT_DISTRICT_ID"); - - entity.HasOne(d => d.PrimaryContact) - .WithMany(p => p.HetProjects) - .HasForeignKey(d => d.PrimaryContactId) - .HasConstraintName("FK_HET_PROJECT_PRIMARY_CONTACT_ID"); - - entity.HasOne(d => d.ProjectStatusType) - .WithMany(p => p.HetProjects) - .HasForeignKey(d => d.ProjectStatusTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_PROJECT_HET_PROJECT_STATUS_TYPE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ProjectStatusTypeId); - - entity.ToTable("HET_PROJECT_STATUS_TYPE"); - - entity.HasIndex(e => e.ProjectStatusTypeCode, "UK_HET_PROJECT_STATUS_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.ProjectStatusTypeId) - .HasColumnName("PROJECT_STATUS_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_PROJECT_STATUS_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.ProjectStatusTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("PROJECT_STATUS_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RateType); - - entity.ToTable("HET_PROVINCIAL_RATE_TYPE"); - - entity.Property(e => e.RateType) - .HasMaxLength(20) - .HasColumnName("RATE_TYPE"); - - entity.Property(e => e.Active).HasColumnName("ACTIVE"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(200) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.IsInTotalEditable).HasColumnName("IS_IN_TOTAL_EDITABLE"); - - entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); - - entity.Property(e => e.IsPercentRate).HasColumnName("IS_PERCENT_RATE"); - - entity.Property(e => e.IsRateEditable).HasColumnName("IS_RATE_EDITABLE"); - - entity.Property(e => e.Overtime).HasColumnName("OVERTIME"); - - entity.Property(e => e.PeriodType) - .HasMaxLength(20) - .HasColumnName("PERIOD_TYPE"); - - entity.Property(e => e.Rate).HasColumnName("RATE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RatePeriodTypeId); - - entity.ToTable("HET_RATE_PERIOD_TYPE"); - - entity.HasIndex(e => e.RatePeriodTypeCode, "UK_HET_RATE_PERIOD_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.RatePeriodTypeId) - .HasColumnName("RATE_PERIOD_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_RATE_PERIOD_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.RatePeriodTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("RATE_PERIOD_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RegionId); - - entity.ToTable("HET_REGION"); - - entity.Property(e => e.RegionId) - .HasColumnName("REGION_ID") - .HasDefaultValueSql("nextval('\"HET_REGION_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.MinistryRegionId).HasColumnName("MINISTRY_REGION_ID"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.RegionNumber).HasColumnName("REGION_NUMBER"); - - entity.Property(e => e.StartDate).HasColumnName("START_DATE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementId); - - entity.ToTable("HET_RENTAL_AGREEMENT"); - - entity.HasIndex(e => e.Number, "HET_RNTAG_NUMBER_UK") - .IsUnique(); - - entity.HasIndex(e => e.DistrictId, "IX_HET_RENTAL_AGREEMENT_DISTRICT_ID"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_RENTAL_AGREEMENT_EQUIPMENT_ID"); - - entity.HasIndex(e => e.RatePeriodTypeId, "IX_HET_RENTAL_AGREEMENT_HET_RATE_PERIOD_TYPE_ID"); - - entity.HasIndex(e => e.RentalAgreementStatusTypeId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_AGREEMENT_STATUS_TYPE_ID"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_REQUEST_ID"); - - entity.HasIndex(e => e.RentalRequestRotationListId, "IX_HET_RENTAL_AGREEMENT_HET_RENTAL_REQUEST_ROTATION_LIST_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_RENTAL_AGREEMENT_PROJECT_ID"); - - entity.Property(e => e.RentalAgreementId) - .HasColumnName("RENTAL_AGREEMENT_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AgreementCity) - .HasMaxLength(255) - .HasColumnName("AGREEMENT_CITY"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DatedOn).HasColumnName("DATED_ON"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.EquipmentRate).HasColumnName("EQUIPMENT_RATE"); - - entity.Property(e => e.EstimateHours).HasColumnName("ESTIMATE_HOURS"); - - entity.Property(e => e.EstimateStartWork).HasColumnName("ESTIMATE_START_WORK"); - - entity.Property(e => e.Note) - .HasMaxLength(2048) - .HasColumnName("NOTE"); - - entity.Property(e => e.Number) - .HasMaxLength(30) - .HasColumnName("NUMBER"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RateComment) - .HasMaxLength(2048) - .HasColumnName("RATE_COMMENT"); - - entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); - - entity.Property(e => e.RentalAgreementStatusTypeId).HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.RentalRequestRotationListId).HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_DISTRICT_ID"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_EQUIPMENT_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_PROJECT_ID"); - - entity.HasOne(d => d.RatePeriodType) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.RatePeriodTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_PERIOD_TYPE_ID"); - - entity.HasOne(d => d.RentalAgreementStatusType) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.RentalAgreementStatusTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_STATUS_TYPE_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RENTAL_REQUEST_ID"); - - entity.HasOne(d => d.RentalRequestRotationList) - .WithMany(p => p.HetRentalAgreements) - .HasForeignKey(d => d.RentalRequestRotationListId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RENTAL_REQUEST_ROTATION_LIST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementConditionId); - - entity.ToTable("HET_RENTAL_AGREEMENT_CONDITION"); - - entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_AGREEMENT_CONDITION_RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementConditionId) - .HasColumnName("RENTAL_AGREEMENT_CONDITION_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_CONDITION_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Comment) - .HasMaxLength(2048) - .HasColumnName("COMMENT"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.ConditionName) - .HasMaxLength(150) - .HasColumnName("CONDITION_NAME"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.HasOne(d => d.RentalAgreement) - .WithMany(p => p.HetRentalAgreementConditions) - .HasForeignKey(d => d.RentalAgreementId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_CONDITION_RENTAL_AGREEMENT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementConditionHistId) - .HasName("HET_RENTAL_AGREEMENT_CONDITION_HIST_PK"); - - entity.ToTable("HET_RENTAL_AGREEMENT_CONDITION_HIST"); - - entity.Property(e => e.RentalAgreementConditionHistId) - .HasColumnName("RENTAL_AGREEMENT_CONDITION_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_CONDITION_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Comment) - .HasMaxLength(2048) - .HasColumnName("COMMENT"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.ConditionName) - .HasMaxLength(150) - .HasColumnName("CONDITION_NAME"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.RentalAgreementConditionId).HasColumnName("RENTAL_AGREEMENT_CONDITION_ID"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementHistId) - .HasName("HET_RENTAL_AGREEMENT_HIST_PK"); - - entity.ToTable("HET_RENTAL_AGREEMENT_HIST"); - - entity.Property(e => e.RentalAgreementHistId) - .HasColumnName("RENTAL_AGREEMENT_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AgreementCity) - .HasMaxLength(255) - .HasColumnName("AGREEMENT_CITY"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DatedOn).HasColumnName("DATED_ON"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.EquipmentRate).HasColumnName("EQUIPMENT_RATE"); - - entity.Property(e => e.EstimateHours).HasColumnName("ESTIMATE_HOURS"); - - entity.Property(e => e.EstimateStartWork).HasColumnName("ESTIMATE_START_WORK"); - - entity.Property(e => e.Note) - .HasMaxLength(2048) - .HasColumnName("NOTE"); - - entity.Property(e => e.Number) - .HasMaxLength(30) - .HasColumnName("NUMBER"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RateComment) - .HasMaxLength(2048) - .HasColumnName("RATE_COMMENT"); - - entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementStatusTypeId).HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementRateId); - - entity.ToTable("HET_RENTAL_AGREEMENT_RATE"); - - entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_AGREEMENT_RATE_RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementRateId) - .HasColumnName("RENTAL_AGREEMENT_RATE_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_RATE_ID_seq\"'::regclass)"); - - entity.Property(e => e.Active) - .HasColumnName("ACTIVE") - .HasDefaultValueSql("false"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Comment) - .HasMaxLength(2048) - .HasColumnName("COMMENT"); - - entity.Property(e => e.ComponentName) - .HasMaxLength(150) - .HasColumnName("COMPONENT_NAME"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); - - entity.Property(e => e.Overtime) - .HasColumnName("OVERTIME") - .HasDefaultValueSql("false"); - - entity.Property(e => e.Rate).HasColumnName("RATE"); - - entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.Set) - .HasColumnName("SET") - .HasDefaultValueSql("false"); - - entity.HasOne(d => d.RatePeriodType) - .WithMany(p => p.HetRentalAgreementRates) - .HasForeignKey(d => d.RatePeriodTypeId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_PERIOD_TYPE_ID"); - - entity.HasOne(d => d.RentalAgreement) - .WithMany(p => p.HetRentalAgreementRates) - .HasForeignKey(d => d.RentalAgreementId) - .HasConstraintName("FK_HET_RENTAL_AGREEMENT_RATE_AGREEMENT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementRateHistId) - .HasName("HET_RENTAL_AGREEMENT_RATE_HIST_PK"); - - entity.ToTable("HET_RENTAL_AGREEMENT_RATE_HIST"); - - entity.Property(e => e.RentalAgreementRateHistId) - .HasColumnName("RENTAL_AGREEMENT_RATE_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_RATE_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.Active) - .HasColumnName("ACTIVE") - .HasDefaultValueSql("false"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Comment) - .HasMaxLength(2048) - .HasColumnName("COMMENT"); - - entity.Property(e => e.ComponentName) - .HasMaxLength(150) - .HasColumnName("COMPONENT_NAME"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.IsIncludedInTotal).HasColumnName("IS_INCLUDED_IN_TOTAL"); - - entity.Property(e => e.Overtime) - .HasColumnName("OVERTIME") - .HasDefaultValueSql("false"); - - entity.Property(e => e.Rate).HasColumnName("RATE"); - - entity.Property(e => e.RatePeriodTypeId).HasColumnName("RATE_PERIOD_TYPE_ID"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); - - entity.Property(e => e.Set).HasColumnName("SET"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalAgreementStatusTypeId); - - entity.ToTable("HET_RENTAL_AGREEMENT_STATUS_TYPE"); - - entity.HasIndex(e => e.RentalAgreementStatusTypeCode, "UK_HET_RENTAL_AGREEMENT_STATUS_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.RentalAgreementStatusTypeId) - .HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_AGREEMENT_STATUS_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.RentalAgreementStatusTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("RENTAL_AGREEMENT_STATUS_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalRequestId); - - entity.ToTable("HET_RENTAL_REQUEST"); - - entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_RENTAL_REQUEST_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasIndex(e => e.FirstOnRotationListId, "IX_HET_RENTAL_REQUEST_FIRST_ON_ROTATION_LIST_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_RENTAL_REQUEST_LOCAL_AREA_ID"); - - entity.HasIndex(e => e.ProjectId, "IX_HET_RENTAL_REQUEST_PROJECT_ID"); - - entity.HasIndex(e => e.RentalRequestStatusTypeId, "IX_HET_RENTAL_REQUEST_STATUS_TYPE_ID"); - - entity.Property(e => e.RentalRequestId) - .HasColumnName("RENTAL_REQUEST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.EquipmentCount).HasColumnName("EQUIPMENT_COUNT"); - - entity.Property(e => e.ExpectedEndDate).HasColumnName("EXPECTED_END_DATE"); - - entity.Property(e => e.ExpectedHours).HasColumnName("EXPECTED_HOURS"); - - entity.Property(e => e.ExpectedStartDate).HasColumnName("EXPECTED_START_DATE"); - - entity.Property(e => e.FirstOnRotationListId).HasColumnName("FIRST_ON_ROTATION_LIST_ID"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.Property(e => e.ProjectId).HasColumnName("PROJECT_ID"); - - entity.Property(e => e.RentalRequestStatusTypeId).HasColumnName("RENTAL_REQUEST_STATUS_TYPE_ID"); - - entity.HasOne(d => d.DistrictEquipmentType) - .WithMany(p => p.HetRentalRequests) - .HasForeignKey(d => d.DistrictEquipmentTypeId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_DISTRICT_EQUIPMENT_TYPE_DISTRICT_ID"); - - entity.HasOne(d => d.FirstOnRotationList) - .WithMany(p => p.HetRentalRequests) - .HasForeignKey(d => d.FirstOnRotationListId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_FIRST_ON_ROTATION_LIST_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetRentalRequests) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_LOCAL_AREA_ID"); - - entity.HasOne(d => d.Project) - .WithMany(p => p.HetRentalRequests) - .HasForeignKey(d => d.ProjectId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_PROJECT_ID"); - - entity.HasOne(d => d.RentalRequestStatusType) - .WithMany(p => p.HetRentalRequests) - .HasForeignKey(d => d.RentalRequestStatusTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_RENTAL_REQUEST_STATUS_TYPE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalRequestAttachmentId); - - entity.ToTable("HET_RENTAL_REQUEST_ATTACHMENT"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_REQUEST_ATTACHMENT_RENTAL_REQUEST_ID"); - - entity.Property(e => e.RentalRequestAttachmentId) - .HasColumnName("RENTAL_REQUEST_ATTACHMENT_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ATTACHMENT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.Attachment) - .HasMaxLength(150) - .HasColumnName("ATTACHMENT"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetRentalRequestAttachments) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_ATTACHMENT_RENTAL_REQUEST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalRequestRotationListId); - - entity.ToTable("HET_RENTAL_REQUEST_ROTATION_LIST"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_EQUIPMENT_ID"); - - entity.HasIndex(e => e.RentalAgreementId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_AGREEMENT_ID"); - - entity.HasIndex(e => e.RentalRequestId, "IX_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_REQUEST_ID"); - - entity.Property(e => e.RentalRequestRotationListId) - .HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ROTATION_LIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.AskedDateTime).HasColumnName("ASKED_DATE_TIME"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.IsForceHire).HasColumnName("IS_FORCE_HIRE"); - - entity.Property(e => e.Note) - .HasMaxLength(2048) - .HasColumnName("NOTE"); - - entity.Property(e => e.OfferRefusalReason) - .HasMaxLength(50) - .HasColumnName("OFFER_REFUSAL_REASON"); - - entity.Property(e => e.OfferResponse).HasColumnName("OFFER_RESPONSE"); - - entity.Property(e => e.OfferResponseDatetime).HasColumnName("OFFER_RESPONSE_DATETIME"); - - entity.Property(e => e.OfferResponseNote) - .HasMaxLength(2048) - .HasColumnName("OFFER_RESPONSE_NOTE"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.RotationListSortOrder).HasColumnName("ROTATION_LIST_SORT_ORDER"); - - entity.Property(e => e.WasAsked).HasColumnName("WAS_ASKED"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetRentalRequestRotationLists) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_EQUIPMENT_ID"); - - entity.HasOne(d => d.RentalAgreement) - .WithMany(p => p.HetRentalRequestRotationLists) - .HasForeignKey(d => d.RentalAgreementId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_AGREEMENT_ID"); - - entity.HasOne(d => d.RentalRequest) - .WithMany(p => p.HetRentalRequestRotationLists) - .HasForeignKey(d => d.RentalRequestId) - .HasConstraintName("FK_HET_RENTAL_REQUEST_ROTATION_LIST_RENTAL_REQUEST_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalRequestRotationListHistId) - .HasName("HET_RENTAL_REQUEST_ROTATION_LIST_HIST_PK"); - - entity.ToTable("HET_RENTAL_REQUEST_ROTATION_LIST_HIST"); - - entity.Property(e => e.RentalRequestRotationListHistId) - .HasColumnName("RENTAL_REQUEST_ROTATION_LIST_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_ROTATION_LIST_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.AskedDateTime).HasColumnName("ASKED_DATE_TIME"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.IsForceHire).HasColumnName("IS_FORCE_HIRE"); - - entity.Property(e => e.Note) - .HasMaxLength(2048) - .HasColumnName("NOTE"); - - entity.Property(e => e.OfferRefusalReason) - .HasMaxLength(50) - .HasColumnName("OFFER_REFUSAL_REASON"); - - entity.Property(e => e.OfferResponse).HasColumnName("OFFER_RESPONSE"); - - entity.Property(e => e.OfferResponseDatetime).HasColumnName("OFFER_RESPONSE_DATETIME"); - - entity.Property(e => e.OfferResponseNote) - .HasMaxLength(2048) - .HasColumnName("OFFER_RESPONSE_NOTE"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalRequestId).HasColumnName("RENTAL_REQUEST_ID"); - - entity.Property(e => e.RentalRequestRotationListId).HasColumnName("RENTAL_REQUEST_ROTATION_LIST_ID"); - - entity.Property(e => e.RotationListSortOrder).HasColumnName("ROTATION_LIST_SORT_ORDER"); - - entity.Property(e => e.WasAsked).HasColumnName("WAS_ASKED"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RentalRequestStatusTypeId); - - entity.ToTable("HET_RENTAL_REQUEST_STATUS_TYPE"); - - entity.HasIndex(e => e.RentalRequestStatusTypeCode, "UK_HET_RENTAL_REQUEST_STATUS_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.RentalRequestStatusTypeId) - .HasColumnName("RENTAL_REQUEST_STATUS_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_RENTAL_REQUEST_STATUS_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.RentalRequestStatusTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("RENTAL_REQUEST_STATUS_TYPE_CODE"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RoleId); - - entity.ToTable("HET_ROLE"); - - entity.HasIndex(e => e.Name, "HET_ROLE_NAME_UK") - .IsUnique(); - - entity.Property(e => e.RoleId) - .HasColumnName("ROLE_ID") - .HasDefaultValueSql("nextval('\"HET_ROLE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.Name) - .HasMaxLength(255) - .HasColumnName("NAME"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.RolePermissionId); - - entity.ToTable("HET_ROLE_PERMISSION"); - - entity.HasIndex(e => e.PermissionId, "IX_HET_ROLE_PERMISSION_PERMISSION_ID"); - - entity.HasIndex(e => e.RoleId, "IX_HET_ROLE_PERMISSION_ROLE_ID"); - - entity.Property(e => e.RolePermissionId) - .HasColumnName("ROLE_PERMISSION_ID") - .HasDefaultValueSql("nextval('\"HET_ROLE_PERMISSION_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.PermissionId).HasColumnName("PERMISSION_ID"); - - entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); - - entity.HasOne(d => d.Permission) - .WithMany(p => p.HetRolePermissions) - .HasForeignKey(d => d.PermissionId) - .HasConstraintName("FK_HET_ROLE_PERMISSION_PERMISSION_ID"); - - entity.HasOne(d => d.Role) - .WithMany(p => p.HetRolePermissions) - .HasForeignKey(d => d.RoleId) - .HasConstraintName("FK_HET_ROLE_PERMISSION_ROLE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.DistrictId); - - entity.ToTable("HET_ROLLOVER_PROGRESS"); - - entity.Property(e => e.DistrictId) - .ValueGeneratedNever() - .HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.ProgressPercentage).HasColumnName("PROGRESS_PERCENTAGE"); - - entity.HasOne(d => d.District) - .WithOne(p => p.HetRolloverProgress) - .HasForeignKey(d => d.DistrictId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.SeniorityAuditId); - - entity.ToTable("HET_SENIORITY_AUDIT"); - - entity.HasIndex(e => e.EquipmentId, "IX_HET_SENIORITY_AUDIT_EQUIPMENT_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_SENIORITY_AUDIT_LOCAL_AREA_ID"); - - entity.HasIndex(e => e.OwnerId, "IX_HET_SENIORITY_AUDIT_OWNER_ID"); - - entity.Property(e => e.SeniorityAuditId) - .HasColumnName("SENIORITY_AUDIT_ID") - .HasDefaultValueSql("nextval('\"HET_SENIORITY_AUDIT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.BlockNumber).HasColumnName("BLOCK_NUMBER"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EquipmentId).HasColumnName("EQUIPMENT_ID"); - - entity.Property(e => e.IsSeniorityOverridden).HasColumnName("IS_SENIORITY_OVERRIDDEN"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.Property(e => e.OwnerId).HasColumnName("OWNER_ID"); - - entity.Property(e => e.OwnerOrganizationName) - .HasMaxLength(150) - .HasColumnName("OWNER_ORGANIZATION_NAME"); - - entity.Property(e => e.Seniority).HasColumnName("SENIORITY"); - - entity.Property(e => e.SeniorityOverrideReason) - .HasMaxLength(2048) - .HasColumnName("SENIORITY_OVERRIDE_REASON"); - - entity.Property(e => e.ServiceHoursLastYear).HasColumnName("SERVICE_HOURS_LAST_YEAR"); - - entity.Property(e => e.ServiceHoursThreeYearsAgo).HasColumnName("SERVICE_HOURS_THREE_YEARS_AGO"); - - entity.Property(e => e.ServiceHoursTwoYearsAgo).HasColumnName("SERVICE_HOURS_TWO_YEARS_AGO"); - - entity.Property(e => e.StartDate).HasColumnName("START_DATE"); - - entity.HasOne(d => d.Equipment) - .WithMany(p => p.HetSeniorityAudits) - .HasForeignKey(d => d.EquipmentId) - .HasConstraintName("FK_HET_SENIORITY_AUDIT_EQUIPMENT_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetSeniorityAudits) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_SENIORITY_AUDIT_LOCAL_AREA_ID"); - - entity.HasOne(d => d.Owner) - .WithMany(p => p.HetSeniorityAudits) - .HasForeignKey(d => d.OwnerId) - .HasConstraintName("FK_HET_SENIORITY_AUDIT_OWNER_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ServiceAreaId); - - entity.ToTable("HET_SERVICE_AREA"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_SERVICE_AREA_DISTRICT_ID"); - - entity.Property(e => e.ServiceAreaId) - .HasColumnName("SERVICE_AREA_ID") - .HasDefaultValueSql("nextval('\"HET_SERVICE_AREA_ID_seq\"'::regclass)"); - - entity.Property(e => e.Address) - .HasMaxLength(255) - .HasColumnName("ADDRESS"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.AreaNumber).HasColumnName("AREA_NUMBER"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.Fax) - .HasMaxLength(50) - .HasColumnName("FAX"); - - entity.Property(e => e.FiscalEndDate).HasColumnName("FISCAL_END_DATE"); - - entity.Property(e => e.FiscalStartDate).HasColumnName("FISCAL_START_DATE"); - - entity.Property(e => e.MinistryServiceAreaId).HasColumnName("MINISTRY_SERVICE_AREA_ID"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.Phone) - .HasMaxLength(50) - .HasColumnName("PHONE"); - - entity.Property(e => e.SupportingDocuments) - .HasMaxLength(500) - .HasColumnName("SUPPORTING_DOCUMENTS"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetServiceAreas) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_SERVICE_AREA_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.TimePeriodTypeId); - - entity.ToTable("HET_TIME_PERIOD_TYPE"); - - entity.HasIndex(e => e.TimePeriodTypeCode, "UK_HET_TIME_PERIOD_TYPE_CODE") - .IsUnique(); - - entity.Property(e => e.TimePeriodTypeId) - .HasColumnName("TIME_PERIOD_TYPE_ID") - .HasDefaultValueSql("nextval('\"HET_TIME_PERIOD_TYPE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.Description) - .IsRequired() - .HasMaxLength(2048) - .HasColumnName("DESCRIPTION"); - - entity.Property(e => e.DisplayOrder).HasColumnName("DISPLAY_ORDER"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.ScreenLabel) - .HasMaxLength(200) - .HasColumnName("SCREEN_LABEL"); - - entity.Property(e => e.TimePeriodTypeCode) - .IsRequired() - .HasMaxLength(20) - .HasColumnName("TIME_PERIOD_TYPE_CODE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.TimeRecordId); - - entity.ToTable("HET_TIME_RECORD"); - - entity.HasIndex(e => e.RentalAgreementId, "IX_HET_TIME_RECORD_RENTAL_AGREEMENT_ID"); - - entity.HasIndex(e => e.RentalAgreementRateId, "IX_HET_TIME_RECORD_RENTAL_AGREEMENT_RATE_ID"); - - entity.HasIndex(e => e.TimePeriodTypeId, "IX_HET_TIME_RECORD_TIME_PERIOD_TYPE_ID"); - - entity.Property(e => e.TimeRecordId) - .HasColumnName("TIME_RECORD_ID") - .HasDefaultValueSql("nextval('\"HET_TIME_RECORD_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EnteredDate).HasColumnName("ENTERED_DATE"); - - entity.Property(e => e.Hours).HasColumnName("HOURS"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); - - entity.Property(e => e.TimePeriodTypeId).HasColumnName("TIME_PERIOD_TYPE_ID"); - - entity.Property(e => e.WorkedDate).HasColumnName("WORKED_DATE"); - - entity.HasOne(d => d.RentalAgreement) - .WithMany(p => p.HetTimeRecords) - .HasForeignKey(d => d.RentalAgreementId) - .HasConstraintName("FK_HET_TIME_RECORD_RENTAL_AGREEMENT_ID"); - - entity.HasOne(d => d.RentalAgreementRate) - .WithMany(p => p.HetTimeRecords) - .HasForeignKey(d => d.RentalAgreementRateId) - .HasConstraintName("FK_HET_TIME_RECORD_RENTAL_AGREEMENT_RATE_ID"); - - entity.HasOne(d => d.TimePeriodType) - .WithMany(p => p.HetTimeRecords) - .HasForeignKey(d => d.TimePeriodTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_HET_TIME_RECORD_TIME_PERIOD_TYPE_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.TimeRecordHistId) - .HasName("HET_TIME_RECORD_HIST_PK"); - - entity.ToTable("HET_TIME_RECORD_HIST"); - - entity.Property(e => e.TimeRecordHistId) - .HasColumnName("TIME_RECORD_HIST_ID") - .HasDefaultValueSql("nextval('\"HET_TIME_RECORD_HIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.EndDate).HasColumnName("END_DATE"); - - entity.Property(e => e.EnteredDate).HasColumnName("ENTERED_DATE"); - - entity.Property(e => e.Hours).HasColumnName("HOURS"); - - entity.Property(e => e.RentalAgreementId).HasColumnName("RENTAL_AGREEMENT_ID"); - - entity.Property(e => e.RentalAgreementRateId).HasColumnName("RENTAL_AGREEMENT_RATE_ID"); - - entity.Property(e => e.TimePeriodTypeId).HasColumnName("TIME_PERIOD_TYPE_ID"); - - entity.Property(e => e.TimeRecordId).HasColumnName("TIME_RECORD_ID"); - - entity.Property(e => e.WorkedDate).HasColumnName("WORKED_DATE"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.UserId); - - entity.ToTable("HET_USER"); - - entity.HasIndex(e => e.Guid, "HET_USR_GUID_UK") - .IsUnique(); - - entity.HasIndex(e => e.DistrictId, "IX_HET_USER_DISTRICT_ID"); - - entity.Property(e => e.UserId) - .HasColumnName("USER_ID") - .HasDefaultValueSql("nextval('\"HET_USER_ID_seq\"'::regclass)"); - - entity.Property(e => e.Active).HasColumnName("ACTIVE"); - - entity.Property(e => e.AgreementCity) - .HasMaxLength(255) - .HasColumnName("AGREEMENT_CITY"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.Email) - .HasMaxLength(255) - .HasColumnName("EMAIL"); - - entity.Property(e => e.GivenName) - .HasMaxLength(50) - .HasColumnName("GIVEN_NAME"); - - entity.Property(e => e.Guid) - .HasMaxLength(255) - .HasColumnName("GUID"); - - entity.Property(e => e.Initials) - .HasMaxLength(10) - .HasColumnName("INITIALS"); - - entity.Property(e => e.SmAuthorizationDirectory) - .HasMaxLength(255) - .HasColumnName("SM_AUTHORIZATION_DIRECTORY"); - - entity.Property(e => e.SmUserId) - .HasMaxLength(255) - .HasColumnName("SM_USER_ID"); - - entity.Property(e => e.Surname) - .HasMaxLength(50) - .HasColumnName("SURNAME"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetUsers) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_USER_DISTRICT_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.UserDistrictId); - - entity.ToTable("HET_USER_DISTRICT"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_USER_DISTRICT_DISTRICT_ID"); - - entity.HasIndex(e => e.UserId, "IX_HET_USER_DISTRICT_USER_ID"); - - entity.Property(e => e.UserDistrictId) - .HasColumnName("USER_DISTRICT_ID") - .HasDefaultValueSql("nextval('\"HET_USER_DISTRICT_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.IsPrimary).HasColumnName("IS_PRIMARY"); - - entity.Property(e => e.UserId).HasColumnName("USER_ID"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetUserDistricts) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_USER_DISTRICT_DISTRICT_ID"); - - entity.HasOne(d => d.User) - .WithMany(p => p.HetUserDistricts) - .HasForeignKey(d => d.UserId) - .HasConstraintName("FK_HET_USER_DISTRICT_USER_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.UserFavouriteId); - - entity.ToTable("HET_USER_FAVOURITE"); - - entity.HasIndex(e => e.DistrictId, "IX_HET_USER_FAVOURITE_DISTRICT_ID"); - - entity.HasIndex(e => e.UserId, "IX_HET_USER_FAVOURITE_USER_ID"); - - entity.Property(e => e.UserFavouriteId) - .HasColumnName("USER_FAVOURITE_ID") - .HasDefaultValueSql("nextval('\"HET_USER_FAVOURITE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictId).HasColumnName("DISTRICT_ID"); - - entity.Property(e => e.IsDefault).HasColumnName("IS_DEFAULT"); - - entity.Property(e => e.Name) - .HasMaxLength(150) - .HasColumnName("NAME"); - - entity.Property(e => e.Type) - .HasMaxLength(150) - .HasColumnName("TYPE"); - - entity.Property(e => e.UserId).HasColumnName("USER_ID"); - - entity.Property(e => e.Value) - .HasMaxLength(2048) - .HasColumnName("VALUE"); - - entity.HasOne(d => d.District) - .WithMany(p => p.HetUserFavourites) - .HasForeignKey(d => d.DistrictId) - .HasConstraintName("FK_HET_USER_FAVOURITE_DISTRICT_ID"); - - entity.HasOne(d => d.User) - .WithMany(p => p.HetUserFavourites) - .HasForeignKey(d => d.UserId) - .HasConstraintName("FK_HET_USER_FAVOURITE_USER_ID"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.UserRoleId); - - entity.ToTable("HET_USER_ROLE"); - - entity.HasIndex(e => e.RoleId, "IX_HET_USER_ROLE_ROLE_ID"); - - entity.HasIndex(e => e.UserId, "IX_HET_USER_ROLE_USER_ID"); - - entity.Property(e => e.UserRoleId) - .HasColumnName("USER_ROLE_ID") - .HasDefaultValueSql("nextval('\"HET_USER_ROLE_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.EffectiveDate).HasColumnName("EFFECTIVE_DATE"); - - entity.Property(e => e.ExpiryDate).HasColumnName("EXPIRY_DATE"); - - entity.Property(e => e.RoleId).HasColumnName("ROLE_ID"); - - entity.Property(e => e.UserId).HasColumnName("USER_ID"); - - entity.HasOne(d => d.Role) - .WithMany(p => p.HetUserRoles) - .HasForeignKey(d => d.RoleId) - .HasConstraintName("FK_HET_USER_ROLE_ROLE_ID"); - - entity.HasOne(d => d.User) - .WithMany(p => p.HetUserRoles) - .HasForeignKey(d => d.UserId) - .HasConstraintName("FK_HET_USER_ROLE_USER_ID"); - }); - - modelBuilder.HasSequence("counter_id_seq"); - - modelBuilder.HasSequence("hash_id_seq"); - - modelBuilder.HasSequence("HET_BATCH_REPORT_ID_seq"); - - modelBuilder.HasSequence("HET_BUSINESS_ID_seq"); - - modelBuilder.HasSequence("HET_BUSINESS_USER_ID_seq"); - - modelBuilder.HasSequence("HET_BUSINESS_USER_ROLE_ID_seq"); - - modelBuilder.HasSequence("HET_CONDITION_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_CONTACT_ID_seq"); - - modelBuilder.HasSequence("HET_DIGITAL_FILE_ID_seq"); - - modelBuilder.HasSequence("HET_DISTRICT_EQUIPMENT_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_DISTRICT_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_ATTACHMENT_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_ATTACHMENT_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_STATUS_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_EQUIPMENT_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_HISTORY_ID_seq"); - - modelBuilder.HasSequence("HET_IMPORT_MAP_ID_seq"); - - modelBuilder.HasSequence("HET_LOCAL_AREA_ID_seq"); - - modelBuilder.HasSequence("HET_LOCAL_AREA_ROTATION_LIST_ID_seq"); - - modelBuilder.HasSequence("HET_MIME_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_NOTE_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_NOTE_ID_seq"); - - modelBuilder.HasSequence("HET_OWNER_ID_seq"); - - modelBuilder.HasSequence("HET_OWNER_STATUS_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_PERMISSION_ID_seq"); - - modelBuilder.HasSequence("HET_PERSON_ID_seq"); - - modelBuilder.HasSequence("HET_PROJECT_ID_seq"); - - modelBuilder.HasSequence("HET_PROJECT_STATUS_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_RATE_PERIOD_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_REGION_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_CONDITION_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_CONDITION_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_RATE_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_RATE_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_AGREEMENT_STATUS_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_REQUEST_ATTACHMENT_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_REQUEST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_REQUEST_ROTATION_LIST_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_REQUEST_ROTATION_LIST_ID_seq"); - - modelBuilder.HasSequence("HET_RENTAL_REQUEST_STATUS_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_ROLE_ID_seq"); - - modelBuilder.HasSequence("HET_ROLE_PERMISSION_ID_seq"); - - modelBuilder.HasSequence("HET_SENIORITY_AUDIT_ID_seq"); - - modelBuilder.HasSequence("HET_SERVICE_AREA_ID_seq"); - - modelBuilder.HasSequence("HET_TIME_PERIOD_TYPE_ID_seq"); - - modelBuilder.HasSequence("HET_TIME_RECORD_HIST_ID_seq"); - - modelBuilder.HasSequence("HET_TIME_RECORD_ID_seq"); - - modelBuilder.HasSequence("HET_USER_DISTRICT_ID_seq"); - - modelBuilder.HasSequence("HET_USER_FAVOURITE_ID_seq"); - - modelBuilder.HasSequence("HET_USER_ID_seq"); - - modelBuilder.HasSequence("HET_USER_ROLE_ID_seq"); - - modelBuilder.HasSequence("job_id_seq"); - - modelBuilder.HasSequence("jobparameter_id_seq"); - - modelBuilder.HasSequence("jobqueue_id_seq"); - - modelBuilder.HasSequence("list_id_seq"); - - modelBuilder.HasSequence("set_id_seq"); - - modelBuilder.HasSequence("state_id_seq"); - - OnModelCreatingPartial(modelBuilder); - } - - partial void OnModelCreatingPartial(ModelBuilder modelBuilder); - } -} diff --git a/Server/HetsData/Model/HetBatchReport.cs b/Server/HetsData/Model/HetBatchReport.cs deleted file mode 100644 index a1b0d5458..000000000 --- a/Server/HetsData/Model/HetBatchReport.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetBatchReport - { - public int ReportId { get; set; } - public string ReportName { get; set; } - public string ReportLink { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public bool? Complete { get; set; } - public int DistrictId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - } -} diff --git a/Server/HetsData/Model/HetBusiness.cs b/Server/HetsData/Model/HetBusiness.cs deleted file mode 100644 index 3fd803a2b..000000000 --- a/Server/HetsData/Model/HetBusiness.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetBusiness - { - public HetBusiness() - { - HetBusinessUsers = new HashSet(); - HetOwners = new HashSet(); - } - - public int BusinessId { get; set; } - public string BceidLegalName { get; set; } - public string BceidDoingBusinessAs { get; set; } - public string BceidBusinessNumber { get; set; } - public string BceidBusinessGuid { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetBusinessUsers { get; set; } - public virtual ICollection HetOwners { get; set; } - } -} diff --git a/Server/HetsData/Model/HetBusinessUser.cs b/Server/HetsData/Model/HetBusinessUser.cs deleted file mode 100644 index 37c9181ab..000000000 --- a/Server/HetsData/Model/HetBusinessUser.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetBusinessUser - { - public HetBusinessUser() - { - HetBusinessUserRoles = new HashSet(); - } - - public int BusinessUserId { get; set; } - public string BceidUserId { get; set; } - public string BceidGuid { get; set; } - public string BceidDisplayName { get; set; } - public string BceidFirstName { get; set; } - public string BceidLastName { get; set; } - public string BceidEmail { get; set; } - public string BceidTelephone { get; set; } - public int? BusinessId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetBusiness Business { get; set; } - public virtual ICollection HetBusinessUserRoles { get; set; } - } -} diff --git a/Server/HetsData/Model/HetBusinessUserRole.cs b/Server/HetsData/Model/HetBusinessUserRole.cs deleted file mode 100644 index 543ccbb72..000000000 --- a/Server/HetsData/Model/HetBusinessUserRole.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetBusinessUserRole - { - public int BusinessUserRoleId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? ExpiryDate { get; set; } - public int? BusinessUserId { get; set; } - public int? RoleId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetBusinessUser BusinessUser { get; set; } - public virtual HetRole Role { get; set; } - } -} diff --git a/Server/HetsData/Model/HetConditionType.cs b/Server/HetsData/Model/HetConditionType.cs deleted file mode 100644 index e4c44a74c..000000000 --- a/Server/HetsData/Model/HetConditionType.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetConditionType - { - public int ConditionTypeId { get; set; } - public int? DistrictId { get; set; } - public string ConditionTypeCode { get; set; } - public string Description { get; set; } - public bool Active { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - } -} diff --git a/Server/HetsData/Model/HetContact.cs b/Server/HetsData/Model/HetContact.cs deleted file mode 100644 index d4f40c8a8..000000000 --- a/Server/HetsData/Model/HetContact.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetContact - { - public HetContact() - { - HetOwners = new HashSet(); - HetProjects = new HashSet(); - } - - public int ContactId { get; set; } - public string Surname { get; set; } - public string GivenName { get; set; } - public string Role { get; set; } - public string Notes { get; set; } - public string EmailAddress { get; set; } - public string MobilePhoneNumber { get; set; } - public string WorkPhoneNumber { get; set; } - public string FaxPhoneNumber { get; set; } - public string Address1 { get; set; } - public string Address2 { get; set; } - public string City { get; set; } - public string PostalCode { get; set; } - public string Province { get; set; } - public int? OwnerId { get; set; } - public int? ProjectId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetOwner Owner { get; set; } - public virtual HetProject Project { get; set; } - public virtual ICollection HetOwners { get; set; } - public virtual ICollection HetProjects { get; set; } - } -} diff --git a/Server/HetsData/Model/HetDigitalFile.cs b/Server/HetsData/Model/HetDigitalFile.cs deleted file mode 100644 index f4513c60f..000000000 --- a/Server/HetsData/Model/HetDigitalFile.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetDigitalFile - { - public int DigitalFileId { get; set; } - public string Description { get; set; } - public string FileName { get; set; } - public string Type { get; set; } - public int MimeTypeId { get; set; } - public byte[] FileContents { get; set; } - public int? EquipmentId { get; set; } - public int? OwnerId { get; set; } - public int? ProjectId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - public virtual HetMimeType MimeType { get; set; } - public virtual HetOwner Owner { get; set; } - public virtual HetProject Project { get; set; } - public virtual HetRentalRequest RentalRequest { get; set; } - } -} diff --git a/Server/HetsData/Model/HetDistrict.cs b/Server/HetsData/Model/HetDistrict.cs deleted file mode 100644 index 55c5ead8a..000000000 --- a/Server/HetsData/Model/HetDistrict.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetDistrict - { - public HetDistrict() - { - HetBatchReports = new HashSet(); - HetConditionTypes = new HashSet(); - HetDistrictEquipmentTypes = new HashSet(); - HetProjects = new HashSet(); - HetRentalAgreements = new HashSet(); - HetServiceAreas = new HashSet(); - HetUserDistricts = new HashSet(); - HetUserFavourites = new HashSet(); - HetUsers = new HashSet(); - } - - public int DistrictId { get; set; } - public int? DistrictNumber { get; set; } - public string Name { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public int MinistryDistrictId { get; set; } - public int? RegionId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetRegion Region { get; set; } - public virtual HetRolloverProgress HetRolloverProgress { get; set; } - public virtual ICollection HetBatchReports { get; set; } - public virtual ICollection HetConditionTypes { get; set; } - public virtual ICollection HetDistrictEquipmentTypes { get; set; } - public virtual ICollection HetProjects { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - public virtual ICollection HetServiceAreas { get; set; } - public virtual ICollection HetUserDistricts { get; set; } - public virtual ICollection HetUserFavourites { get; set; } - public virtual ICollection HetUsers { get; set; } - } -} diff --git a/Server/HetsData/Model/HetDistrictEquipmentType.cs b/Server/HetsData/Model/HetDistrictEquipmentType.cs deleted file mode 100644 index 9c0d3018e..000000000 --- a/Server/HetsData/Model/HetDistrictEquipmentType.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetDistrictEquipmentType - { - public HetDistrictEquipmentType() - { - HetEquipments = new HashSet(); - HetLocalAreaRotationLists = new HashSet(); - HetRentalRequests = new HashSet(); - } - - public int DistrictEquipmentTypeId { get; set; } - public string DistrictEquipmentName { get; set; } - public int? DistrictId { get; set; } - public int? EquipmentTypeId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public bool Deleted { get; set; } - public int? ServiceAreaId { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual HetEquipmentType EquipmentType { get; set; } - public virtual ICollection HetEquipments { get; set; } - public virtual ICollection HetLocalAreaRotationLists { get; set; } - public virtual ICollection HetRentalRequests { get; set; } - } -} diff --git a/Server/HetsData/Model/HetDistrictStatus.cs b/Server/HetsData/Model/HetDistrictStatus.cs deleted file mode 100644 index 05d89ab9b..000000000 --- a/Server/HetsData/Model/HetDistrictStatus.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetDistrictStatus - { - public int? DistrictId { get; set; } - public int? CurrentFiscalYear { get; set; } - public int? NextFiscalYear { get; set; } - public DateTime? RolloverStartDate { get; set; } - public DateTime? RolloverEndDate { get; set; } - public int? LocalAreaCount { get; set; } - public int? DistrictEquipmentTypeCount { get; set; } - public int? LocalAreaCompleteCount { get; set; } - public int? DistrictEquipmentTypeCompleteCount { get; set; } - public int? ProgressPercentage { get; set; } - public bool DisplayRolloverMessage { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipment.cs b/Server/HetsData/Model/HetEquipment.cs deleted file mode 100644 index 951d2735a..000000000 --- a/Server/HetsData/Model/HetEquipment.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipment - { - public HetEquipment() - { - HetDigitalFiles = new HashSet(); - HetEquipmentAttachments = new HashSet(); - HetHistories = new HashSet(); - HetLocalAreaRotationListAskNextBlock1s = new HashSet(); - HetLocalAreaRotationListAskNextBlock2s = new HashSet(); - HetLocalAreaRotationListAskNextBlockOpens = new HashSet(); - HetNotes = new HashSet(); - HetRentalAgreements = new HashSet(); - HetRentalRequestRotationLists = new HashSet(); - HetRentalRequests = new HashSet(); - HetSeniorityAudits = new HashSet(); - } - - public int EquipmentId { get; set; } - public string Type { get; set; } - public string EquipmentCode { get; set; } - public string Make { get; set; } - public string Model { get; set; } - public string Year { get; set; } - public DateTime ReceivedDate { get; set; } - public float? YearsOfService { get; set; } - public string LicencePlate { get; set; } - public string SerialNumber { get; set; } - public string Size { get; set; } - public float? Seniority { get; set; } - public DateTime? SeniorityEffectiveDate { get; set; } - public DateTime? ToDate { get; set; } - public int? NumberInBlock { get; set; } - public int? BlockNumber { get; set; } - public float? ServiceHoursLastYear { get; set; } - public float? ServiceHoursThreeYearsAgo { get; set; } - public float? ServiceHoursTwoYearsAgo { get; set; } - public bool? IsSeniorityOverridden { get; set; } - public string SeniorityOverrideReason { get; set; } - public DateTime? ApprovedDate { get; set; } - public int EquipmentStatusTypeId { get; set; } - public string StatusComment { get; set; } - public DateTime? ArchiveDate { get; set; } - public string ArchiveCode { get; set; } - public string ArchiveReason { get; set; } - public DateTime LastVerifiedDate { get; set; } - public string InformationUpdateNeededReason { get; set; } - public bool? IsInformationUpdateNeeded { get; set; } - public int? DistrictEquipmentTypeId { get; set; } - public int? LocalAreaId { get; set; } - public string Operator { get; set; } - public int? OwnerId { get; set; } - public float? PayRate { get; set; } - public string RefuseRate { get; set; } - public string LegalCapacity { get; set; } - public string LicencedGvw { get; set; } - public string PupLegalCapacity { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } - public virtual HetEquipmentStatusType EquipmentStatusType { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - public virtual HetOwner Owner { get; set; } - public virtual ICollection HetDigitalFiles { get; set; } - public virtual ICollection HetEquipmentAttachments { get; set; } - public virtual ICollection HetHistories { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlock1s { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlock2s { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlockOpens { get; set; } - public virtual ICollection HetNotes { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - public virtual ICollection HetRentalRequestRotationLists { get; set; } - public virtual ICollection HetRentalRequests { get; set; } - public virtual ICollection HetSeniorityAudits { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipmentAttachment.cs b/Server/HetsData/Model/HetEquipmentAttachment.cs deleted file mode 100644 index 5421d15bc..000000000 --- a/Server/HetsData/Model/HetEquipmentAttachment.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipmentAttachment - { - public int EquipmentAttachmentId { get; set; } - public string TypeName { get; set; } - public string Description { get; set; } - public int? EquipmentId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipmentAttachmentHist.cs b/Server/HetsData/Model/HetEquipmentAttachmentHist.cs deleted file mode 100644 index 6010e4595..000000000 --- a/Server/HetsData/Model/HetEquipmentAttachmentHist.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipmentAttachmentHist - { - public int EquipmentAttachmentHistId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public int EquipmentAttachmentId { get; set; } - public string TypeName { get; set; } - public string Description { get; set; } - public int? EquipmentId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipmentHist.cs b/Server/HetsData/Model/HetEquipmentHist.cs deleted file mode 100644 index 4d35a8c05..000000000 --- a/Server/HetsData/Model/HetEquipmentHist.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipmentHist - { - public int EquipmentHistId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public int EquipmentId { get; set; } - public string Type { get; set; } - public string EquipmentCode { get; set; } - public string Make { get; set; } - public string Model { get; set; } - public string Year { get; set; } - public DateTime ReceivedDate { get; set; } - public float? YearsOfService { get; set; } - public string LicencePlate { get; set; } - public string SerialNumber { get; set; } - public string Size { get; set; } - public float? Seniority { get; set; } - public DateTime? SeniorityEffectiveDate { get; set; } - public DateTime? ToDate { get; set; } - public int? NumberInBlock { get; set; } - public int? BlockNumber { get; set; } - public float? ServiceHoursLastYear { get; set; } - public float? ServiceHoursThreeYearsAgo { get; set; } - public float? ServiceHoursTwoYearsAgo { get; set; } - public bool? IsSeniorityOverridden { get; set; } - public string SeniorityOverrideReason { get; set; } - public DateTime? ApprovedDate { get; set; } - public int EquipmentStatusTypeId { get; set; } - public string StatusComment { get; set; } - public DateTime? ArchiveDate { get; set; } - public string ArchiveCode { get; set; } - public string ArchiveReason { get; set; } - public DateTime LastVerifiedDate { get; set; } - public string InformationUpdateNeededReason { get; set; } - public bool? IsInformationUpdateNeeded { get; set; } - public int? DistrictEquipmentTypeId { get; set; } - public int? LocalAreaId { get; set; } - public string Operator { get; set; } - public int? OwnerId { get; set; } - public float? PayRate { get; set; } - public string RefuseRate { get; set; } - public string LegalCapacity { get; set; } - public string LicencedGvw { get; set; } - public string PupLegalCapacity { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipmentStatusType.cs b/Server/HetsData/Model/HetEquipmentStatusType.cs deleted file mode 100644 index d258d99cc..000000000 --- a/Server/HetsData/Model/HetEquipmentStatusType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipmentStatusType - { - public HetEquipmentStatusType() - { - HetEquipments = new HashSet(); - } - - public int EquipmentStatusTypeId { get; set; } - public string EquipmentStatusTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetEquipments { get; set; } - } -} diff --git a/Server/HetsData/Model/HetEquipmentType.cs b/Server/HetsData/Model/HetEquipmentType.cs deleted file mode 100644 index 545b5f5df..000000000 --- a/Server/HetsData/Model/HetEquipmentType.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetEquipmentType - { - public HetEquipmentType() - { - HetDistrictEquipmentTypes = new HashSet(); - } - - public int EquipmentTypeId { get; set; } - public string Name { get; set; } - public float? BlueBookRateNumber { get; set; } - public float? BlueBookSection { get; set; } - public bool IsDumpTruck { get; set; } - public int NumberOfBlocks { get; set; } - public float? ExtendHours { get; set; } - public float? MaximumHours { get; set; } - public float? MaxHoursSub { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetDistrictEquipmentTypes { get; set; } - } -} diff --git a/Server/HetsData/Model/HetHistory.cs b/Server/HetsData/Model/HetHistory.cs deleted file mode 100644 index f06234d9b..000000000 --- a/Server/HetsData/Model/HetHistory.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetHistory - { - public int HistoryId { get; set; } - public DateTime? CreatedDate { get; set; } - public string HistoryText { get; set; } - public int? EquipmentId { get; set; } - public int? OwnerId { get; set; } - public int? ProjectId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - public virtual HetOwner Owner { get; set; } - public virtual HetProject Project { get; set; } - public virtual HetRentalRequest RentalRequest { get; set; } - } -} diff --git a/Server/HetsData/Model/HetImportMap.cs b/Server/HetsData/Model/HetImportMap.cs deleted file mode 100644 index 7cd3becfd..000000000 --- a/Server/HetsData/Model/HetImportMap.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetImportMap - { - public int ImportMapId { get; set; } - public string OldTable { get; set; } - public string OldKey { get; set; } - public string NewTable { get; set; } - public int NewKey { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetLocalArea.cs b/Server/HetsData/Model/HetLocalArea.cs deleted file mode 100644 index 27f7fcaeb..000000000 --- a/Server/HetsData/Model/HetLocalArea.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetLocalArea - { - public HetLocalArea() - { - HetEquipments = new HashSet(); - HetLocalAreaRotationLists = new HashSet(); - HetOwners = new HashSet(); - HetRentalRequests = new HashSet(); - HetSeniorityAudits = new HashSet(); - } - - public int LocalAreaId { get; set; } - public int LocalAreaNumber { get; set; } - public string Name { get; set; } - public DateTime? EndDate { get; set; } - public DateTime StartDate { get; set; } - public int? ServiceAreaId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetServiceArea ServiceArea { get; set; } - public virtual ICollection HetEquipments { get; set; } - public virtual ICollection HetLocalAreaRotationLists { get; set; } - public virtual ICollection HetOwners { get; set; } - public virtual ICollection HetRentalRequests { get; set; } - public virtual ICollection HetSeniorityAudits { get; set; } - } -} diff --git a/Server/HetsData/Model/HetLocalAreaRotationList.cs b/Server/HetsData/Model/HetLocalAreaRotationList.cs deleted file mode 100644 index f60231043..000000000 --- a/Server/HetsData/Model/HetLocalAreaRotationList.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetLocalAreaRotationList - { - public int LocalAreaRotationListId { get; set; } - public int? LocalAreaId { get; set; } - public int? DistrictEquipmentTypeId { get; set; } - public int? AskNextBlock1Id { get; set; } - public float? AskNextBlock1Seniority { get; set; } - public int? AskNextBlock2Id { get; set; } - public float? AskNextBlock2Seniority { get; set; } - public int? AskNextBlockOpenId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment AskNextBlock1 { get; set; } - public virtual HetEquipment AskNextBlock2 { get; set; } - public virtual HetEquipment AskNextBlockOpen { get; set; } - public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - } -} diff --git a/Server/HetsData/Model/HetMimeType.cs b/Server/HetsData/Model/HetMimeType.cs deleted file mode 100644 index 1808920da..000000000 --- a/Server/HetsData/Model/HetMimeType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetMimeType - { - public HetMimeType() - { - HetDigitalFiles = new HashSet(); - } - - public int MimeTypeId { get; set; } - public string MimeTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetDigitalFiles { get; set; } - } -} diff --git a/Server/HetsData/Model/HetNote.cs b/Server/HetsData/Model/HetNote.cs deleted file mode 100644 index 56f620ca8..000000000 --- a/Server/HetsData/Model/HetNote.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetNote - { - public int NoteId { get; set; } - public string Text { get; set; } - public bool? IsNoLongerRelevant { get; set; } - public int? EquipmentId { get; set; } - public int? OwnerId { get; set; } - public int? ProjectId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - public virtual HetOwner Owner { get; set; } - public virtual HetProject Project { get; set; } - public virtual HetRentalRequest RentalRequest { get; set; } - } -} diff --git a/Server/HetsData/Model/HetNoteHist.cs b/Server/HetsData/Model/HetNoteHist.cs deleted file mode 100644 index f0f5133e9..000000000 --- a/Server/HetsData/Model/HetNoteHist.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetNoteHist - { - public int NoteHistId { get; set; } - public int NoteId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public string Text { get; set; } - public bool? IsNoLongerRelevant { get; set; } - public int? EquipmentId { get; set; } - public int? OwnerId { get; set; } - public int? ProjectId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetOwner.cs b/Server/HetsData/Model/HetOwner.cs deleted file mode 100644 index 168a6584b..000000000 --- a/Server/HetsData/Model/HetOwner.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetOwner - { - public HetOwner() - { - HetContacts = new HashSet(); - HetDigitalFiles = new HashSet(); - HetEquipments = new HashSet(); - HetHistories = new HashSet(); - HetNotes = new HashSet(); - HetSeniorityAudits = new HashSet(); - } - - public int OwnerId { get; set; } - public string OrganizationName { get; set; } - public string OwnerCode { get; set; } - public string DoingBusinessAs { get; set; } - public string Surname { get; set; } - public string GivenName { get; set; } - public string RegisteredCompanyNumber { get; set; } - public string Address1 { get; set; } - public string Address2 { get; set; } - public string City { get; set; } - public string PostalCode { get; set; } - public string Province { get; set; } - public int OwnerStatusTypeId { get; set; } - public string StatusComment { get; set; } - public DateTime? ArchiveDate { get; set; } - public string ArchiveCode { get; set; } - public string ArchiveReason { get; set; } - public int? LocalAreaId { get; set; } - public int? PrimaryContactId { get; set; } - public string CglCompany { get; set; } - public string CglPolicyNumber { get; set; } - public DateTime? CglendDate { get; set; } - public string WorkSafeBcpolicyNumber { get; set; } - public DateTime? WorkSafeBcexpiryDate { get; set; } - public bool? IsMaintenanceContractor { get; set; } - public bool MeetsResidency { get; set; } - public int? BusinessId { get; set; } - public string SharedKey { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetBusiness Business { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - public virtual HetOwnerStatusType OwnerStatusType { get; set; } - public virtual HetContact PrimaryContact { get; set; } - public virtual ICollection HetContacts { get; set; } - public virtual ICollection HetDigitalFiles { get; set; } - public virtual ICollection HetEquipments { get; set; } - public virtual ICollection HetHistories { get; set; } - public virtual ICollection HetNotes { get; set; } - public virtual ICollection HetSeniorityAudits { get; set; } - } -} diff --git a/Server/HetsData/Model/HetOwnerStatusType.cs b/Server/HetsData/Model/HetOwnerStatusType.cs deleted file mode 100644 index 91f376517..000000000 --- a/Server/HetsData/Model/HetOwnerStatusType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetOwnerStatusType - { - public HetOwnerStatusType() - { - HetOwners = new HashSet(); - } - - public int OwnerStatusTypeId { get; set; } - public string OwnerStatusTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetOwners { get; set; } - } -} diff --git a/Server/HetsData/Model/HetPermission.cs b/Server/HetsData/Model/HetPermission.cs deleted file mode 100644 index 6f6270b02..000000000 --- a/Server/HetsData/Model/HetPermission.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetPermission - { - public HetPermission() - { - HetRolePermissions = new HashSet(); - } - - public int PermissionId { get; set; } - public string Code { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetRolePermissions { get; set; } - } -} diff --git a/Server/HetsData/Model/HetPerson.cs b/Server/HetsData/Model/HetPerson.cs deleted file mode 100644 index 1e7021e12..000000000 --- a/Server/HetsData/Model/HetPerson.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetPerson - { - public int PersonId { get; set; } - public string Surname { get; set; } - public string FirstName { get; set; } - public string MiddleNames { get; set; } - public string NameSuffix { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetProject.cs b/Server/HetsData/Model/HetProject.cs deleted file mode 100644 index 66445a5bb..000000000 --- a/Server/HetsData/Model/HetProject.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetProject - { - public HetProject() - { - HetContacts = new HashSet(); - HetDigitalFiles = new HashSet(); - HetHistories = new HashSet(); - HetNotes = new HashSet(); - HetRentalAgreements = new HashSet(); - HetRentalRequests = new HashSet(); - } - - public int ProjectId { get; set; } - public string ProvincialProjectNumber { get; set; } - public string Name { get; set; } - public int ProjectStatusTypeId { get; set; } - public string Information { get; set; } - public int? DistrictId { get; set; } - public int? PrimaryContactId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public string FiscalYear { get; set; } - public string ResponsibilityCentre { get; set; } - public string ServiceLine { get; set; } - public string Stob { get; set; } - public string Product { get; set; } - public string BusinessFunction { get; set; } - public string WorkActivity { get; set; } - public string CostType { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual HetContact PrimaryContact { get; set; } - public virtual HetProjectStatusType ProjectStatusType { get; set; } - public virtual ICollection HetContacts { get; set; } - public virtual ICollection HetDigitalFiles { get; set; } - public virtual ICollection HetHistories { get; set; } - public virtual ICollection HetNotes { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - public virtual ICollection HetRentalRequests { get; set; } - } -} diff --git a/Server/HetsData/Model/HetProjectStatusType.cs b/Server/HetsData/Model/HetProjectStatusType.cs deleted file mode 100644 index 41a1e8f34..000000000 --- a/Server/HetsData/Model/HetProjectStatusType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetProjectStatusType - { - public HetProjectStatusType() - { - HetProjects = new HashSet(); - } - - public int ProjectStatusTypeId { get; set; } - public string ProjectStatusTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetProjects { get; set; } - } -} diff --git a/Server/HetsData/Model/HetProvincialRateType.cs b/Server/HetsData/Model/HetProvincialRateType.cs deleted file mode 100644 index 140119f4e..000000000 --- a/Server/HetsData/Model/HetProvincialRateType.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetProvincialRateType - { - public string RateType { get; set; } - public bool Active { get; set; } - public string Description { get; set; } - public string PeriodType { get; set; } - public float? Rate { get; set; } - public bool Overtime { get; set; } - public bool IsIncludedInTotal { get; set; } - public bool IsPercentRate { get; set; } - public bool IsRateEditable { get; set; } - public bool IsInTotalEditable { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRatePeriodType.cs b/Server/HetsData/Model/HetRatePeriodType.cs deleted file mode 100644 index 2124fdbab..000000000 --- a/Server/HetsData/Model/HetRatePeriodType.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRatePeriodType - { - public HetRatePeriodType() - { - HetRentalAgreementRates = new HashSet(); - HetRentalAgreements = new HashSet(); - } - - public int RatePeriodTypeId { get; set; } - public string RatePeriodTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetRentalAgreementRates { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRegion.cs b/Server/HetsData/Model/HetRegion.cs deleted file mode 100644 index d033a3f39..000000000 --- a/Server/HetsData/Model/HetRegion.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRegion - { - public HetRegion() - { - HetDistricts = new HashSet(); - } - - public int RegionId { get; set; } - public string Name { get; set; } - public int? RegionNumber { get; set; } - public int MinistryRegionId { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetDistricts { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreement.cs b/Server/HetsData/Model/HetRentalAgreement.cs deleted file mode 100644 index c313fa940..000000000 --- a/Server/HetsData/Model/HetRentalAgreement.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreement - { - public HetRentalAgreement() - { - HetRentalAgreementConditions = new HashSet(); - HetRentalAgreementRates = new HashSet(); - HetRentalRequestRotationLists = new HashSet(); - HetTimeRecords = new HashSet(); - } - - public int RentalAgreementId { get; set; } - public string Number { get; set; } - public int? EstimateHours { get; set; } - public DateTime? EstimateStartWork { get; set; } - public string Note { get; set; } - public float? EquipmentRate { get; set; } - public string RateComment { get; set; } - public int RatePeriodTypeId { get; set; } - public DateTime? DatedOn { get; set; } - public int RentalAgreementStatusTypeId { get; set; } - public int? EquipmentId { get; set; } - public int? ProjectId { get; set; } - public int? DistrictId { get; set; } - public int? RentalRequestId { get; set; } - public int? RentalRequestRotationListId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public string AgreementCity { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual HetEquipment Equipment { get; set; } - public virtual HetProject Project { get; set; } - public virtual HetRatePeriodType RatePeriodType { get; set; } - public virtual HetRentalAgreementStatusType RentalAgreementStatusType { get; set; } - public virtual HetRentalRequest RentalRequest { get; set; } - public virtual HetRentalRequestRotationList RentalRequestRotationList { get; set; } - public virtual ICollection HetRentalAgreementConditions { get; set; } - public virtual ICollection HetRentalAgreementRates { get; set; } - public virtual ICollection HetRentalRequestRotationLists { get; set; } - public virtual ICollection HetTimeRecords { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementCondition.cs b/Server/HetsData/Model/HetRentalAgreementCondition.cs deleted file mode 100644 index 50132d045..000000000 --- a/Server/HetsData/Model/HetRentalAgreementCondition.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementCondition - { - public int RentalAgreementConditionId { get; set; } - public string Comment { get; set; } - public string ConditionName { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetRentalAgreement RentalAgreement { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementConditionHist.cs b/Server/HetsData/Model/HetRentalAgreementConditionHist.cs deleted file mode 100644 index 8297f54e3..000000000 --- a/Server/HetsData/Model/HetRentalAgreementConditionHist.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementConditionHist - { - public int RentalAgreementConditionHistId { get; set; } - public int RentalAgreementConditionId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public string Comment { get; set; } - public string ConditionName { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementHist.cs b/Server/HetsData/Model/HetRentalAgreementHist.cs deleted file mode 100644 index 8b3f2d572..000000000 --- a/Server/HetsData/Model/HetRentalAgreementHist.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementHist - { - public int RentalAgreementHistId { get; set; } - public int RentalAgreementId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public string Number { get; set; } - public int? EstimateHours { get; set; } - public DateTime? EstimateStartWork { get; set; } - public string Note { get; set; } - public float? EquipmentRate { get; set; } - public string RateComment { get; set; } - public int RatePeriodTypeId { get; set; } - public DateTime? DatedOn { get; set; } - public int RentalAgreementStatusTypeId { get; set; } - public int? EquipmentId { get; set; } - public int? ProjectId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public string AgreementCity { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementRate.cs b/Server/HetsData/Model/HetRentalAgreementRate.cs deleted file mode 100644 index 710dc3fa7..000000000 --- a/Server/HetsData/Model/HetRentalAgreementRate.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementRate - { - public HetRentalAgreementRate() - { - HetTimeRecords = new HashSet(); - } - - public int RentalAgreementRateId { get; set; } - public string Comment { get; set; } - public string ComponentName { get; set; } - public float? Rate { get; set; } - public bool? Overtime { get; set; } - public bool? Active { get; set; } - public bool IsIncludedInTotal { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public bool? Set { get; set; } - public int? RatePeriodTypeId { get; set; } - - public virtual HetRatePeriodType RatePeriodType { get; set; } - public virtual HetRentalAgreement RentalAgreement { get; set; } - public virtual ICollection HetTimeRecords { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementRateHist.cs b/Server/HetsData/Model/HetRentalAgreementRateHist.cs deleted file mode 100644 index d4a5ba719..000000000 --- a/Server/HetsData/Model/HetRentalAgreementRateHist.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementRateHist - { - public int RentalAgreementRateHistId { get; set; } - public int RentalAgreementRateId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public string Comment { get; set; } - public string ComponentName { get; set; } - public float? Rate { get; set; } - public bool? Overtime { get; set; } - public bool? Active { get; set; } - public bool IsIncludedInTotal { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - public bool? Set { get; set; } - public int? RatePeriodTypeId { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalAgreementStatusType.cs b/Server/HetsData/Model/HetRentalAgreementStatusType.cs deleted file mode 100644 index 731c5b497..000000000 --- a/Server/HetsData/Model/HetRentalAgreementStatusType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalAgreementStatusType - { - public HetRentalAgreementStatusType() - { - HetRentalAgreements = new HashSet(); - } - - public int RentalAgreementStatusTypeId { get; set; } - public string RentalAgreementStatusTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetRentalAgreements { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalRequest.cs b/Server/HetsData/Model/HetRentalRequest.cs deleted file mode 100644 index 29e817e39..000000000 --- a/Server/HetsData/Model/HetRentalRequest.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalRequest - { - public HetRentalRequest() - { - HetDigitalFiles = new HashSet(); - HetHistories = new HashSet(); - HetNotes = new HashSet(); - HetRentalAgreements = new HashSet(); - HetRentalRequestAttachments = new HashSet(); - HetRentalRequestRotationLists = new HashSet(); - } - - public int RentalRequestId { get; set; } - public int EquipmentCount { get; set; } - public DateTime? ExpectedStartDate { get; set; } - public DateTime? ExpectedEndDate { get; set; } - public int? ExpectedHours { get; set; } - public int? FirstOnRotationListId { get; set; } - public int RentalRequestStatusTypeId { get; set; } - public int? DistrictEquipmentTypeId { get; set; } - public int? LocalAreaId { get; set; } - public int? ProjectId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } - public virtual HetEquipment FirstOnRotationList { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - public virtual HetProject Project { get; set; } - public virtual HetRentalRequestStatusType RentalRequestStatusType { get; set; } - public virtual ICollection HetDigitalFiles { get; set; } - public virtual ICollection HetHistories { get; set; } - public virtual ICollection HetNotes { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - public virtual ICollection HetRentalRequestAttachments { get; set; } - public virtual ICollection HetRentalRequestRotationLists { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalRequestAttachment.cs b/Server/HetsData/Model/HetRentalRequestAttachment.cs deleted file mode 100644 index 8ab051aae..000000000 --- a/Server/HetsData/Model/HetRentalRequestAttachment.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalRequestAttachment - { - public int RentalRequestAttachmentId { get; set; } - public string Attachment { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetRentalRequest RentalRequest { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalRequestRotationList.cs b/Server/HetsData/Model/HetRentalRequestRotationList.cs deleted file mode 100644 index 60ffe2d2d..000000000 --- a/Server/HetsData/Model/HetRentalRequestRotationList.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalRequestRotationList - { - public HetRentalRequestRotationList() - { - HetRentalAgreements = new HashSet(); - } - - public int RentalRequestRotationListId { get; set; } - public int RotationListSortOrder { get; set; } - public DateTime? AskedDateTime { get; set; } - public bool? WasAsked { get; set; } - public string OfferResponse { get; set; } - public string OfferResponseNote { get; set; } - public string OfferRefusalReason { get; set; } - public DateTime? OfferResponseDatetime { get; set; } - public bool? IsForceHire { get; set; } - public string Note { get; set; } - public int? EquipmentId { get; set; } - public int? RentalAgreementId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - public virtual HetRentalAgreement RentalAgreement { get; set; } - public virtual HetRentalRequest RentalRequest { get; set; } - public virtual ICollection HetRentalAgreements { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalRequestRotationListHist.cs b/Server/HetsData/Model/HetRentalRequestRotationListHist.cs deleted file mode 100644 index 20515e467..000000000 --- a/Server/HetsData/Model/HetRentalRequestRotationListHist.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalRequestRotationListHist - { - public int RentalRequestRotationListHistId { get; set; } - public int RentalRequestRotationListId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public int RotationListSortOrder { get; set; } - public DateTime? AskedDateTime { get; set; } - public bool? WasAsked { get; set; } - public string OfferResponse { get; set; } - public string OfferResponseNote { get; set; } - public string OfferRefusalReason { get; set; } - public DateTime? OfferResponseDatetime { get; set; } - public bool? IsForceHire { get; set; } - public string Note { get; set; } - public int? EquipmentId { get; set; } - public int? RentalAgreementId { get; set; } - public int? RentalRequestId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRentalRequestStatusType.cs b/Server/HetsData/Model/HetRentalRequestStatusType.cs deleted file mode 100644 index bdb1f8046..000000000 --- a/Server/HetsData/Model/HetRentalRequestStatusType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRentalRequestStatusType - { - public HetRentalRequestStatusType() - { - HetRentalRequests = new HashSet(); - } - - public int RentalRequestStatusTypeId { get; set; } - public string RentalRequestStatusTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetRentalRequests { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRole.cs b/Server/HetsData/Model/HetRole.cs deleted file mode 100644 index af1b46932..000000000 --- a/Server/HetsData/Model/HetRole.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRole - { - public HetRole() - { - HetBusinessUserRoles = new HashSet(); - HetRolePermissions = new HashSet(); - HetUserRoles = new HashSet(); - } - - public int RoleId { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetBusinessUserRoles { get; set; } - public virtual ICollection HetRolePermissions { get; set; } - public virtual ICollection HetUserRoles { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRolePermission.cs b/Server/HetsData/Model/HetRolePermission.cs deleted file mode 100644 index 28853d6d5..000000000 --- a/Server/HetsData/Model/HetRolePermission.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRolePermission - { - public int RolePermissionId { get; set; } - public int? PermissionId { get; set; } - public int? RoleId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetPermission Permission { get; set; } - public virtual HetRole Role { get; set; } - } -} diff --git a/Server/HetsData/Model/HetRolloverProgress.cs b/Server/HetsData/Model/HetRolloverProgress.cs deleted file mode 100644 index 99f5bc793..000000000 --- a/Server/HetsData/Model/HetRolloverProgress.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetRolloverProgress - { - public int DistrictId { get; set; } - public int? ProgressPercentage { get; set; } - - public virtual HetDistrict District { get; set; } - } -} diff --git a/Server/HetsData/Model/HetSeniorityAudit.cs b/Server/HetsData/Model/HetSeniorityAudit.cs deleted file mode 100644 index 5305a052e..000000000 --- a/Server/HetsData/Model/HetSeniorityAudit.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetSeniorityAudit - { - public int SeniorityAuditId { get; set; } - public DateTime StartDate { get; set; } - public DateTime EndDate { get; set; } - public string OwnerOrganizationName { get; set; } - public float? Seniority { get; set; } - public int? BlockNumber { get; set; } - public bool? IsSeniorityOverridden { get; set; } - public string SeniorityOverrideReason { get; set; } - public float? ServiceHoursLastYear { get; set; } - public float? ServiceHoursThreeYearsAgo { get; set; } - public float? ServiceHoursTwoYearsAgo { get; set; } - public int? EquipmentId { get; set; } - public int? LocalAreaId { get; set; } - public int? OwnerId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment Equipment { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - public virtual HetOwner Owner { get; set; } - } -} diff --git a/Server/HetsData/Model/HetServiceArea.cs b/Server/HetsData/Model/HetServiceArea.cs deleted file mode 100644 index eb9d7eda7..000000000 --- a/Server/HetsData/Model/HetServiceArea.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetServiceArea - { - public HetServiceArea() - { - HetLocalAreas = new HashSet(); - } - - public int ServiceAreaId { get; set; } - public string Name { get; set; } - public int? AreaNumber { get; set; } - public int MinistryServiceAreaId { get; set; } - public DateTime FiscalStartDate { get; set; } - public DateTime? FiscalEndDate { get; set; } - public string Address { get; set; } - public string Phone { get; set; } - public string Fax { get; set; } - public string SupportingDocuments { get; set; } - public int? DistrictId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual ICollection HetLocalAreas { get; set; } - } -} diff --git a/Server/HetsData/Model/HetTimePeriodType.cs b/Server/HetsData/Model/HetTimePeriodType.cs deleted file mode 100644 index fedf39cdd..000000000 --- a/Server/HetsData/Model/HetTimePeriodType.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetTimePeriodType - { - public HetTimePeriodType() - { - HetTimeRecords = new HashSet(); - } - - public int TimePeriodTypeId { get; set; } - public string TimePeriodTypeCode { get; set; } - public string Description { get; set; } - public string ScreenLabel { get; set; } - public int? DisplayOrder { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual ICollection HetTimeRecords { get; set; } - } -} diff --git a/Server/HetsData/Model/HetTimeRecord.cs b/Server/HetsData/Model/HetTimeRecord.cs deleted file mode 100644 index d8398214b..000000000 --- a/Server/HetsData/Model/HetTimeRecord.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetTimeRecord - { - public int TimeRecordId { get; set; } - public DateTime? EnteredDate { get; set; } - public DateTime WorkedDate { get; set; } - public int TimePeriodTypeId { get; set; } - public float? Hours { get; set; } - public int? RentalAgreementRateId { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetRentalAgreement RentalAgreement { get; set; } - public virtual HetRentalAgreementRate RentalAgreementRate { get; set; } - public virtual HetTimePeriodType TimePeriodType { get; set; } - } -} diff --git a/Server/HetsData/Model/HetTimeRecordHist.cs b/Server/HetsData/Model/HetTimeRecordHist.cs deleted file mode 100644 index c20107bd3..000000000 --- a/Server/HetsData/Model/HetTimeRecordHist.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetTimeRecordHist - { - public int TimeRecordHistId { get; set; } - public int TimeRecordId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? EndDate { get; set; } - public DateTime? EnteredDate { get; set; } - public DateTime WorkedDate { get; set; } - public int TimePeriodTypeId { get; set; } - public float? Hours { get; set; } - public int? RentalAgreementRateId { get; set; } - public int? RentalAgreementId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Model/HetUser.cs b/Server/HetsData/Model/HetUser.cs deleted file mode 100644 index d94605272..000000000 --- a/Server/HetsData/Model/HetUser.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetUser - { - public HetUser() - { - HetUserDistricts = new HashSet(); - HetUserFavourites = new HashSet(); - HetUserRoles = new HashSet(); - } - - public int UserId { get; set; } - public string Surname { get; set; } - public string GivenName { get; set; } - public string Initials { get; set; } - public string SmUserId { get; set; } - public string SmAuthorizationDirectory { get; set; } - public string Guid { get; set; } - public string Email { get; set; } - public string AgreementCity { get; set; } - public bool Active { get; set; } - public int? DistrictId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual ICollection HetUserDistricts { get; set; } - public virtual ICollection HetUserFavourites { get; set; } - public virtual ICollection HetUserRoles { get; set; } - } -} diff --git a/Server/HetsData/Model/HetUserDistrict.cs b/Server/HetsData/Model/HetUserDistrict.cs deleted file mode 100644 index 2743c7f8c..000000000 --- a/Server/HetsData/Model/HetUserDistrict.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetUserDistrict - { - public int UserDistrictId { get; set; } - public bool IsPrimary { get; set; } - public int? UserId { get; set; } - public int? DistrictId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual HetUser User { get; set; } - } -} diff --git a/Server/HetsData/Model/HetUserFavourite.cs b/Server/HetsData/Model/HetUserFavourite.cs deleted file mode 100644 index be9db73a0..000000000 --- a/Server/HetsData/Model/HetUserFavourite.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetUserFavourite - { - public int UserFavouriteId { get; set; } - public string Type { get; set; } - public string Name { get; set; } - public string Value { get; set; } - public bool? IsDefault { get; set; } - public int? UserId { get; set; } - public int? DistrictId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetDistrict District { get; set; } - public virtual HetUser User { get; set; } - } -} diff --git a/Server/HetsData/Model/HetUserRole.cs b/Server/HetsData/Model/HetUserRole.cs deleted file mode 100644 index 94976b353..000000000 --- a/Server/HetsData/Model/HetUserRole.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Model -{ - public partial class HetUserRole - { - public int UserRoleId { get; set; } - public DateTime EffectiveDate { get; set; } - public DateTime? ExpiryDate { get; set; } - public int? UserId { get; set; } - public int? RoleId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetRole Role { get; set; } - public virtual HetUser User { get; set; } - } -} From 9141230e2cb128aaef17226c6a6aea463ec79267 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Mon, 19 Jul 2021 14:09:00 -0700 Subject: [PATCH 132/352] Updated scaffold instruction --- Server/HetsData/Scaffold.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/HetsData/Scaffold.txt b/Server/HetsData/Scaffold.txt index 785fe3754..7a47a44b1 100644 --- a/Server/HetsData/Scaffold.txt +++ b/Server/HetsData/Scaffold.txt @@ -1,7 +1,7 @@ ******************************************** Step 1: Generate / Update Model: ******************************************** -Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Entities -Force -Project "HetsData" -Verbose -Context "DbAppContext" -Schema "public" +Scaffold-DbContext "Host=localhost;Username=postgres;Password=postgres;Database=hets;Port=9010" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Entities -Force -Project "HetsData" -Context "DbAppContext" -Schema "public" ******************************************** Step 2: Update Context From 301ee730a6341ffdab35397b22fd5654b2c0f515 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Mon, 19 Jul 2021 14:33:30 -0700 Subject: [PATCH 133/352] removed hangfire entity --- Server/HetsData/Entities/Counter.cs | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Server/HetsData/Entities/Counter.cs diff --git a/Server/HetsData/Entities/Counter.cs b/Server/HetsData/Entities/Counter.cs deleted file mode 100644 index 10a7611ea..000000000 --- a/Server/HetsData/Entities/Counter.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Entities -{ - public partial class Counter - { - public long Id { get; set; } - public string Key { get; set; } - public long Value { get; set; } - public DateTime? Expireat { get; set; } - } -} From 9cf2dad29af4b8f0bd00421b0cce5a991d1a72cc Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 07:26:53 -0700 Subject: [PATCH 134/352] removed unused tables --- Db Scripts/UPDATE/RELEASE1.9.3-01.sql | 6 + .../DistrictEquipmentTypeController.cs | 6 - Server/HetsData/Entities/DbAppContext.cs | 267 ------------------ .../Entities/HetDistrictEquipmentType.cs | 2 - Server/HetsData/Entities/HetEquipment.cs | 6 - Server/HetsData/Entities/HetImportMap.cs | 29 -- Server/HetsData/Entities/HetLocalArea.cs | 2 - .../Entities/HetLocalAreaRotationList.cs | 38 --- Server/HetsData/Entities/HetPerson.cs | 30 -- .../Hangfire/DistrictEquipmentTypesMerger.cs | 10 +- 10 files changed, 8 insertions(+), 388 deletions(-) delete mode 100644 Server/HetsData/Entities/HetImportMap.cs delete mode 100644 Server/HetsData/Entities/HetLocalAreaRotationList.cs delete mode 100644 Server/HetsData/Entities/HetPerson.cs diff --git a/Db Scripts/UPDATE/RELEASE1.9.3-01.sql b/Db Scripts/UPDATE/RELEASE1.9.3-01.sql index 4fea71a98..4dfb0ddff 100644 --- a/Db Scripts/UPDATE/RELEASE1.9.3-01.sql +++ b/Db Scripts/UPDATE/RELEASE1.9.3-01.sql @@ -14,3 +14,9 @@ ADD CONSTRAINT "FK_HET_ROLLOVER_PROGRESS_DISTRICT_ID" FOREIGN KEY ("DISTRICT_ID"); GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE public."HET_ROLLOVER_PROGRESS" TO het_application_proxy; + +DROP TABLE "HET_PERSON"; + +DROP TABLE "HET_LOCAL_AREA_ROTATION_LIST"; + +DROP TABLE "HET_IMPORT_MAP" ; \ No newline at end of file diff --git a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs index 3b011bb59..632180947 100644 --- a/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs +++ b/Server/HetsApi/Controllers/DistrictEquipmentTypeController.cs @@ -162,12 +162,6 @@ public virtual ActionResult DistrictEquipmentTypesIdDe if (equipment != null) softDelete = true; - // check for foreign key relationships - local area rotation lists - HetLocalAreaRotationList rotationList = _context.HetLocalAreaRotationLists.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == item.DistrictEquipmentTypeId); - - if (rotationList != null) softDelete = true; - // check for foreign key relationships - rental requests HetRentalRequest request = _context.HetRentalRequests.AsNoTracking() .FirstOrDefault(x => x.DistrictEquipmentTypeId == item.DistrictEquipmentTypeId); diff --git a/Server/HetsData/Entities/DbAppContext.cs b/Server/HetsData/Entities/DbAppContext.cs index cac2cfc6e..fbca7f94a 100644 --- a/Server/HetsData/Entities/DbAppContext.cs +++ b/Server/HetsData/Entities/DbAppContext.cs @@ -34,16 +34,13 @@ public DbAppContext(DbContextOptions options) public virtual DbSet HetEquipmentStatusTypes { get; set; } public virtual DbSet HetEquipmentTypes { get; set; } public virtual DbSet HetHistories { get; set; } - public virtual DbSet HetImportMaps { get; set; } public virtual DbSet HetLocalAreas { get; set; } - public virtual DbSet HetLocalAreaRotationLists { get; set; } public virtual DbSet HetMimeTypes { get; set; } public virtual DbSet HetNotes { get; set; } public virtual DbSet HetNoteHists { get; set; } public virtual DbSet HetOwners { get; set; } public virtual DbSet HetOwnerStatusTypes { get; set; } public virtual DbSet HetPermissions { get; set; } - public virtual DbSet HetPeople { get; set; } public virtual DbSet HetProjects { get; set; } public virtual DbSet HetProjectStatusTypes { get; set; } public virtual DbSet HetProvincialRateTypes { get; set; } @@ -1821,77 +1818,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasConstraintName("FK_HET_HISTORY_RENTAL_REQUEST_ID"); }); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.ImportMapId); - - entity.ToTable("HET_IMPORT_MAP"); - - entity.Property(e => e.ImportMapId) - .HasColumnName("IMPORT_MAP_ID") - .HasDefaultValueSql("nextval('\"HET_IMPORT_MAP_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.NewKey).HasColumnName("NEW_KEY"); - - entity.Property(e => e.NewTable).HasColumnName("NEW_TABLE"); - - entity.Property(e => e.OldKey) - .HasMaxLength(250) - .HasColumnName("OLD_KEY"); - - entity.Property(e => e.OldTable).HasColumnName("OLD_TABLE"); - }); - modelBuilder.Entity(entity => { entity.HasKey(e => e.LocalAreaId); @@ -1977,116 +1903,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasConstraintName("FK_HET_LOCAL_AREA_SERVICE_AREA_ID"); }); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.LocalAreaRotationListId); - - entity.ToTable("HET_LOCAL_AREA_ROTATION_LIST"); - - entity.HasIndex(e => e.AskNextBlock1Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); - - entity.HasIndex(e => e.AskNextBlock2Id, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); - - entity.HasIndex(e => e.AskNextBlockOpenId, "IX_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); - - entity.HasIndex(e => e.DistrictEquipmentTypeId, "IX_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasIndex(e => e.LocalAreaId, "IX_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); - - entity.Property(e => e.LocalAreaRotationListId) - .HasColumnName("LOCAL_AREA_ROTATION_LIST_ID") - .HasDefaultValueSql("nextval('\"HET_LOCAL_AREA_ROTATION_LIST_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.AskNextBlock1Id).HasColumnName("ASK_NEXT_BLOCK1_ID"); - - entity.Property(e => e.AskNextBlock1Seniority).HasColumnName("ASK_NEXT_BLOCK1_SENIORITY"); - - entity.Property(e => e.AskNextBlock2Id).HasColumnName("ASK_NEXT_BLOCK2_ID"); - - entity.Property(e => e.AskNextBlock2Seniority).HasColumnName("ASK_NEXT_BLOCK2_SENIORITY"); - - entity.Property(e => e.AskNextBlockOpenId).HasColumnName("ASK_NEXT_BLOCK_OPEN_ID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.DistrictEquipmentTypeId).HasColumnName("DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.Property(e => e.LocalAreaId).HasColumnName("LOCAL_AREA_ID"); - - entity.HasOne(d => d.AskNextBlock1) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlock1s) - .HasForeignKey(d => d.AskNextBlock1Id) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK1_ID"); - - entity.HasOne(d => d.AskNextBlock2) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlock2s) - .HasForeignKey(d => d.AskNextBlock2Id) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK2_ID"); - - entity.HasOne(d => d.AskNextBlockOpen) - .WithMany(p => p.HetLocalAreaRotationListAskNextBlockOpens) - .HasForeignKey(d => d.AskNextBlockOpenId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_ASK_NEXT_BLOCK_OPEN_ID"); - - entity.HasOne(d => d.DistrictEquipmentType) - .WithMany(p => p.HetLocalAreaRotationLists) - .HasForeignKey(d => d.DistrictEquipmentTypeId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_DISTRICT_EQUIPMENT_TYPE_ID"); - - entity.HasOne(d => d.LocalArea) - .WithMany(p => p.HetLocalAreaRotationLists) - .HasForeignKey(d => d.LocalAreaId) - .HasConstraintName("FK_HET_LOCAL_AREA_ROTATION_LIST_LOCAL_AREA_ID"); - }); - modelBuilder.Entity(entity => { entity.HasKey(e => e.MimeTypeId); @@ -2701,89 +2517,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasColumnName("NAME"); }); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.PersonId); - - entity.ToTable("HET_PERSON"); - - entity.Property(e => e.PersonId) - .HasColumnName("PERSON_ID") - .HasDefaultValueSql("nextval('\"HET_PERSON_ID_seq\"'::regclass)"); - - entity.Property(e => e.AppCreateTimestamp) - .HasColumnName("APP_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppCreateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_CREATE_USER_DIRECTORY"); - - entity.Property(e => e.AppCreateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USER_GUID"); - - entity.Property(e => e.AppCreateUserid) - .HasMaxLength(255) - .HasColumnName("APP_CREATE_USERID"); - - entity.Property(e => e.AppLastUpdateTimestamp) - .HasColumnName("APP_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.AppLastUpdateUserDirectory) - .HasMaxLength(50) - .HasColumnName("APP_LAST_UPDATE_USER_DIRECTORY"); - - entity.Property(e => e.AppLastUpdateUserGuid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USER_GUID"); - - entity.Property(e => e.AppLastUpdateUserid) - .HasMaxLength(255) - .HasColumnName("APP_LAST_UPDATE_USERID"); - - entity.Property(e => e.ConcurrencyControlNumber).HasColumnName("CONCURRENCY_CONTROL_NUMBER"); - - entity.Property(e => e.DbCreateTimestamp) - .HasColumnName("DB_CREATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbCreateUserId) - .HasMaxLength(63) - .HasColumnName("DB_CREATE_USER_ID"); - - entity.Property(e => e.DbLastUpdateTimestamp) - .HasColumnName("DB_LAST_UPDATE_TIMESTAMP") - .HasDefaultValueSql("'0001-01-01 00:00:00'::timestamp without time zone"); - - entity.Property(e => e.DbLastUpdateUserId) - .HasMaxLength(63) - .HasColumnName("DB_LAST_UPDATE_USER_ID"); - - entity.Property(e => e.FirstName) - .HasMaxLength(50) - .HasColumnName("FIRST_NAME"); - - entity.Property(e => e.IsActive) - .IsRequired() - .HasColumnName("IS_ACTIVE") - .HasDefaultValueSql("true"); - - entity.Property(e => e.MiddleNames) - .HasMaxLength(200) - .HasColumnName("MIDDLE_NAMES"); - - entity.Property(e => e.NameSuffix) - .HasMaxLength(50) - .HasColumnName("NAME_SUFFIX"); - - entity.Property(e => e.Surname) - .IsRequired() - .HasMaxLength(50) - .HasColumnName("SURNAME"); - }); - modelBuilder.Entity(entity => { entity.HasKey(e => e.ProjectId); diff --git a/Server/HetsData/Entities/HetDistrictEquipmentType.cs b/Server/HetsData/Entities/HetDistrictEquipmentType.cs index dde01ca63..d8fdcc666 100644 --- a/Server/HetsData/Entities/HetDistrictEquipmentType.cs +++ b/Server/HetsData/Entities/HetDistrictEquipmentType.cs @@ -10,7 +10,6 @@ public partial class HetDistrictEquipmentType public HetDistrictEquipmentType() { HetEquipments = new HashSet(); - HetLocalAreaRotationLists = new HashSet(); HetRentalRequests = new HashSet(); } @@ -37,7 +36,6 @@ public HetDistrictEquipmentType() public virtual HetDistrict District { get; set; } public virtual HetEquipmentType EquipmentType { get; set; } public virtual ICollection HetEquipments { get; set; } - public virtual ICollection HetLocalAreaRotationLists { get; set; } public virtual ICollection HetRentalRequests { get; set; } } } diff --git a/Server/HetsData/Entities/HetEquipment.cs b/Server/HetsData/Entities/HetEquipment.cs index b51c5068a..0d2a023ff 100644 --- a/Server/HetsData/Entities/HetEquipment.cs +++ b/Server/HetsData/Entities/HetEquipment.cs @@ -12,9 +12,6 @@ public HetEquipment() HetDigitalFiles = new HashSet(); HetEquipmentAttachments = new HashSet(); HetHistories = new HashSet(); - HetLocalAreaRotationListAskNextBlock1s = new HashSet(); - HetLocalAreaRotationListAskNextBlock2s = new HashSet(); - HetLocalAreaRotationListAskNextBlockOpens = new HashSet(); HetNotes = new HashSet(); HetRentalAgreements = new HashSet(); HetRentalRequestRotationLists = new HashSet(); @@ -82,9 +79,6 @@ public HetEquipment() public virtual ICollection HetDigitalFiles { get; set; } public virtual ICollection HetEquipmentAttachments { get; set; } public virtual ICollection HetHistories { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlock1s { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlock2s { get; set; } - public virtual ICollection HetLocalAreaRotationListAskNextBlockOpens { get; set; } public virtual ICollection HetNotes { get; set; } public virtual ICollection HetRentalAgreements { get; set; } public virtual ICollection HetRentalRequestRotationLists { get; set; } diff --git a/Server/HetsData/Entities/HetImportMap.cs b/Server/HetsData/Entities/HetImportMap.cs deleted file mode 100644 index 6446af2a4..000000000 --- a/Server/HetsData/Entities/HetImportMap.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Entities -{ - public partial class HetImportMap - { - public int ImportMapId { get; set; } - public string OldTable { get; set; } - public string OldKey { get; set; } - public string NewTable { get; set; } - public int NewKey { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Entities/HetLocalArea.cs b/Server/HetsData/Entities/HetLocalArea.cs index 99ecf6ddd..5d684a712 100644 --- a/Server/HetsData/Entities/HetLocalArea.cs +++ b/Server/HetsData/Entities/HetLocalArea.cs @@ -10,7 +10,6 @@ public partial class HetLocalArea public HetLocalArea() { HetEquipments = new HashSet(); - HetLocalAreaRotationLists = new HashSet(); HetOwners = new HashSet(); HetRentalRequests = new HashSet(); HetSeniorityAudits = new HashSet(); @@ -38,7 +37,6 @@ public HetLocalArea() public virtual HetServiceArea ServiceArea { get; set; } public virtual ICollection HetEquipments { get; set; } - public virtual ICollection HetLocalAreaRotationLists { get; set; } public virtual ICollection HetOwners { get; set; } public virtual ICollection HetRentalRequests { get; set; } public virtual ICollection HetSeniorityAudits { get; set; } diff --git a/Server/HetsData/Entities/HetLocalAreaRotationList.cs b/Server/HetsData/Entities/HetLocalAreaRotationList.cs deleted file mode 100644 index 72a47da37..000000000 --- a/Server/HetsData/Entities/HetLocalAreaRotationList.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Entities -{ - public partial class HetLocalAreaRotationList - { - public int LocalAreaRotationListId { get; set; } - public int? LocalAreaId { get; set; } - public int? DistrictEquipmentTypeId { get; set; } - public int? AskNextBlock1Id { get; set; } - public float? AskNextBlock1Seniority { get; set; } - public int? AskNextBlock2Id { get; set; } - public float? AskNextBlock2Seniority { get; set; } - public int? AskNextBlockOpenId { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - - public virtual HetEquipment AskNextBlock1 { get; set; } - public virtual HetEquipment AskNextBlock2 { get; set; } - public virtual HetEquipment AskNextBlockOpen { get; set; } - public virtual HetDistrictEquipmentType DistrictEquipmentType { get; set; } - public virtual HetLocalArea LocalArea { get; set; } - } -} diff --git a/Server/HetsData/Entities/HetPerson.cs b/Server/HetsData/Entities/HetPerson.cs deleted file mode 100644 index d1d990fb2..000000000 --- a/Server/HetsData/Entities/HetPerson.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace HetsData.Entities -{ - public partial class HetPerson - { - public int PersonId { get; set; } - public string Surname { get; set; } - public string FirstName { get; set; } - public string MiddleNames { get; set; } - public string NameSuffix { get; set; } - public bool? IsActive { get; set; } - public string AppCreateUserDirectory { get; set; } - public string AppCreateUserGuid { get; set; } - public string AppCreateUserid { get; set; } - public DateTime AppCreateTimestamp { get; set; } - public string AppLastUpdateUserDirectory { get; set; } - public string AppLastUpdateUserGuid { get; set; } - public string AppLastUpdateUserid { get; set; } - public DateTime AppLastUpdateTimestamp { get; set; } - public string DbCreateUserId { get; set; } - public DateTime DbCreateTimestamp { get; set; } - public DateTime DbLastUpdateTimestamp { get; set; } - public string DbLastUpdateUserId { get; set; } - public int ConcurrencyControlNumber { get; set; } - } -} diff --git a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs index aad48eb2b..cff7678a6 100644 --- a/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs +++ b/Server/HetsData/Hangfire/DistrictEquipmentTypesMerger.cs @@ -177,10 +177,7 @@ public void MergeDistrictEquipmentTypes(string seniorityScoringRules) HetRentalRequest request = _dbContext.HetRentalRequests .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - HetLocalAreaRotationList rotationList = _dbContext.HetLocalAreaRotationLists - .FirstOrDefault(x => x.DistrictEquipmentTypeId == originalDistrictEquipmentTypeId); - - if (request != null || rotationList != null) + if (request != null) { det.Deleted = true; } @@ -259,10 +256,7 @@ public void MergeDistrictEquipmentTypes(string seniorityScoringRules) HetRentalRequest request = _dbContext.HetRentalRequests.AsNoTracking() .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); - HetLocalAreaRotationList rotationList = _dbContext.HetLocalAreaRotationLists.AsNoTracking() - .FirstOrDefault(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId); - - if (request != null || rotationList != null) + if (request != null) { det.Deleted = true; } From f07d9d89a16f1efceeeaeae74bca382905fe3813 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 08:36:50 -0700 Subject: [PATCH 135/352] Logger --- Server/HetsApi/Authorization/PermissionHandler.cs | 8 ++++---- Server/HetsApi/Controllers/CurrentUserController.cs | 10 +++++----- Server/HetsApi/Controllers/EquipmentController.cs | 6 +++--- Server/HetsApi/Controllers/OwnerController.cs | 6 +++--- .../HetsApi/Controllers/RentalAgreementController.cs | 10 +++++----- Server/HetsApi/Controllers/RentalRequestController.cs | 6 ++++-- Server/HetsApi/Helpers/UserAccountHelper.cs | 4 ++-- Server/HetsApi/Middlewares/ExceptionMiddleware.cs | 2 +- Server/HetsApi/Model/User.cs | 4 +--- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Server/HetsApi/Authorization/PermissionHandler.cs b/Server/HetsApi/Authorization/PermissionHandler.cs index 9de7876d7..0830db2a0 100644 --- a/Server/HetsApi/Authorization/PermissionHandler.cs +++ b/Server/HetsApi/Authorization/PermissionHandler.cs @@ -2,8 +2,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; -using Serilog; using HetsData.Entities; +using Microsoft.Extensions.Logging; namespace HetsApi.Authorization { @@ -25,10 +25,10 @@ public static IServiceCollection RegisterPermissionHandler(this IServiceCollecti public class PermissionHandler : AuthorizationHandler { - private ILogger _logger; + private ILogger _logger; private IHttpContextAccessor _httpContextAccessor; - public PermissionHandler(ILogger logger, IHttpContextAccessor httpContextAccessor) + public PermissionHandler(ILogger logger, IHttpContextAccessor httpContextAccessor) { _logger = logger; _httpContextAccessor = httpContextAccessor; @@ -47,7 +47,7 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte { if (!user.HasClaim(HetUser.PermissionClaim, permission)) { - _logger.Information("RequiresPermission - {user} - {url} - {permission}", user.Identity.Name, _httpContextAccessor.HttpContext.Request.Path, permission); + _logger.LogInformation("RequiresPermission - {user} - {url} - {permission}", user.Identity.Name, _httpContextAccessor.HttpContext.Request.Path, permission); context.Fail(); return Task.CompletedTask; diff --git a/Server/HetsApi/Controllers/CurrentUserController.cs b/Server/HetsApi/Controllers/CurrentUserController.cs index 29373e9cc..e8788fa95 100644 --- a/Server/HetsApi/Controllers/CurrentUserController.cs +++ b/Server/HetsApi/Controllers/CurrentUserController.cs @@ -27,15 +27,15 @@ public class CurrentUserController : ControllerBase { private readonly DbAppContext _context; private readonly IConfiguration _configuration; - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IWebHostEnvironment _env; private readonly IMapper _mapper; - public CurrentUserController(DbAppContext context, IConfiguration configuration, IMapper mapper, ILoggerFactory loggerFactory, IWebHostEnvironment env) + public CurrentUserController(DbAppContext context, IConfiguration configuration, IMapper mapper, ILogger logger, IWebHostEnvironment env) { _context = context; _configuration = configuration; - _logger = loggerFactory.CreateLogger(typeof(CurrentUserController)); + _logger = logger; _env = env; _mapper = mapper; } @@ -137,7 +137,7 @@ public virtual ActionResult UsersCurrentFavouritesPut([FromBod [HttpGet] [Route("")] [AllowAnonymous] - public virtual ActionResult UsersCurrentGet() + public virtual ActionResult UsersCurrentGet() { _logger.LogDebug("Get Current User"); @@ -151,7 +151,7 @@ public virtual ActionResult UsersCurrentGet() // not found - return an HTTP 401 error response if (string.IsNullOrEmpty(userId)) return StatusCode(401); - User user = new User(); + CurrentUserDto user = new CurrentUserDto(); if (string.IsNullOrEmpty(businessGuid)) { diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index f655539b1..6c0be0a22 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -32,18 +32,18 @@ public class EquipmentController : ControllerBase private readonly IMapper _mapper; private readonly IRentalAgreementRepository _rentalAgreementRepo; private readonly IEquipmentRepository _equipmentRepo; - private readonly ILogger _logger; + private readonly ILogger _logger; public EquipmentController(DbAppContext context, IConfiguration configuration, IRentalAgreementRepository rentalAgreementRepo, IEquipmentRepository equipmentRepo, - IMapper mapper, ILoggerFactory loggerFactory) + IMapper mapper, ILogger logger) { _context = context; _configuration = configuration; _mapper = mapper; _rentalAgreementRepo = rentalAgreementRepo; _equipmentRepo = equipmentRepo; - _logger = loggerFactory.CreateLogger(); + _logger = logger; } /// diff --git a/Server/HetsApi/Controllers/OwnerController.cs b/Server/HetsApi/Controllers/OwnerController.cs index 40fe6fcdd..5417eef67 100644 --- a/Server/HetsApi/Controllers/OwnerController.cs +++ b/Server/HetsApi/Controllers/OwnerController.cs @@ -55,19 +55,19 @@ public class OwnerController : ControllerBase private readonly HttpContext _httpContext; private readonly IOwnerRepository _ownerRepo; private readonly IMapper _mapper; - private readonly ILogger _logger; + private readonly ILogger _logger; public OwnerController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IOwnerRepository ownerRepo, IMapper mapper, - ILoggerFactory loggerFactory) + ILogger logger) { _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _ownerRepo = ownerRepo; _mapper = mapper; - _logger = loggerFactory.CreateLogger(); + _logger = logger; } /// diff --git a/Server/HetsApi/Controllers/RentalAgreementController.cs b/Server/HetsApi/Controllers/RentalAgreementController.cs index a365c1bbe..dccd68240 100644 --- a/Server/HetsApi/Controllers/RentalAgreementController.cs +++ b/Server/HetsApi/Controllers/RentalAgreementController.cs @@ -32,20 +32,20 @@ public class RentalAgreementController : ControllerBase private readonly HttpContext _httpContext; private readonly IRentalAgreementRepository _rentalAgreementRepo; private readonly IMapper _mapper; - private readonly ILogger _logger; + private readonly ILogger _logger; public RentalAgreementController(DbAppContext context, IConfiguration configuration, IHttpContextAccessor httpContextAccessor, IRentalAgreementRepository rentalAgreementRepo, IMapper mapper, - ILoggerFactory loggerFactory) + ILogger logger) { _context = context; _configuration = configuration; _httpContext = httpContextAccessor.HttpContext; _rentalAgreementRepo = rentalAgreementRepo; _mapper = mapper; - _logger = loggerFactory.CreateLogger(); + _logger = logger; } /// @@ -223,7 +223,7 @@ public virtual ActionResult RentalAgreementsPost([FromBody] if (statusId == null) return new BadRequestObjectResult(new HetsResponse("HETS-23", ErrorViewModel.GetDescription("HETS-23", _configuration))); // get user info - agreement city - User user = UserAccountHelper.GetUser(_context, _httpContext); + CurrentUserDto user = UserAccountHelper.GetUser(_context, _httpContext); string agreementCity = user.AgreementCity; // create agreement @@ -329,7 +329,7 @@ public virtual ActionResult RentalAgreementsIdReleasePost([F public virtual IActionResult RentalAgreementsIdDocGet([FromRoute] int id) { // get user info - agreement city - User user = UserAccountHelper.GetUser(_context, _httpContext); + CurrentUserDto user = UserAccountHelper.GetUser(_context, _httpContext); string agreementCity = user.AgreementCity; HetRentalAgreement rentalAgreement = _context.HetRentalAgreements.AsNoTracking() diff --git a/Server/HetsApi/Controllers/RentalRequestController.cs b/Server/HetsApi/Controllers/RentalRequestController.cs index 4f9c1b2d3..da394fac3 100644 --- a/Server/HetsApi/Controllers/RentalRequestController.cs +++ b/Server/HetsApi/Controllers/RentalRequestController.cs @@ -29,17 +29,19 @@ public class RentalRequestController : ControllerBase private readonly IRentalRequestRepository _rentalRequestRepo; private readonly IMapper _mapper; private readonly HttpContext _httpContext; + private readonly ILogger _logger; public RentalRequestController(DbAppContext context, IConfiguration configuration, IRentalRequestRepository rentalRequestRepo, IMapper mapper, - IHttpContextAccessor httpContextAccessor, ILoggerFactory loggerFactory) + IHttpContextAccessor httpContextAccessor, ILogger logger) { _context = context; _configuration = configuration; _rentalRequestRepo = rentalRequestRepo; _mapper = mapper; _httpContext = httpContextAccessor.HttpContext; + _logger = logger; } /// @@ -607,7 +609,7 @@ public virtual ActionResult RentalRequestIdRotationListIdPut([ string agreementNumber = RentalAgreementHelper.GetRentalAgreementNumber(item.Equipment?.LocalAreaId, _context); // get user info - agreement city - User user = UserAccountHelper.GetUser(_context, _httpContext); + CurrentUserDto user = UserAccountHelper.GetUser(_context, _httpContext); string agreementCity = user.AgreementCity; int? rateTypeId = StatusHelper.GetRatePeriodId(HetRatePeriodType.PeriodHourly, _context); diff --git a/Server/HetsApi/Helpers/UserAccountHelper.cs b/Server/HetsApi/Helpers/UserAccountHelper.cs index 12aedd725..53f149cb2 100644 --- a/Server/HetsApi/Helpers/UserAccountHelper.cs +++ b/Server/HetsApi/Helpers/UserAccountHelper.cs @@ -52,9 +52,9 @@ public static bool IsBusiness(HttpContext httpContext) /// /// /// - public static User GetUser(DbAppContext context, HttpContext httpContext) + public static CurrentUserDto GetUser(DbAppContext context, HttpContext httpContext) { - User user = new User(); + CurrentUserDto user = new CurrentUserDto(); // is this a business? bool isBusinessUser = IsBusiness(httpContext); diff --git a/Server/HetsApi/Middlewares/ExceptionMiddleware.cs b/Server/HetsApi/Middlewares/ExceptionMiddleware.cs index fde6c0e09..877979a95 100644 --- a/Server/HetsApi/Middlewares/ExceptionMiddleware.cs +++ b/Server/HetsApi/Middlewares/ExceptionMiddleware.cs @@ -11,7 +11,7 @@ namespace HetsApi.Middlewares public class ExceptionMiddleware { private readonly RequestDelegate _next; - private readonly ILogger _logger; + private readonly ILogger _logger; public ExceptionMiddleware(RequestDelegate next, ILogger logger) { diff --git a/Server/HetsApi/Model/User.cs b/Server/HetsApi/Model/User.cs index e30cedf53..3faa41dae 100644 --- a/Server/HetsApi/Model/User.cs +++ b/Server/HetsApi/Model/User.cs @@ -1,11 +1,9 @@ using System.Collections.Generic; using HetsData.Dtos; -using HetsData.Entities; -using Newtonsoft.Json; namespace HetsApi.Model { - public class User + public class CurrentUserDto { public int Id { get; set; } public string SmUserId { get; set; } From f0c285207df3521905b455e2a0ac220f5ed1571e Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 10:09:28 -0700 Subject: [PATCH 136/352] Serilog Logging --- Server/HetsApi/HetsApi.csproj | 1 + Server/HetsApi/appsettings.json | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/Server/HetsApi/HetsApi.csproj b/Server/HetsApi/HetsApi.csproj index b3af0bb48..5332a8e75 100644 --- a/Server/HetsApi/HetsApi.csproj +++ b/Server/HetsApi/HetsApi.csproj @@ -33,6 +33,7 @@ + diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index 7e0c2ecc6..e7d922eec 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -107,6 +107,14 @@ "Args": { "configure": [ { "Name": "Console" } ] } + }, + { + "Name": "HetsPostgreSql", + "Args": { + "connectionString": "HETS", + "tableName": "HET_LOG", + "needAutoCreateTable": true + } } ], "Enrich": [ "FromLogContext", "WithMachineName" ] From eac06845c37f89a07725496eb6a59e5a94ce4f22 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 11:39:41 -0700 Subject: [PATCH 137/352] Serilolg-UI --- Server/HetsApi.sln | 6 - Server/HetsApi/HetsApi.csproj | 29 +++-- Server/HetsApi/Startup.cs | 7 ++ Server/HetsApi/appsettings.json | 30 ++++- Server/HetsCommon/HetsCommon.csproj | 6 +- Server/HetsData/HetsData.csproj | 6 +- .../HetsPostgreSqlSink.cs | 68 ---------- ...erConfigurationHetsPostgreSqlExtensions.cs | 117 ------------------ .../Serilog.Sinks.HetsPostgreSql.csproj | 13 -- 9 files changed, 57 insertions(+), 225 deletions(-) delete mode 100644 Server/Serilog.Sinks.HetsPostgreSql/HetsPostgreSqlSink.cs delete mode 100644 Server/Serilog.Sinks.HetsPostgreSql/LoggerConfigurationHetsPostgreSqlExtensions.cs delete mode 100644 Server/Serilog.Sinks.HetsPostgreSql/Serilog.Sinks.HetsPostgreSql.csproj diff --git a/Server/HetsApi.sln b/Server/HetsApi.sln index 32f63eeaf..62da952af 100644 --- a/Server/HetsApi.sln +++ b/Server/HetsApi.sln @@ -12,8 +12,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HetsReport", "HetsReport\He EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HetsBceid", "HetsBceid\HetsBceid.csproj", "{7E21ACC0-6FAF-42F3-8DFF-B281D0183D31}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.HetsPostgreSql", "Serilog.Sinks.HetsPostgreSql\Serilog.Sinks.HetsPostgreSql.csproj", "{D40BF5D4-D549-466A-A9B0-ABDDB80236E2}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,10 +38,6 @@ Global {7E21ACC0-6FAF-42F3-8DFF-B281D0183D31}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E21ACC0-6FAF-42F3-8DFF-B281D0183D31}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E21ACC0-6FAF-42F3-8DFF-B281D0183D31}.Release|Any CPU.Build.0 = Release|Any CPU - {D40BF5D4-D549-466A-A9B0-ABDDB80236E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D40BF5D4-D549-466A-A9B0-ABDDB80236E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D40BF5D4-D549-466A-A9B0-ABDDB80236E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D40BF5D4-D549-466A-A9B0-ABDDB80236E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Server/HetsApi/HetsApi.csproj b/Server/HetsApi/HetsApi.csproj index 5332a8e75..77b609de4 100644 --- a/Server/HetsApi/HetsApi.csproj +++ b/Server/HetsApi/HetsApi.csproj @@ -33,38 +33,41 @@ - - - - - + + + + - + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + + + + + diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index 32df0c341..dd3305d41 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -23,6 +23,8 @@ using AutoMapper; using HetsData.Mappings; using HetsData.Repositories; +using Serilog.Ui.Web; +using Serilog.Ui.PostgreSqlProvider.Extensions; namespace HetsApi { @@ -55,6 +57,8 @@ public void ConfigureServices(IServiceCollection services) var mapper = mappingConfig.CreateMapper(); services.AddSingleton(mapper); + services.AddSerilogUi(options => options.UseNpgSql(connectionString, "het_log")); + // add database context services.AddDbContext(options => options.UseNpgsql(connectionString)); services.AddDbContext(options => options.UseNpgsql(connectionString)); @@ -158,6 +162,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); + + app.UseSerilogUi(); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index e7d922eec..ea0aec2f0 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -94,6 +94,7 @@ "UploadPath": "D:\\Temp\\HETSUploads\\", "ReportsPath": "D:\\Temp\\HETSReports\\", "Serilog": { + "Using": [ "Serilog.Sinks.PostgreSQL.Configuration" ], "MinimumLevel": { "Default": "Information", "Override": { @@ -109,14 +110,39 @@ } }, { - "Name": "HetsPostgreSql", + "Name": "PostgreSQL", "Args": { "connectionString": "HETS", - "tableName": "HET_LOG", + "tableName": "het_log", "needAutoCreateTable": true } } ], "Enrich": [ "FromLogContext", "WithMachineName" ] + }, + "Columns": { + "message": "RenderedMessageColumnWriter", + "message_template": "MessageTemplateColumnWriter", + "level": { + "Name": "LevelColumnWriter", + "Args": { + "renderAsText": true, + "dbType": "Varchar" + } + }, + "timestamp": "TimestampColumnWriter", + "exception": "ExceptionColumnWriter", + "log_event": "LogEventSerializedColumnWriter", + "props_test": { + "Name": "PropertiesColumnWriter", + "Args": { "dbType": "Json" } + }, + "machine_name": { + "Name": "SinglePropertyColumnWriter", + "Args": { + "propertyName": "MachineName", + "writeMethod": "Raw" + } + } } } diff --git a/Server/HetsCommon/HetsCommon.csproj b/Server/HetsCommon/HetsCommon.csproj index 954d5bd15..82a9f95ce 100644 --- a/Server/HetsCommon/HetsCommon.csproj +++ b/Server/HetsCommon/HetsCommon.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/Server/HetsData/HetsData.csproj b/Server/HetsData/HetsData.csproj index fde40ab19..65c921f95 100644 --- a/Server/HetsData/HetsData.csproj +++ b/Server/HetsData/HetsData.csproj @@ -13,9 +13,9 @@ - - - + + + diff --git a/Server/Serilog.Sinks.HetsPostgreSql/HetsPostgreSqlSink.cs b/Server/Serilog.Sinks.HetsPostgreSql/HetsPostgreSqlSink.cs deleted file mode 100644 index d03a21c06..000000000 --- a/Server/Serilog.Sinks.HetsPostgreSql/HetsPostgreSqlSink.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Serilog.Sinks.PostgreSQL; -using System; -using System.Collections.Generic; - -namespace Serilog.Sinks.HetsPostgreSql -{ - public class HetsPostgreSqlSink : PostgreSqlSink - { - /// - /// - /// Initializes a new instance of the class. - /// - /// The connection string. - /// Name of the table. - /// The time to wait between checking for event batches. - /// The format provider. - /// The column options. - /// The maximum number of events to include in a single batch. - /// Enables the copy command to allow batch inserting instead of multiple INSERT commands. - /// Name of the schema. - /// Specifies whether the table should be auto-created if it does not already exist or not. - public HetsPostgreSqlSink( - string connectionString, - string tableName, - TimeSpan period, - IFormatProvider formatProvider = null, - IDictionary columnOptions = null, - int batchSizeLimit = DefaultBatchSizeLimit, - bool useCopy = true, - string schemaName = "", - bool needAutoCreateTable = false) - : base(connectionString, tableName, period, formatProvider, columnOptions, batchSizeLimit, useCopy, schemaName, needAutoCreateTable) - { - - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The connection string. - /// Name of the table. - /// The time to wait between checking for event batches. - /// The format provider. - /// The column options. - /// The maximum number of events to include in a single batch. - /// Maximum number of events in the queue. - /// Enables the copy command to allow batch inserting instead of multiple INSERT commands. - /// Name of the schema. - /// Specifies whether the table should be auto-created if it does not already exist or not. - // ReSharper disable once UnusedMember.Global - public HetsPostgreSqlSink( - string connectionString, - string tableName, - TimeSpan period, - IFormatProvider formatProvider = null, - IDictionary columnOptions = null, - int batchSizeLimit = DefaultBatchSizeLimit, - int queueLimit = DefaultQueueLimit, - bool useCopy = true, - string schemaName = "", - bool needAutoCreateTable = false) - : base(connectionString, tableName, period, formatProvider, columnOptions, batchSizeLimit, queueLimit, useCopy, schemaName, needAutoCreateTable) - { - - } - } -} diff --git a/Server/Serilog.Sinks.HetsPostgreSql/LoggerConfigurationHetsPostgreSqlExtensions.cs b/Server/Serilog.Sinks.HetsPostgreSql/LoggerConfigurationHetsPostgreSqlExtensions.cs deleted file mode 100644 index 57f60ba49..000000000 --- a/Server/Serilog.Sinks.HetsPostgreSql/LoggerConfigurationHetsPostgreSqlExtensions.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -using Serilog.Configuration; -using Serilog.Core; -using Serilog.Events; -using Serilog.Sinks.PostgreSQL; - -using Microsoft.Extensions.Configuration; -using NpgsqlTypes; -using Serilog.Debugging; - -namespace Serilog.Sinks.HetsPostgreSql -{ - /// - /// This class contains the PostgreSQL logger configuration. - /// - [SuppressMessage( - "StyleCop.CSharp.DocumentationRules", - "SA1650:ElementDocumentationMustBeSpelledCorrectly", - Justification = "Reviewed. Suppression is OK here.")] - // ReSharper disable once UnusedMember.Global - public static class LoggerConfigurationHetsPostgreSqlExtensions - { - /// - /// Default time to wait between checking for event batches. - /// - // ReSharper disable once MemberCanBePrivate.Global - public static readonly TimeSpan DefaultPeriod = TimeSpan.FromSeconds(5); - - /// - /// Adds a sink which writes to PostgreSQL table. - /// - /// The logger configuration. - /// The connection string to the database where to store the events. - /// Name of the table to store the events in. - /// Table columns writers - /// The minimum log event level required in order to write an event to the sink. - /// The time to wait between checking for event batches. - /// Supplies culture-specific formatting information, or null. - /// The maximum number of events to include to single batch. - /// A switch allowing the pass-through minimum level to be changed at runtime. - /// If true inserts data via COPY command, otherwise uses INSERT INTO statement - /// Schema name - /// Set if sink should create table - /// Logger configuration, allowing configuration to continue. - [SuppressMessage( - "StyleCop.CSharp.DocumentationRules", - "SA1650:ElementDocumentationMustBeSpelledCorrectly", - Justification = "Reviewed. Suppression is OK here.")] - // ReSharper disable once UnusedMember.Global - public static LoggerConfiguration HetsPostgreSql( - this LoggerSinkConfiguration sinkConfiguration, - string connectionString, - string tableName, - IDictionary columnOptions = null, - LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, - TimeSpan? period = null, - IFormatProvider formatProvider = null, - int batchSizeLimit = PostgreSqlSink.DefaultBatchSizeLimit, - LoggingLevelSwitch levelSwitch = null, - bool useCopy = true, - string schemaName = "", - bool needAutoCreateTable = false, - IConfiguration appConfiguration = null) - { - if (sinkConfiguration == null) - { - throw new ArgumentNullException(nameof(sinkConfiguration)); - } - - period = period ?? DefaultPeriod; - - var connectionStr = GetConnectionString(connectionString, appConfiguration); - - IDictionary columnOpts = new Dictionary - { - { "message", new RenderedMessageColumnWriter(NpgsqlDbType.Text) }, - { "message_template", new MessageTemplateColumnWriter(NpgsqlDbType.Text) }, - { "level", new LevelColumnWriter(true, NpgsqlDbType.Varchar) }, - { "raise_date", new TimestampColumnWriter(NpgsqlDbType.TimestampTz) }, - { "exception", new ExceptionColumnWriter(NpgsqlDbType.Text) }, - { "properties", new LogEventSerializedColumnWriter(NpgsqlDbType.Jsonb) }, - { "props_test", new PropertiesColumnWriter(NpgsqlDbType.Jsonb) }, - { "machine_name", new SinglePropertyColumnWriter("MachineName", PropertyWriteMethod.ToString, NpgsqlDbType.Text, "l") } - }; - - return sinkConfiguration.Sink( - new HetsPostgreSqlSink( - connectionStr, - tableName, - period.Value, - formatProvider, - columnOptions == null ? columnOpts : columnOptions, - batchSizeLimit, - useCopy, - schemaName, - needAutoCreateTable), - restrictedToMinimumLevel, - levelSwitch); - } - - private static string GetConnectionString(string nameOrConnectionString, IConfiguration appConfiguration) - { - // If there is an `=`, we assume this is a raw connection string not a named value - // If there are no `=`, attempt to pull the named value from config - if (nameOrConnectionString.IndexOf('=') > -1) return nameOrConnectionString; - string cs = appConfiguration?.GetConnectionString(nameOrConnectionString); - if (string.IsNullOrEmpty(cs)) - { - SelfLog.WriteLine("HetsPostgreSql sink configured value {0} is not found in ConnectionStrings settings and does not appear to be a raw connection string.", nameOrConnectionString); - } - return cs; - } - } -} \ No newline at end of file diff --git a/Server/Serilog.Sinks.HetsPostgreSql/Serilog.Sinks.HetsPostgreSql.csproj b/Server/Serilog.Sinks.HetsPostgreSql/Serilog.Sinks.HetsPostgreSql.csproj deleted file mode 100644 index f326feb8e..000000000 --- a/Server/Serilog.Sinks.HetsPostgreSql/Serilog.Sinks.HetsPostgreSql.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net5.0 - - - - - - - - - From 5a0da0d6a8f48945f607b340b64cdacbea98aca5 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 12:07:17 -0700 Subject: [PATCH 138/352] Logging --- Server/HetsData/Hangfire/AnnualRollover.cs | 7 +++++-- Server/HetsData/Hangfire/SeniorityCalculator.cs | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Server/HetsData/Hangfire/AnnualRollover.cs b/Server/HetsData/Hangfire/AnnualRollover.cs index f361b8f03..b222b6373 100644 --- a/Server/HetsData/Hangfire/AnnualRollover.cs +++ b/Server/HetsData/Hangfire/AnnualRollover.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using AutoMapper; +using Microsoft.Extensions.Logging; namespace HetsData.Hangfire { @@ -24,13 +25,15 @@ public class AnnualRollover : IAnnualRollover private DbAppMonitorContext _dbContextMonitor; private string _jobId; private IMapper _mapper; + private ILogger _logger; - public AnnualRollover(DbAppContext dbContextMain, DbAppMonitorContext dbContextMonitor, IMapper mapper) + public AnnualRollover(DbAppContext dbContextMain, DbAppMonitorContext dbContextMonitor, ILogger logger, IMapper mapper) { _dbContextMain = dbContextMain; _dbContextMonitor = dbContextMonitor; _jobId = Guid.NewGuid().ToString(); _mapper = mapper; + _logger = logger; } #region Get a District Status record @@ -355,7 +358,7 @@ private HetDistrictStatus GetStatus(int id) private void WriteLog(string message) { - Console.WriteLine($"Annual Rollover[{_jobId}] {message}"); + _logger.LogInformation($"Annual Rollover[{_jobId}] {message}"); } #endregion diff --git a/Server/HetsData/Hangfire/SeniorityCalculator.cs b/Server/HetsData/Hangfire/SeniorityCalculator.cs index 7a22dea7c..e66fe215d 100644 --- a/Server/HetsData/Hangfire/SeniorityCalculator.cs +++ b/Server/HetsData/Hangfire/SeniorityCalculator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.Logging; namespace HetsData.Hangfire { @@ -11,11 +12,13 @@ public class SeniorityCalculator { private DbAppContext _dbContext; private string _jobId; + private ILogger _logger; - public SeniorityCalculator(DbAppContext dbContext) + public SeniorityCalculator(DbAppContext dbContext, ILogger logger) { _dbContext = dbContext; _jobId = Guid.NewGuid().ToString(); + _logger = logger; } /// /// Recalculates seniority with the new sorting rule (sorting by equipment code) for the district equipment types that have the same seniority and received date @@ -58,7 +61,7 @@ public void RecalculateSeniorityList(string seniorityScoringRules) private void WriteLog(string message) { - Console.WriteLine($"Seniority Calculator[{_jobId}] {message}"); + _logger.LogInformation($"Seniority Calculator[{_jobId}] {message}"); } } } From 2a6f83ad651a916962e4bccd208650c825dfb4d7 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 14:46:14 -0700 Subject: [PATCH 139/352] pipeline-cli fix --- .pipeline/package-lock.json | 66 +++++++++---------------------------- .pipeline/package.json | 2 +- 2 files changed, 17 insertions(+), 51 deletions(-) diff --git a/.pipeline/package-lock.json b/.pipeline/package-lock.json index d6e3d2f92..a4867b317 100644 --- a/.pipeline/package-lock.json +++ b/.pipeline/package-lock.json @@ -4,17 +4,26 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@bcgov/pipeline-cli": { - "version": "1.0.1-0", - "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1-0.tgz", - "integrity": "sha512-DXneptaJuG81Vo+GotZaS4M78uOVnocCCzte6UghOkO+Bt8EQ6xlPblITPXiNDCufO7gOnEmB4T/pyh1ZBnvcw==", + "@ychung-mot/pipeline-cli": { + "version": "1.0.1", + "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/eb5f53ab6ea7681b8be275c61ff0827809fdbdbc8642cf2594d624aeb11ae748", + "integrity": "sha512-aHELkmceLlprOwj4fhiZjytpA8oIvuyIgXTLQ0JlAyvwthXh28CbSYDzIWZkyCfXr7XOyzfVJ/4OoMkUCg2fGA==", "requires": { - "debug": "^4.1.0", + "debug": "^4.2.0", "lodash.isempty": "^4.0.1", "lodash.isfunction": "^3.0.9", "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "snakecase-keys": "^3.1.0" + "lodash.isstring": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } } }, "axios": { @@ -25,14 +34,6 @@ "follow-redirects": "^1.10.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, "follow-redirects": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", @@ -63,45 +64,10 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "snakecase-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.1.0.tgz", - "integrity": "sha512-QM038drLbhdOY5HcRQVjO1ZJ1WR7yV5D5TIBzcOB/g3f5HURHhfpYEnvOyzXet8K+MQsgeIUA7O7vn90nAX6EA==", - "requires": { - "map-obj": "^4.0.0", - "to-snake-case": "^1.0.0" - } - }, - "to-no-case": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" - }, - "to-snake-case": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", - "requires": { - "to-space-case": "^1.0.0" - } - }, - "to-space-case": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", - "requires": { - "to-no-case": "^1.0.0" - } } } } diff --git a/.pipeline/package.json b/.pipeline/package.json index 537634455..08e01e0f5 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "^1.0.1-0", + "@ychung-mot/pipeline-cli": "^1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } From 1dc33a52c6d271767f7a4b03084bc90f2e0d276c Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Tue, 20 Jul 2021 15:26:12 -0700 Subject: [PATCH 140/352] pipeline-cli --- .jenkins/.pipeline/package-lock.json | 66 +++++++--------------------- .jenkins/.pipeline/package.json | 2 +- 2 files changed, 17 insertions(+), 51 deletions(-) diff --git a/.jenkins/.pipeline/package-lock.json b/.jenkins/.pipeline/package-lock.json index 10aadbae1..5384ce624 100644 --- a/.jenkins/.pipeline/package-lock.json +++ b/.jenkins/.pipeline/package-lock.json @@ -4,25 +4,26 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@bcgov/pipeline-cli": { - "version": "1.0.1-0", - "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1-0.tgz", - "integrity": "sha512-DXneptaJuG81Vo+GotZaS4M78uOVnocCCzte6UghOkO+Bt8EQ6xlPblITPXiNDCufO7gOnEmB4T/pyh1ZBnvcw==", + "@ychung-mot/pipeline-cli": { + "version": "1.0.1", + "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/eb5f53ab6ea7681b8be275c61ff0827809fdbdbc8642cf2594d624aeb11ae748", + "integrity": "sha512-aHELkmceLlprOwj4fhiZjytpA8oIvuyIgXTLQ0JlAyvwthXh28CbSYDzIWZkyCfXr7XOyzfVJ/4OoMkUCg2fGA==", "requires": { - "debug": "^4.1.0", + "debug": "^4.2.0", "lodash.isempty": "^4.0.1", "lodash.isfunction": "^3.0.9", "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "snakecase-keys": "^3.1.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" + "lodash.isstring": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + } } }, "lodash.isempty": { @@ -45,45 +46,10 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "snakecase-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.1.0.tgz", - "integrity": "sha512-QM038drLbhdOY5HcRQVjO1ZJ1WR7yV5D5TIBzcOB/g3f5HURHhfpYEnvOyzXet8K+MQsgeIUA7O7vn90nAX6EA==", - "requires": { - "map-obj": "^4.0.0", - "to-snake-case": "^1.0.0" - } - }, - "to-no-case": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" - }, - "to-snake-case": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", - "requires": { - "to-space-case": "^1.0.0" - } - }, - "to-space-case": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", - "requires": { - "to-no-case": "^1.0.0" - } } } } diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index c2f445d13..820fd9e1e 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "^1.0.1-0" + "@ychung-mot/pipeline-cli": "^1.0.1" } } From 3e87499930fdd2f0c13d1346d34d41b93b1a20b9 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 21 Jul 2021 07:20:56 -0700 Subject: [PATCH 141/352] bcgov pipeline-cli --- .jenkins/.pipeline/package-lock.json | 24 +++++++++++------------- .jenkins/.pipeline/package.json | 2 +- .pipeline/package-lock.json | 24 +++++++++++------------- .pipeline/package.json | 2 +- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/.jenkins/.pipeline/package-lock.json b/.jenkins/.pipeline/package-lock.json index 5384ce624..746f0f1f1 100644 --- a/.jenkins/.pipeline/package-lock.json +++ b/.jenkins/.pipeline/package-lock.json @@ -4,26 +4,24 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ychung-mot/pipeline-cli": { + "@bcgov/pipeline-cli": { "version": "1.0.1", - "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/eb5f53ab6ea7681b8be275c61ff0827809fdbdbc8642cf2594d624aeb11ae748", - "integrity": "sha512-aHELkmceLlprOwj4fhiZjytpA8oIvuyIgXTLQ0JlAyvwthXh28CbSYDzIWZkyCfXr7XOyzfVJ/4OoMkUCg2fGA==", + "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", + "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", "lodash.isfunction": "^3.0.9", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - } + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" } }, "lodash.isempty": { diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index 820fd9e1e..fe051ec56 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "^1.0.1" + "@bcgov/pipeline-cli": "^1.0.1" } } diff --git a/.pipeline/package-lock.json b/.pipeline/package-lock.json index a4867b317..cd8221df0 100644 --- a/.pipeline/package-lock.json +++ b/.pipeline/package-lock.json @@ -4,26 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ychung-mot/pipeline-cli": { + "@bcgov/pipeline-cli": { "version": "1.0.1", - "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/eb5f53ab6ea7681b8be275c61ff0827809fdbdbc8642cf2594d624aeb11ae748", - "integrity": "sha512-aHELkmceLlprOwj4fhiZjytpA8oIvuyIgXTLQ0JlAyvwthXh28CbSYDzIWZkyCfXr7XOyzfVJ/4OoMkUCg2fGA==", + "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", + "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", "lodash.isfunction": "^3.0.9", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - } } }, "axios": { @@ -34,6 +24,14 @@ "follow-redirects": "^1.10.0" } }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, "follow-redirects": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", diff --git a/.pipeline/package.json b/.pipeline/package.json index 08e01e0f5..0a3a628cc 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "^1.0.1", + "@bcgov/pipeline-cli": "^1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } From 0fdc5da6cc673e89fffb8db980ae12c3f0a5c12f Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 21 Jul 2021 12:38:28 -0700 Subject: [PATCH 142/352] pipeline-cli --- .jenkins/.pipeline/.npmrc | 1 + .jenkins/.pipeline/package.json | 2 +- .pipeline/.npmrc | 1 + .pipeline/package.json | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 .jenkins/.pipeline/.npmrc create mode 100644 .pipeline/.npmrc diff --git a/.jenkins/.pipeline/.npmrc b/.jenkins/.pipeline/.npmrc new file mode 100644 index 000000000..dfd202a12 --- /dev/null +++ b/.jenkins/.pipeline/.npmrc @@ -0,0 +1 @@ +@ychung-mot:registry=https://registry.npmjs.org \ No newline at end of file diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index fe051ec56..568e0f82f 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "^1.0.1" + "@ychung-mot/pipeline-cli": "1.0.1" } } diff --git a/.pipeline/.npmrc b/.pipeline/.npmrc new file mode 100644 index 000000000..dfd202a12 --- /dev/null +++ b/.pipeline/.npmrc @@ -0,0 +1 @@ +@ychung-mot:registry=https://registry.npmjs.org \ No newline at end of file diff --git a/.pipeline/package.json b/.pipeline/package.json index 0a3a628cc..0ef80e200 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "^1.0.1", + "@ychung-mot/pipeline-cli": "1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } From 3102e8fde5442ee67a835f780e2bdb9fc8d20f75 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 21 Jul 2021 12:42:19 -0700 Subject: [PATCH 143/352] bcgov pipeline-cli --- .jenkins/.pipeline/package.json | 2 +- .pipeline/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index 568e0f82f..d780a0ee5 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "1.0.1" + "@bcgov/pipeline-cli": "1.0.1" } } diff --git a/.pipeline/package.json b/.pipeline/package.json index 0ef80e200..a21adec90 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "1.0.1", + "@bcgov/pipeline-cli": "1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } From 2b9fe645b5247354f9617a926649547e154f6d1e Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 21 Jul 2021 13:27:15 -0700 Subject: [PATCH 144/352] pipeline-cli fix --- .jenkins/.pipeline/.npmrc | 3 ++- .jenkins/.pipeline/package-lock.json | 6 +++--- .jenkins/.pipeline/package.json | 2 +- .pipeline/.npmrc | 3 ++- .pipeline/package-lock.json | 6 +++--- .pipeline/package.json | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.jenkins/.pipeline/.npmrc b/.jenkins/.pipeline/.npmrc index dfd202a12..aab629c38 100644 --- a/.jenkins/.pipeline/.npmrc +++ b/.jenkins/.pipeline/.npmrc @@ -1 +1,2 @@ -@ychung-mot:registry=https://registry.npmjs.org \ No newline at end of file +@ychung-mot:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=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 \ No newline at end of file diff --git a/.jenkins/.pipeline/package-lock.json b/.jenkins/.pipeline/package-lock.json index 746f0f1f1..2c4739bf8 100644 --- a/.jenkins/.pipeline/package-lock.json +++ b/.jenkins/.pipeline/package-lock.json @@ -4,10 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@bcgov/pipeline-cli": { + "@ychung-mot/pipeline-cli": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", - "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", + "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/de224f498e615532c692f0082d44e0a1a6aab7cfc01b6efdaf589d2daeab98bc", + "integrity": "sha512-AQNi05nmDitW8lzsIDT9tawezUOfVATr2QMhwvFd6Vq1ijCvp/FHz2ZuOtWGtfKEh1jA5SepHNIH2kVxFS6WgQ==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index d780a0ee5..568e0f82f 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "1.0.1" + "@ychung-mot/pipeline-cli": "1.0.1" } } diff --git a/.pipeline/.npmrc b/.pipeline/.npmrc index dfd202a12..aab629c38 100644 --- a/.pipeline/.npmrc +++ b/.pipeline/.npmrc @@ -1 +1,2 @@ -@ychung-mot:registry=https://registry.npmjs.org \ No newline at end of file +@ychung-mot:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=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 \ No newline at end of file diff --git a/.pipeline/package-lock.json b/.pipeline/package-lock.json index cd8221df0..5793c143c 100644 --- a/.pipeline/package-lock.json +++ b/.pipeline/package-lock.json @@ -4,10 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@bcgov/pipeline-cli": { + "@ychung-mot/pipeline-cli": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", - "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", + "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/de224f498e615532c692f0082d44e0a1a6aab7cfc01b6efdaf589d2daeab98bc", + "integrity": "sha512-AQNi05nmDitW8lzsIDT9tawezUOfVATr2QMhwvFd6Vq1ijCvp/FHz2ZuOtWGtfKEh1jA5SepHNIH2kVxFS6WgQ==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", diff --git a/.pipeline/package.json b/.pipeline/package.json index a21adec90..0ef80e200 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@bcgov/pipeline-cli": "1.0.1", + "@ychung-mot/pipeline-cli": "1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } From 664d76084d1c2d465e233d3ea638560658b66200 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Wed, 21 Jul 2021 14:04:38 -0700 Subject: [PATCH 145/352] DTO replacement fix & rollback pipeline-cli fix --- .jenkins/.pipeline/.npmrc | 2 -- .jenkins/.pipeline/package-lock.json | 6 +++--- .jenkins/.pipeline/package.json | 2 +- .pipeline/package-lock.json | 6 +++--- .pipeline/package.json | 2 +- .../Controllers/EquipmentController.cs | 4 ++-- Server/HetsApi/Controllers/OwnerController.cs | 20 +++++++++++-------- .../Controllers/UserDistrictsController.cs | 8 ++++---- 8 files changed, 26 insertions(+), 24 deletions(-) delete mode 100644 .jenkins/.pipeline/.npmrc diff --git a/.jenkins/.pipeline/.npmrc b/.jenkins/.pipeline/.npmrc deleted file mode 100644 index aab629c38..000000000 --- a/.jenkins/.pipeline/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -@ychung-mot:registry=https://npm.pkg.github.com -//npm.pkg.github.com/:_authToken=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 \ No newline at end of file diff --git a/.jenkins/.pipeline/package-lock.json b/.jenkins/.pipeline/package-lock.json index 2c4739bf8..746f0f1f1 100644 --- a/.jenkins/.pipeline/package-lock.json +++ b/.jenkins/.pipeline/package-lock.json @@ -4,10 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ychung-mot/pipeline-cli": { + "@bcgov/pipeline-cli": { "version": "1.0.1", - "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/de224f498e615532c692f0082d44e0a1a6aab7cfc01b6efdaf589d2daeab98bc", - "integrity": "sha512-AQNi05nmDitW8lzsIDT9tawezUOfVATr2QMhwvFd6Vq1ijCvp/FHz2ZuOtWGtfKEh1jA5SepHNIH2kVxFS6WgQ==", + "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", + "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", diff --git a/.jenkins/.pipeline/package.json b/.jenkins/.pipeline/package.json index 568e0f82f..d780a0ee5 100644 --- a/.jenkins/.pipeline/package.json +++ b/.jenkins/.pipeline/package.json @@ -18,6 +18,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "1.0.1" + "@bcgov/pipeline-cli": "1.0.1" } } diff --git a/.pipeline/package-lock.json b/.pipeline/package-lock.json index 5793c143c..cd8221df0 100644 --- a/.pipeline/package-lock.json +++ b/.pipeline/package-lock.json @@ -4,10 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ychung-mot/pipeline-cli": { + "@bcgov/pipeline-cli": { "version": "1.0.1", - "resolved": "https://npm.pkg.github.com/download/@ychung-mot/pipeline-cli/1.0.1/de224f498e615532c692f0082d44e0a1a6aab7cfc01b6efdaf589d2daeab98bc", - "integrity": "sha512-AQNi05nmDitW8lzsIDT9tawezUOfVATr2QMhwvFd6Vq1ijCvp/FHz2ZuOtWGtfKEh1jA5SepHNIH2kVxFS6WgQ==", + "resolved": "https://registry.npmjs.org/@bcgov/pipeline-cli/-/pipeline-cli-1.0.1.tgz", + "integrity": "sha512-nVLTWDFGXymtPCupj+shMv1cZAl9QfFBKVoj80lSxbOdDqO/VW3Z1X9/DiNyiOqO1IS9k7mMcexBXF1Eu4WhXA==", "requires": { "debug": "^4.2.0", "lodash.isempty": "^4.0.1", diff --git a/.pipeline/package.json b/.pipeline/package.json index 0ef80e200..a21adec90 100644 --- a/.pipeline/package.json +++ b/.pipeline/package.json @@ -18,7 +18,7 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@ychung-mot/pipeline-cli": "1.0.1", + "@bcgov/pipeline-cli": "1.0.1", "axios": "^0.21.1", "lodash": "^4.17.21" } diff --git a/Server/HetsApi/Controllers/EquipmentController.cs b/Server/HetsApi/Controllers/EquipmentController.cs index 6c0be0a22..ac2a340b9 100644 --- a/Server/HetsApi/Controllers/EquipmentController.cs +++ b/Server/HetsApi/Controllers/EquipmentController.cs @@ -1154,7 +1154,7 @@ public virtual ActionResult> EquipmentIdHistoryGet([FromRoute]int [HttpPost] [Route("{id}/history")] [RequiresPermission(HetPermission.Login, HetPermission.WriteAccess)] - public virtual ActionResult> EquipmentIdHistoryPost([FromRoute]int id, [FromBody]HetHistory item) + public virtual ActionResult> EquipmentIdHistoryPost([FromRoute]int id, [FromBody]History item) { bool exists = _context.HetEquipments.Any(a => a.EquipmentId == id); @@ -1164,7 +1164,7 @@ public virtual ActionResult> EquipmentIdHistoryPost([FromRoute]int { HistoryId = 0, HistoryText = item.HistoryText, - CreatedDate = item.CreatedDate, + CreatedDate = DateTime.UtcNow, EquipmentId = id }; diff --git a/Server/HetsApi/Controllers/OwnerController.cs b/Server/HetsApi/Controllers/OwnerController.cs index 5417eef67..8d1a82ca0 100644 --- a/Server/HetsApi/Controllers/OwnerController.cs +++ b/Server/HetsApi/Controllers/OwnerController.cs @@ -927,41 +927,45 @@ public virtual ActionResult> OwnersIdEquipmentGet([FromRoute] [HttpPut] [Route("{id}/equipment")] [RequiresPermission(HetPermission.Login, HetPermission.WriteAccess)] - public virtual ActionResult> OwnersIdEquipmentPut([FromRoute]int id, [FromBody]HetEquipment[] items) + public virtual ActionResult> OwnersIdEquipmentPut([FromRoute]int id, [FromBody]EquipmentDto[] items) { bool exists = _context.HetOwners.Any(a => a.OwnerId == id); // not found if (!exists || items == null) return new NotFoundObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration))); + var entities = new List(); + // adjust the incoming list for (int i = 0; i < items.Length; i++) { - HetEquipment item = items[i]; + var item = items[i]; if (item != null) { DateTime lastVerifiedDate = item.LastVerifiedDate; - bool equipmentExists = _context.HetEquipments.Any(x => x.EquipmentId == item.EquipmentId); + bool equipmentExists = _context.HetEquipments + .Any(x => x.EquipmentId == item.EquipmentId && item.OwnerId == id); if (equipmentExists) { - items[i] = _context.HetEquipments + var equipment = _context.HetEquipments .First(x => x.EquipmentId == item.EquipmentId); if (items[i].LastVerifiedDate != lastVerifiedDate) { items[i].LastVerifiedDate = lastVerifiedDate; - _context.HetEquipments.Update(items[i]); } + + entities.Add(equipment); } } } _context.SaveChanges(); - return new ObjectResult(new HetsResponse(_mapper.Map>(items))); + return new ObjectResult(new HetsResponse(_mapper.Map>(entities))); } #endregion @@ -1513,7 +1517,7 @@ public virtual ActionResult> OwnersIdHistoryGet([FromRoute]int id, [HttpPost] [Route("{id}/history")] [RequiresPermission(HetPermission.Login, HetPermission.WriteAccess)] - public virtual ActionResult> OwnersIdHistoryPost([FromRoute]int id, [FromBody]HetHistory item) + public virtual ActionResult> OwnersIdHistoryPost([FromRoute]int id, [FromBody]History item) { bool exists = _context.HetOwners.Any(a => a.OwnerId == id); @@ -1523,7 +1527,7 @@ public virtual ActionResult> OwnersIdHistoryPost([FromRoute]int id { HistoryId = 0, HistoryText = item.HistoryText, - CreatedDate = item.CreatedDate, + CreatedDate = DateTime.UtcNow, OwnerId = id }; diff --git a/Server/HetsApi/Controllers/UserDistrictsController.cs b/Server/HetsApi/Controllers/UserDistrictsController.cs index cc9ccc68d..9a42f2277 100644 --- a/Server/HetsApi/Controllers/UserDistrictsController.cs +++ b/Server/HetsApi/Controllers/UserDistrictsController.cs @@ -100,7 +100,7 @@ public virtual ActionResult> UserDistrictsIdDeletePost([Fr [HttpPost] [Route("{id}")] [RequiresPermission(HetPermission.UserManagement, HetPermission.WriteAccess)] - public virtual ActionResult> UserDistrictsIdPost([FromRoute]int id, [FromBody]HetUserDistrict item) + public virtual ActionResult> UserDistrictsIdPost([FromRoute]int id, [FromBody]UserDistrictDto item) { // not found if (id != item.UserDistrictId) return new NotFoundObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration))); @@ -202,7 +202,7 @@ public virtual ActionResult> UserDistrictsIdPost([FromRout { if (item.User != null) { - item.User = _context.HetUsers.FirstOrDefault(a => a.UserId == item.User.UserId); + var user = _context.HetUsers.FirstOrDefault(a => a.UserId == item.User.UserId); } else { @@ -212,7 +212,7 @@ public virtual ActionResult> UserDistrictsIdPost([FromRout if (item.District != null) { - item.District = _context.HetDistricts.FirstOrDefault(a => a.DistrictId == item.District.DistrictId); + var district = _context.HetDistricts.FirstOrDefault(a => a.DistrictId == item.District.DistrictId); } else { @@ -252,7 +252,7 @@ public virtual ActionResult> UserDistrictsIdPost([FromRout } } - _context.HetUserDistricts.Add(item); + _context.HetUserDistricts.Add(_mapper.Map(item)); } } From 323e50fc01ba4745147d920c44dfa3df18fa1667 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 22 Jul 2021 07:37:29 -0700 Subject: [PATCH 146/352] Serilog level to integer --- Server/HetsApi/appsettings.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Server/HetsApi/appsettings.json b/Server/HetsApi/appsettings.json index ea0aec2f0..b232e6e85 100644 --- a/Server/HetsApi/appsettings.json +++ b/Server/HetsApi/appsettings.json @@ -126,8 +126,7 @@ "level": { "Name": "LevelColumnWriter", "Args": { - "renderAsText": true, - "dbType": "Varchar" + "renderAsText": false } }, "timestamp": "TimestampColumnWriter", From 83b1ef79bc4e2d330b141f0cd0d4429f7cb55143 Mon Sep 17 00:00:00 2001 From: Young-Jin Chung Date: Thu, 22 Jul 2021 08:56:15 -0700 Subject: [PATCH 147/352] QuerySplittingBehavior.SplitQuery --- Server/HetsApi/Startup.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Server/HetsApi/Startup.cs b/Server/HetsApi/Startup.cs index dd3305d41..622acea9c 100644 --- a/Server/HetsApi/Startup.cs +++ b/Server/HetsApi/Startup.cs @@ -25,6 +25,7 @@ using HetsData.Repositories; using Serilog.Ui.Web; using Serilog.Ui.PostgreSqlProvider.Extensions; +using Microsoft.EntityFrameworkCore.Diagnostics; namespace HetsApi { @@ -60,8 +61,18 @@ public void ConfigureServices(IServiceCollection services) services.AddSerilogUi(options => options.UseNpgSql(connectionString, "het_log")); // add database context - services.AddDbContext(options => options.UseNpgsql(connectionString)); - services.AddDbContext(options => options.UseNpgsql(connectionString)); + services.AddDbContext(options => + { + options.UseNpgsql(connectionString, o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)); + options.ConfigureWarnings(o => o.Ignore(CoreEventId.RowLimitingOperationWithoutOrderByWarning)); + }); + + services.AddDbContext(options => + { + options.UseNpgsql(connectionString, o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)); + options.ConfigureWarnings(o => o.Ignore(CoreEventId.RowLimitingOperationWithoutOrderByWarning)); + }); + services.AddScoped(); services From 55f8d50170978e36090dbbf750bf8b8a3e3d8ce5 Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Tue, 29 Jun 2021 10:30:41 -0700 Subject: [PATCH 148/352] updating react-bootstrap. Fixing navbar --- client/src/js/views/TopNav.jsx | 400 +++++++++++++++++---------------- client/src/sass/header.scss | 9 +- 2 files changed, 212 insertions(+), 197 deletions(-) diff --git a/client/src/js/views/TopNav.jsx b/client/src/js/views/TopNav.jsx index 1a6086c9e..39f23603e 100644 --- a/client/src/js/views/TopNav.jsx +++ b/client/src/js/views/TopNav.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; +import { withRouter, NavLink } from 'react-router-dom'; import _ from 'lodash'; import { Navbar, @@ -84,240 +84,254 @@ class TopNav extends React.Component { return ( ); } diff --git a/client/src/sass/header.scss b/client/src/sass/header.scss index 7f07ff59c..e3980c94f 100644 --- a/client/src/sass/header.scss +++ b/client/src/sass/header.scss @@ -1,4 +1,4 @@ -@import "./mixins.scss"; +@import './mixins.scss'; $nav-background-color: #38598a; $nav-background-color-test: #448a38; @@ -98,16 +98,17 @@ $nav-active-background-color-uat: #db976d; .navbar-nav > li > a:focus { color: #fff; } + .navbar-nav > li > .dropdown-menu { color: #fff; background-color: $nav-background-color; font-size: 13px; } - .navbar-nav > li > .dropdown-menu > li > a { + .navbar-nav > li > .dropdown-menu > a { color: #fff; } - .navbar-nav > li > .dropdown-menu > li > a:hover, - .navbar-nav > li > .dropdown-menu > li > a:focus { + .navbar-nav > li > .dropdown-menu > a:hover, + .navbar-nav > li > .dropdown-menu > a:focus { color: #fff; background-color: $nav-active-background-color; text-decoration: underline; From 067f58207f5943e1e22fb03cc320bb4752c7ecaa Mon Sep 17 00:00:00 2001 From: DSoLetsDev Date: Tue, 29 Jun 2021 11:49:01 -0700 Subject: [PATCH 149/352] fixing profile button. Needed to parseInt to find matching district --- client/src/js/components/DropdownControl.jsx | 64 +++++++++----------- client/src/js/views/TopNav.jsx | 8 +-- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/client/src/js/components/DropdownControl.jsx b/client/src/js/components/DropdownControl.jsx index 97f41f36c..a30667e02 100644 --- a/client/src/js/components/DropdownControl.jsx +++ b/client/src/js/components/DropdownControl.jsx @@ -1,7 +1,7 @@ -import PropTypes from "prop-types"; -import React from "react"; -import { Dropdown, MenuItem, Popover, OverlayTrigger } from "react-bootstrap"; -import _ from "lodash"; +import PropTypes from 'prop-types'; +import React from 'react'; +import { Dropdown, MenuItem, Popover, OverlayTrigger } from 'react-bootstrap'; +import _ from 'lodash'; class DropdownControl extends React.Component { static propTypes = { @@ -38,11 +38,11 @@ class DropdownControl extends React.Component { super(props); this.state = { - simple: _.has(props, "title"), + simple: _.has(props, 'title'), - selectedId: props.selectedId || "", + selectedId: props.selectedId || '', title: this.buildTitle(props.title), - fieldName: props.fieldName || "name", + fieldName: props.fieldName || 'name', open: false, }; } @@ -56,15 +56,12 @@ class DropdownControl extends React.Component { } } - componentWillReceiveProps(nextProps) { + componentDidUpdate(nextProps) { if (!_.isEqual(nextProps.items, this.props.items)) { var items = nextProps.items || []; this.setState({ items: items, - title: this.buildTitle( - this.state.simple ? this.state.title : this.state.selectedId, - items - ), + title: this.buildTitle(this.state.simple ? this.state.title : this.state.selectedId, items), }); } else if (nextProps.selectedId !== this.props.selectedId) { this.setState({ @@ -87,7 +84,7 @@ class DropdownControl extends React.Component { } } } - return this.props.placeholder || "Select item"; + return this.props.placeholder || 'Select item'; }; itemSelected = (keyEvent) => { @@ -95,14 +92,12 @@ class DropdownControl extends React.Component { if (!this.props.staticTitle) { this.setState({ - selectedId: keyEvent || "", + selectedId: keyEvent || '', title: this.buildTitle(keyEvent, this.props.items), }); } - var selected = this.state.simple - ? keyEvent - : _.find(this.props.items, { id: keyEvent }); + var selected = this.state.simple ? keyEvent : _.find(this.props.items, { id: keyEvent }); // Send selected item to change listener if (this.props.onSelect) { @@ -124,37 +119,35 @@ class DropdownControl extends React.Component { render() { var props = _.omit( this.props, - "updateState", - "onSelect", - "items", - "selectedId", - "blankLine", - "fieldName", - "placeholder", - "staticTitle" + 'updateState', + 'onSelect', + 'items', + 'selectedId', + 'blankLine', + 'fieldName', + 'placeholder', + 'staticTitle' ); return ( - - + {this.state.title} + {this.props.items.length > 0 && (