From 257f3c354f73d754e6f0169dab1cede9a797550b Mon Sep 17 00:00:00 2001 From: Luka Romih Date: Tue, 6 Dec 2022 14:55:46 +0100 Subject: [PATCH] Initial commit --- .dockerignore | 24 + .eslintignore | 1 + .eslintrc.yml | 18 + .gitattributes | 262 + .gitignore | 5 + .prettierignore | 3 + .prettierrc.yml | 19 + README.md | 5 + concordancer/Dockerfile | 6 + dev/.env | 26 + dev/README - old.md | 25 + dev/razvojne_konvencije.md | 51 + docker-compose.prod.yml | 150 + docker-compose.yml | 173 + express/Dockerfile | 26 + express/Dockerfile.prod | 22 + express/app.js | 105 + express/bin/www | 106 + express/config/helmet.js | 41 + express/config/keys.js | 11 + express/config/settings.js | 22 + express/controllers/api/v1/comments.js | 57 + express/controllers/api/v1/consultancy.js | 321 + express/controllers/api/v1/demo-paginacija.js | 15 + express/controllers/api/v1/dictionaries.js | 189 + express/controllers/api/v1/extraction.js | 328 + .../controllers/api/v1/inter_instance_sync.js | 18 + express/controllers/api/v1/portals.js | 63 + express/controllers/api/v1/search.js | 230 + express/controllers/api/v1/system.js | 16 + express/controllers/api/v1/users.js | 35 + express/controllers/consultancy.js | 408 + express/controllers/demo-paginacija.js | 17 + express/controllers/dictionaries.js | 699 ++ express/controllers/extraction-poc.js | 150 + express/controllers/extraction.js | 156 + express/controllers/helpers/dictionary.js | 211 + express/controllers/helpers/extraction.js | 11 + .../search-filter-data-suggestion-importer.js | 34 + express/controllers/index.js | 386 + express/controllers/portals.js | 140 + express/controllers/users.js | 142 + express/middleware/auth.js | 113 + express/middleware/index.js | 6 + express/middleware/session.js | 54 + express/middleware/settings.js | 23 + express/middleware/user.js | 95 + express/models/batch.js | 119 + express/models/cache.js | 18 + express/models/comment.js | 432 ++ express/models/consultancy-entry.js | 754 ++ express/models/db.js | 65 + express/models/demo-paginacija.js | 49 + express/models/dictionary.js | 1373 ++++ express/models/domain.js | 79 + express/models/email.js | 40 + express/models/entry.js | 650 ++ express/models/extraction.js | 501 ++ .../models/helpers/dictionary/import-file.js | 282 + express/models/helpers/dictionary/index.js | 196 + express/models/helpers/extraction.js | 62 + express/models/helpers/index.js | 73 + express/models/helpers/portal/index.js | 67 + .../search/generate-query/consultancy/all.js | 40 + .../generate-query/consultancy/phrase.js | 76 + .../generate-query/consultancy/wildcard.js | 70 + .../generate-query/consultancy/words.js | 85 + .../search/generate-query/editor/all.js | 129 + .../search/generate-query/editor/exists.js | 103 + .../search/generate-query/editor/phrase.js | 76 + .../search/generate-query/editor/wildcard.js | 62 + .../search/generate-query/editor/words.js | 82 + .../helpers/search/generate-query/index.js | 183 + .../generate-query/main/aggregate-all.js | 42 + .../generate-query/main/aggregate-phrase.js | 80 + .../generate-query/main/aggregate-wildcard.js | 68 + .../generate-query/main/aggregate-word.js | 80 + .../helpers/search/generate-query/main/all.js | 64 + .../search/generate-query/main/phrase.js | 247 + .../search/generate-query/main/wildcard.js | 207 + .../search/generate-query/main/word-multi.js | 233 + .../search/generate-query/main/word-single.js | 262 + express/models/helpers/search/index.js | 225 + express/models/helpers/user/index.js | 42 + express/models/inter_instance_sync.js | 109 + express/models/portal.js | 486 ++ express/models/search-engine.js | 244 + express/models/system/eurotermbank.js | 183 + express/models/user.js | 470 ++ express/package-lock.json | 6681 +++++++++++++++++ express/package.json | 47 + .../documents/Podrocja_TP_2022-11-28.pdf | Bin 0 -> 154943 bytes express/public/documents/RSDO_smernice.pdf | Bin 0 -> 484016 bytes express/public/images/Component.svg | 5 + express/public/images/EKP.svg | 27 + express/public/images/Ekran.png | Bin 0 -> 86655 bytes express/public/images/Filtri.png | Bin 0 -> 30136 bytes express/public/images/Iskalni_zadetki.png | Bin 0 -> 91915 bytes express/public/images/Napredno_iskanje.png | Bin 0 -> 10126 bytes express/public/images/Neveljavno.png | Bin 0 -> 9372 bytes express/public/images/Vnosno_polje.png | Bin 0 -> 2908 bytes .../public/images/admin-button-gray-bg.svg | 8 + express/public/images/alert-circle-modal.svg | 7 + express/public/images/alert-circle.svg | 5 + .../public/images/alert-triangle-dark-red.svg | 5 + express/public/images/alert-triangle.svg | 5 + express/public/images/areas.svg | 8 + express/public/images/arrow_drop_down.svg | 10 + express/public/images/arrow_drop_up.svg | 10 + express/public/images/book-colorized.svg | 4 + express/public/images/book-open-blue.svg | 4 + express/public/images/book-open-white.svg | 4 + express/public/images/book-open.svg | 4 + express/public/images/book-white.svg | 4 + express/public/images/book.svg | 4 + .../public/images/burger-menu-button-icon.svg | 6 + express/public/images/check-circle.svg | 4 + express/public/images/chevron-double-left.svg | 16 + .../public/images/chevron-double-right.svg | 16 + express/public/images/chevron-down-darker.svg | 3 + express/public/images/chevron-down.svg | 3 + express/public/images/chevron-left-blue.svg | 3 + express/public/images/chevron-left.svg | 3 + express/public/images/chevron-right-2.svg | 3 + express/public/images/chevron-right.svg | 3 + express/public/images/chevrons-left.svg | 4 + express/public/images/clock.svg | 4 + express/public/images/cog-blue.svg | 4 + express/public/images/cog.svg | 4 + express/public/images/comment.svg | 3 + express/public/images/copy.svg | 4 + express/public/images/download.svg | 5 + express/public/images/dropdown.svg | 3 + express/public/images/edit-blue.svg | 4 + express/public/images/edit.svg | 4 + .../images/exclamation-triangle-red.svg | 5 + express/public/images/external-link-white.svg | 5 + express/public/images/external-link.svg | 5 + express/public/images/eye-off.svg | 11 + express/public/images/eye.svg | 4 + express/public/images/favicon.ico | Bin 0 -> 1150 bytes .../public/images/fi_arrow-right-circle.svg | 5 + express/public/images/fi_blue-calendar.svg | 6 + express/public/images/fi_calendar-white.svg | 6 + express/public/images/fi_calendar.svg | 6 + express/public/images/fi_check-circle.svg | 4 + express/public/images/fi_copy.svg | 4 + express/public/images/fi_copy_border.svg | 4 + express/public/images/fi_corner-down-left.svg | 4 + express/public/images/fi_down_left.svg | 4 + express/public/images/fi_download.svg | 5 + express/public/images/fi_folder.svg | 3 + express/public/images/fi_save.svg | 5 + express/public/images/fi_upload.svg | 5 + express/public/images/fi_x-square.svg | 5 + express/public/images/format_bold.svg | 3 + express/public/images/format_italic.svg | 3 + express/public/images/globe.svg | 5 + express/public/images/gray-clock.svg | 4 + .../images/help-amebis-logo-pug-demo.png | Bin 0 -> 11406 bytes express/public/images/icon-user-x.svg | 101 + express/public/images/icon-user.svg | 3 + express/public/images/keyboard.svg | 6 + express/public/images/left-arrow.svg | 3 + express/public/images/line-break.svg | 3 + express/public/images/link.svg | 4 + express/public/images/list.svg | 8 + express/public/images/lock-gray.svg | 6 + express/public/images/lock.svg | 4 + express/public/images/log-out.svg | 5 + express/public/images/logo.png | Bin 0 -> 11023 bytes express/public/images/mc-hyperlink.svg | 3 + .../public/images/message-square-black.svg | 5 + express/public/images/message-square.svg | 5 + express/public/images/printer.svg | 5 + express/public/images/profile-loggedin.svg | 4 + express/public/images/profile.svg | 3 + express/public/images/quote-marks.svg | 3 + express/public/images/radio-button.svg | 3 + express/public/images/red-trash-icon.svg | 6 + express/public/images/refresh-ccw.svg | 12 + express/public/images/rsmzk.svg | 22 + express/public/images/search-error.svg | 6 + express/public/images/search.svg | 4 + express/public/images/search_blue.svg | 4 + express/public/images/share-2.svg | 7 + express/public/images/sliders.svg | 11 + .../public/images/square-checkbox-solid.svg | 4 + express/public/images/square-minus.svg | 80 + express/public/images/star-blue.svg | 3 + express/public/images/star.svg | 3 + express/public/images/statistics-blue.svg | 5 + express/public/images/statistics.svg | 5 + express/public/images/subscript.svg | 3 + express/public/images/superscript.svg | 3 + express/public/images/threedots.svg | 57 + express/public/images/trash-2.svg | 6 + express/public/images/u_comment-alt.svg | 3 + express/public/images/u_edit-alt.svg | 3 + express/public/images/u_redo.svg | 3 + express/public/images/user-gray.svg | 4 + express/public/images/user.svg | 4 + express/public/images/users-blue.svg | 6 + express/public/images/users.svg | 6 + express/public/images/valid.svg | 3 + express/public/images/vector.svg | 8 + express/public/images/x-black.svg | 4 + express/public/images/x-checkbox.svg | 4 + express/public/images/x-circle-blue.svg | 5 + express/public/images/x-circle-red.svg | 5 + express/public/images/x-circle.svg | 5 + express/public/images/x-gray.svg | 4 + express/public/images/x.svg | 4 + express/public/images/x_red.svg | 4 + express/public/javascripts/admin-portals.js | 222 + express/public/javascripts/admin.js | 1300 ++++ .../javascripts/collapsable-comments.js | 29 + express/public/javascripts/comments.js | 651 ++ .../public/javascripts/consultancy-edit.js | 71 + .../javascripts/consultancy-handle-unsaved.js | 6 + .../consultancy-search-mechanism.js | 67 + express/public/javascripts/consultancy.js | 440 ++ express/public/javascripts/demo-paginacija.js | 172 + express/public/javascripts/dictionaries.js | 2697 +++++++ .../dictionary-import-extraction.js | 72 + .../javascripts/extraction-files-edit.js | 163 + express/public/javascripts/extraction-list.js | 33 + .../public/javascripts/extraction-oss-edit.js | 79 + .../javascripts/extraction-poc-files-edit.js | 128 + .../public/javascripts/extraction-poc-list.js | 22 + .../javascripts/extraction-poc-oss-edit.js | 95 + .../extraction-poc-term-candidates.js | 144 + .../javascripts/extraction-term-candidates.js | 40 + express/public/javascripts/extraction.js | 239 + express/public/javascripts/globals.js | 1 + express/public/javascripts/help.js | 81 + .../public/javascripts/login-and-register.js | 281 + .../public/javascripts/main-sreach-utils.js | 327 + express/public/javascripts/mixed-content.js | 103 + .../javascripts/pagination-extensions.js | 133 + express/public/javascripts/results-index.js | 97 + express/public/javascripts/scripts.js | 1113 +++ .../public/javascripts/search-dictionary.js | 263 + .../javascripts/search-results-admin.js | 12 + .../javascripts/search-results-content.js | 8 + express/public/javascripts/search-results.js | 553 ++ express/public/javascripts/select.js | 206 + .../javascripts/side-menu-filter-languages.js | 433 ++ express/public/javascripts/tooltip-helper.js | 110 + .../trusted-types-default-policy.js | 14 + express/public/javascripts/utils.js | 259 + .../public/sass/common/_basic-includes.scss | 8 + .../sass/common/_comments-includes.scss | 6 + express/public/sass/common/_common.scss | 519 ++ .../sass/common/_dictionaries-includes.scss | 5 + .../sass/common/_index-definitions.scss | 458 ++ express/public/sass/common/_keyboard.scss | 72 + .../public/sass/common/_material-input.scss | 152 + express/public/sass/common/_mixins.scss | 0 .../public/sass/components/_admin-main.scss | 156 + .../sass/components/_admin-side-menu.scss | 251 + .../sass/components/_comments-main.scss | 457 ++ .../sass/components/_consultancy-main.scss | 289 + .../components/_content-header-section.scss | 276 + .../public/sass/components/_content-main.scss | 15 + .../sass/components/_content-side-menu.scss | 561 ++ .../sass/components/_dictionaries-main.scss | 910 +++ .../sass/components/_extraction-main.scss | 204 + express/public/sass/components/_footer.scss | 7 + .../sass/components/_header-section.scss | 547 ++ express/public/sass/components/_help.scss | 262 + .../sass/components/_mixed-content.scss | 30 + .../public/sass/components/_notification.scss | 1 + .../public/sass/components/_side-menu.scss | 80 + express/public/sass/components/_toolbar.scss | 236 + express/public/sass/components/_tooltips.scss | 31 + .../components/search-filter/_res-panel.scss | 295 + .../search-filter/_result-detail.scss | 63 + .../_search-filter-advanced-popup.scss | 273 + .../search-filter/_search-filter-modal.scss | 204 + .../_search-filter-navigation.scss | 221 + .../sass/login-signup/_login-signup.scss | 253 + express/public/sass/style.scss | 33 + express/public/sass/text/_text-styles.scss | 183 + express/public/sass/variables/_variables.scss | 47 + express/routes/admin.js | 121 + express/routes/api/index.js | 13 + express/routes/api/v1/comments.js | 32 + express/routes/api/v1/consultancy.js | 77 + express/routes/api/v1/demo-paginacija.js | 7 + express/routes/api/v1/dictionaries.js | 35 + express/routes/api/v1/entries.js | 33 + express/routes/api/v1/extraction.js | 54 + express/routes/api/v1/index.js | 24 + express/routes/api/v1/portals.js | 34 + express/routes/api/v1/search.js | 20 + express/routes/api/v1/system.js | 23 + express/routes/api/v1/users.js | 19 + express/routes/consultancy.js | 34 + express/routes/dictionaries.js | 130 + express/routes/extraction-poc.js | 27 + express/routes/extraction.js | 61 + express/routes/index.js | 116 + express/scheduled/batch_update_linked.js | 661 ++ express/scheduled/crontab | 4 + express/scheduled/entrypoint.sh | 7 + express/utils/index.js | 10 + express/views/common/footer.pug | 35 + .../common/main-navigation-without-search.pug | 34 + express/views/common/main-navigation.pug | 18 + .../views/common/navigation-search-mixin.pug | 60 + express/views/common/side-menu-fake.pug | 6 + .../views/common/side-menu-mixin-admin.pug | 265 + .../common/side-menu-mixin-consultancy.pug | 90 + .../common/side-menu-mixin-dictionaries.pug | 128 + .../admin/admin-main-panel-content.pug | 0 .../components/admin/admin-navigation.pug | 40 + .../admin/consultancy-item-admin.pug | 123 + .../consultancy/consultancy-item.pug | 17 + .../components/dictionary/dictionary-list.pug | 38 + .../components/login-signup/login-signup.pug | 231 + .../main-panel/generic-main-panel-header.pug | 13 + .../main-panel/implementations/one-button.pug | 6 + .../implementations/two-buttons.pug | 8 + .../components/navigation/edit-navigation.pug | 0 .../main-navigation-right-mixin.pug | 81 + .../advanced-search-modal-area-only.pug | 43 + .../advanced-search-modal.pug | 104 + .../search-and-filter/inline-search.pug | 6 + .../search-and-filter/result-item.pug | 86 + .../result-panel-decision-mixin.pug | 16 + .../search-and-filter/result-panel.pug | 34 + .../search-and-filter/search-filter-modal.pug | 38 + .../search-filter-navigation-mixin.pug | 62 + .../search-filter-navigation.pug | 77 + .../search-with-primary-domain-filter.pug | 54 + .../search-and-filter/small-device-search.pug | 29 + express/views/email/consultancy-assigned.pug | 1 + .../email/consultancy-creation-notify.pug | 1 + .../views/email/consultancy-item-review.pug | 1 + .../views/email/dictionary-status-change.pug | 13 + express/views/email/extraction-done.pug | 2 + express/views/email/user-activation.pug | 4 + express/views/error.pug | 6 + express/views/extraction-poc/docs-edit.pug | 27 + express/views/extraction-poc/edit-oss.pug | 128 + express/views/extraction-poc/edit-own.pug | 20 + express/views/extraction-poc/list.pug | 44 + .../views/extraction-poc/stop-terms-edit.pug | 22 + .../views/extraction-poc/term-candidates.pug | 23 + express/views/layout.pug | 91 + .../views/pages/admin-dict-structure-demo.pug | 20 + express/views/pages/admin.pug | 21 + express/views/pages/admin/areas.pug | 86 + express/views/pages/admin/comments.pug | 22 + .../views/pages/admin/connections-list.pug | 112 + .../views/pages/admin/dictionaries-list.pug | 61 + .../views/pages/admin/dictionary-advanced.pug | 64 + .../views/pages/admin/dictionary-comments.pug | 23 + .../pages/admin/dictionary-description.pug | 246 + .../pages/admin/dictionary-domain-labels.pug | 110 + .../views/pages/admin/dictionary-export.pug | 253 + .../admin/dictionary-extraction-import.pug | 66 + .../views/pages/admin/dictionary-import.pug | 156 + .../pages/admin/dictionary-structure.pug | 23 + .../views/pages/admin/dictionary-users.pug | 282 + express/views/pages/admin/new-connection.pug | 87 + .../admin/portal-consultancy-settings.pug | 81 + express/views/pages/admin/portal-edit.pug | 90 + .../views/pages/admin/portal-list-dict.pug | 53 + express/views/pages/admin/portal.pug | 117 + .../admin/portals-all-linked-dictionaries.pug | 56 + .../pages/admin/settings-dictionaries.pug | 207 + express/views/pages/admin/user-edit.pug | 145 + express/views/pages/admin/user-list.pug | 50 + express/views/pages/admin/user-portals.pug | 114 + .../consultancy-admin-inheritable-module.pug | 64 + .../consultancy/admin/dialogs/assign.pug | 51 + .../pages/consultancy/admin/dialogs/share.pug | 60 + .../views/pages/consultancy/admin/edit.pug | 149 + .../pages/consultancy/admin/in-progress.pug | 6 + .../views/pages/consultancy/admin/index.pug | 1 + .../pages/consultancy/admin/prepared.pug | 6 + .../pages/consultancy/admin/published.pug | 6 + .../pages/consultancy/admin/rejected.pug | 6 + .../pages/consultancy/admin/statistics.pug | 57 + .../views/pages/consultancy/admin/users.pug | 103 + express/views/pages/consultancy/ask.pug | 132 + express/views/pages/consultancy/index.pug | 38 + .../views/pages/consultancy/item-details.pug | 49 + express/views/pages/consultancy/search.pug | 7 + express/views/pages/demo-paginacija.pug | 37 + express/views/pages/dictionaries/advanced.pug | 56 + express/views/pages/dictionaries/content.pug | 47 + .../views/pages/dictionaries/description.pug | 190 + .../dictionaries/dictionary-comments.pug | 22 + express/views/pages/dictionaries/dictlist.pug | 48 + .../pages/dictionaries/domain-labels.pug | 112 + express/views/pages/dictionaries/export.pug | 252 + .../pages/dictionaries/extraction-import.pug | 66 + express/views/pages/dictionaries/import.pug | 154 + express/views/pages/dictionaries/list.pug | 81 + express/views/pages/dictionaries/new.pug | 21 + .../views/pages/dictionaries/structure.pug | 23 + express/views/pages/dictionaries/users.pug | 283 + express/views/pages/extraction/docs-edit.pug | 59 + express/views/pages/extraction/edit-oss.pug | 364 + express/views/pages/extraction/edit-own.pug | 69 + express/views/pages/extraction/list.pug | 220 + .../pages/extraction/stop-terms-edit.pug | 59 + .../pages/extraction/term-candidates.pug | 110 + express/views/pages/help-pug-demo-frame.pug | 5 + express/views/pages/help-pug-demo.pug | 186 + express/views/pages/help.pug | 19 + express/views/pages/index.pug | 49 + express/views/pages/my-dictionaries-root.pug | 20 + express/views/pages/privacy-policy.pug | 82 + .../views/pages/profile/change-password.pug | 67 + .../pages/profile/change-profile-settings.pug | 34 + .../profile/my-profile-side-menu-mixin.pug | 31 + express/views/pages/profile/my-profile.pug | 83 + express/views/pages/search-root.pug | 18 + express/views/pages/search/no-results.pug | 26 + .../pages/search/result-detail-dictionary.pug | 44 + express/views/pages/search/result-detail.pug | 49 + express/views/pages/search/results.pug | 27 + .../views/pages/search/special-keys-demo.pug | 22 + express/views/pages/terms-of-use.pug | 18 + .../views/utilities/comments-input-text.pug | 25 + express/views/utilities/comments-new.pug | 38 + express/views/utilities/comments-pager.pug | 11 + .../comments-with-collapsable-pager.pug | 17 + .../views/utilities/comments-with-pager.pug | 14 + .../utilities/comments-without-pager.pug | 3 + ...ultancy-admin-in-progress-panel-header.pug | 46 + .../consultancy-admin-panel-header.pug | 37 + .../consultancy-main-panel-header.pug | 66 + .../utilities/content-classic-overview.pug | 89 + .../views/utilities/content-date-scroller.pug | 20 + express/views/utilities/content-edit.pug | 386 + express/views/utilities/content-header.pug | 130 + .../utilities/content-selected-overview.pug | 30 + express/views/utilities/content-side-menu.pug | 193 + .../dictionaries-main-panel-header.pug | 105 + .../dictionary-description-header.pug | 8 + .../views/utilities/dictionary-info-panel.pug | 105 + .../views/utilities/dictionary-main-input.pug | 121 + .../utilities/dictionary-structure-input.pug | 371 + .../utilities/empty-main-panel-header.pug | 6 + .../views/utilities/entry-preview-mixin.pug | 114 + express/views/utilities/entry-preview.pug | 177 + express/views/utilities/help-side-nav.pug | 66 + express/views/utilities/help-text.pug | 196 + express/views/utilities/keyboard.pug | 12 + express/views/utilities/mixed-content.pug | 22 + express/views/utilities/modal-alert-mixin.pug | 32 + express/views/utilities/modal-alert.pug | 28 + express/views/utilities/modal-response.pug | 25 + express/views/utilities/modal-spinner.pug | 19 + express/views/utilities/pager.pug | 24 + .../response-pug-wrapper/dictionaryLister.pug | 2 + .../response-pug-wrapper/entryLister.pug | 3 + .../utilities/result-detail-side-menu.pug | 57 + .../side-navigation-dictionary-mixin.pug | 43 + express/views/utilities/table-mixin.pug | 34 + express/views/utilities/table-wrapper.pug | 16 + .../views/utilities/unordered-list-mixin.pug | 10 + opensearch/Dockerfile | 4 + package-lock.json | 1839 +++++ package.json | 24 + postgres/Dockerfile.debug.alpine | 20 + postgres/Dockerfile.debug.debian | 13 + postgres/debugger-setup.sh | 1 + postgres/init/001_structure.sql | 95 + postgres/init/002_data-domain-primary.sql | 70 + postgres/init/003_data-domain-secondary.sql | 155 + postgres/init/004_data-language.sql | 39 + postgres/init/005_dummy-dictionary.sql | 15 + postgres/init/006_auth_and_aut.sql | 71 + postgres/init/007_entry.sql | 110 + postgres/init/008_function_entry_new.sql | 119 + postgres/init/009_function_entry_update.sql | 113 + postgres/init/010_function_dictionary_new.sql | 123 + postgres/init/011_comment.sql | 69 + postgres/init/012_consultancy.sql | 32 + postgres/init/013_linked_portals.sql | 23 + .../init/014_imported_dictionary_updates.sql | 56 + postgres/init/015_instance_settings.sql | 39 + .../016_function_sync_remote_dictionaries.sql | 273 + postgres/init/017_entry_history.sql | 105 + postgres/init/018_extraction.sql | 47 + postgres/init/500_init_user.sql | 13 + postgres/init/README.md | 6 + postgres/manual-scripts/termania.sql | 73 + postgres/manual-scripts/terminologisce.sql | 83 + redis/conf/redis.conf | 5 + 496 files changed, 55373 insertions(+) create mode 100644 .dockerignore create mode 100644 .eslintignore create mode 100644 .eslintrc.yml create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc.yml create mode 100644 README.md create mode 100644 concordancer/Dockerfile create mode 100644 dev/.env create mode 100644 dev/README - old.md create mode 100644 dev/razvojne_konvencije.md create mode 100644 docker-compose.prod.yml create mode 100644 docker-compose.yml create mode 100644 express/Dockerfile create mode 100644 express/Dockerfile.prod create mode 100644 express/app.js create mode 100755 express/bin/www create mode 100644 express/config/helmet.js create mode 100644 express/config/keys.js create mode 100644 express/config/settings.js create mode 100644 express/controllers/api/v1/comments.js create mode 100644 express/controllers/api/v1/consultancy.js create mode 100644 express/controllers/api/v1/demo-paginacija.js create mode 100644 express/controllers/api/v1/dictionaries.js create mode 100644 express/controllers/api/v1/extraction.js create mode 100644 express/controllers/api/v1/inter_instance_sync.js create mode 100644 express/controllers/api/v1/portals.js create mode 100644 express/controllers/api/v1/search.js create mode 100644 express/controllers/api/v1/system.js create mode 100644 express/controllers/api/v1/users.js create mode 100644 express/controllers/consultancy.js create mode 100644 express/controllers/demo-paginacija.js create mode 100644 express/controllers/dictionaries.js create mode 100644 express/controllers/extraction-poc.js create mode 100644 express/controllers/extraction.js create mode 100644 express/controllers/helpers/dictionary.js create mode 100644 express/controllers/helpers/extraction.js create mode 100644 express/controllers/helpers/search-filter-data-suggestion-importer.js create mode 100644 express/controllers/index.js create mode 100644 express/controllers/portals.js create mode 100644 express/controllers/users.js create mode 100644 express/middleware/auth.js create mode 100644 express/middleware/index.js create mode 100644 express/middleware/session.js create mode 100644 express/middleware/settings.js create mode 100644 express/middleware/user.js create mode 100644 express/models/batch.js create mode 100644 express/models/cache.js create mode 100644 express/models/comment.js create mode 100644 express/models/consultancy-entry.js create mode 100644 express/models/db.js create mode 100644 express/models/demo-paginacija.js create mode 100644 express/models/dictionary.js create mode 100644 express/models/domain.js create mode 100644 express/models/email.js create mode 100644 express/models/entry.js create mode 100644 express/models/extraction.js create mode 100644 express/models/helpers/dictionary/import-file.js create mode 100644 express/models/helpers/dictionary/index.js create mode 100644 express/models/helpers/extraction.js create mode 100644 express/models/helpers/index.js create mode 100644 express/models/helpers/portal/index.js create mode 100644 express/models/helpers/search/generate-query/consultancy/all.js create mode 100644 express/models/helpers/search/generate-query/consultancy/phrase.js create mode 100644 express/models/helpers/search/generate-query/consultancy/wildcard.js create mode 100644 express/models/helpers/search/generate-query/consultancy/words.js create mode 100644 express/models/helpers/search/generate-query/editor/all.js create mode 100644 express/models/helpers/search/generate-query/editor/exists.js create mode 100644 express/models/helpers/search/generate-query/editor/phrase.js create mode 100644 express/models/helpers/search/generate-query/editor/wildcard.js create mode 100644 express/models/helpers/search/generate-query/editor/words.js create mode 100644 express/models/helpers/search/generate-query/index.js create mode 100644 express/models/helpers/search/generate-query/main/aggregate-all.js create mode 100644 express/models/helpers/search/generate-query/main/aggregate-phrase.js create mode 100644 express/models/helpers/search/generate-query/main/aggregate-wildcard.js create mode 100644 express/models/helpers/search/generate-query/main/aggregate-word.js create mode 100644 express/models/helpers/search/generate-query/main/all.js create mode 100644 express/models/helpers/search/generate-query/main/phrase.js create mode 100644 express/models/helpers/search/generate-query/main/wildcard.js create mode 100644 express/models/helpers/search/generate-query/main/word-multi.js create mode 100644 express/models/helpers/search/generate-query/main/word-single.js create mode 100644 express/models/helpers/search/index.js create mode 100644 express/models/helpers/user/index.js create mode 100644 express/models/inter_instance_sync.js create mode 100644 express/models/portal.js create mode 100644 express/models/search-engine.js create mode 100644 express/models/system/eurotermbank.js create mode 100644 express/models/user.js create mode 100644 express/package-lock.json create mode 100644 express/package.json create mode 100644 express/public/documents/Podrocja_TP_2022-11-28.pdf create mode 100644 express/public/documents/RSDO_smernice.pdf create mode 100644 express/public/images/Component.svg create mode 100644 express/public/images/EKP.svg create mode 100644 express/public/images/Ekran.png create mode 100644 express/public/images/Filtri.png create mode 100644 express/public/images/Iskalni_zadetki.png create mode 100644 express/public/images/Napredno_iskanje.png create mode 100644 express/public/images/Neveljavno.png create mode 100644 express/public/images/Vnosno_polje.png create mode 100644 express/public/images/admin-button-gray-bg.svg create mode 100644 express/public/images/alert-circle-modal.svg create mode 100644 express/public/images/alert-circle.svg create mode 100644 express/public/images/alert-triangle-dark-red.svg create mode 100644 express/public/images/alert-triangle.svg create mode 100644 express/public/images/areas.svg create mode 100644 express/public/images/arrow_drop_down.svg create mode 100644 express/public/images/arrow_drop_up.svg create mode 100644 express/public/images/book-colorized.svg create mode 100644 express/public/images/book-open-blue.svg create mode 100644 express/public/images/book-open-white.svg create mode 100644 express/public/images/book-open.svg create mode 100644 express/public/images/book-white.svg create mode 100644 express/public/images/book.svg create mode 100644 express/public/images/burger-menu-button-icon.svg create mode 100644 express/public/images/check-circle.svg create mode 100644 express/public/images/chevron-double-left.svg create mode 100644 express/public/images/chevron-double-right.svg create mode 100644 express/public/images/chevron-down-darker.svg create mode 100644 express/public/images/chevron-down.svg create mode 100644 express/public/images/chevron-left-blue.svg create mode 100644 express/public/images/chevron-left.svg create mode 100644 express/public/images/chevron-right-2.svg create mode 100644 express/public/images/chevron-right.svg create mode 100644 express/public/images/chevrons-left.svg create mode 100644 express/public/images/clock.svg create mode 100644 express/public/images/cog-blue.svg create mode 100644 express/public/images/cog.svg create mode 100644 express/public/images/comment.svg create mode 100644 express/public/images/copy.svg create mode 100644 express/public/images/download.svg create mode 100644 express/public/images/dropdown.svg create mode 100644 express/public/images/edit-blue.svg create mode 100644 express/public/images/edit.svg create mode 100644 express/public/images/exclamation-triangle-red.svg create mode 100644 express/public/images/external-link-white.svg create mode 100644 express/public/images/external-link.svg create mode 100644 express/public/images/eye-off.svg create mode 100644 express/public/images/eye.svg create mode 100644 express/public/images/favicon.ico create mode 100644 express/public/images/fi_arrow-right-circle.svg create mode 100644 express/public/images/fi_blue-calendar.svg create mode 100644 express/public/images/fi_calendar-white.svg create mode 100644 express/public/images/fi_calendar.svg create mode 100644 express/public/images/fi_check-circle.svg create mode 100644 express/public/images/fi_copy.svg create mode 100644 express/public/images/fi_copy_border.svg create mode 100644 express/public/images/fi_corner-down-left.svg create mode 100644 express/public/images/fi_down_left.svg create mode 100644 express/public/images/fi_download.svg create mode 100644 express/public/images/fi_folder.svg create mode 100644 express/public/images/fi_save.svg create mode 100644 express/public/images/fi_upload.svg create mode 100644 express/public/images/fi_x-square.svg create mode 100644 express/public/images/format_bold.svg create mode 100644 express/public/images/format_italic.svg create mode 100644 express/public/images/globe.svg create mode 100644 express/public/images/gray-clock.svg create mode 100644 express/public/images/help-amebis-logo-pug-demo.png create mode 100644 express/public/images/icon-user-x.svg create mode 100644 express/public/images/icon-user.svg create mode 100644 express/public/images/keyboard.svg create mode 100644 express/public/images/left-arrow.svg create mode 100644 express/public/images/line-break.svg create mode 100644 express/public/images/link.svg create mode 100644 express/public/images/list.svg create mode 100644 express/public/images/lock-gray.svg create mode 100644 express/public/images/lock.svg create mode 100644 express/public/images/log-out.svg create mode 100644 express/public/images/logo.png create mode 100644 express/public/images/mc-hyperlink.svg create mode 100644 express/public/images/message-square-black.svg create mode 100644 express/public/images/message-square.svg create mode 100644 express/public/images/printer.svg create mode 100644 express/public/images/profile-loggedin.svg create mode 100644 express/public/images/profile.svg create mode 100644 express/public/images/quote-marks.svg create mode 100644 express/public/images/radio-button.svg create mode 100644 express/public/images/red-trash-icon.svg create mode 100644 express/public/images/refresh-ccw.svg create mode 100644 express/public/images/rsmzk.svg create mode 100644 express/public/images/search-error.svg create mode 100644 express/public/images/search.svg create mode 100644 express/public/images/search_blue.svg create mode 100644 express/public/images/share-2.svg create mode 100644 express/public/images/sliders.svg create mode 100644 express/public/images/square-checkbox-solid.svg create mode 100644 express/public/images/square-minus.svg create mode 100644 express/public/images/star-blue.svg create mode 100644 express/public/images/star.svg create mode 100644 express/public/images/statistics-blue.svg create mode 100644 express/public/images/statistics.svg create mode 100644 express/public/images/subscript.svg create mode 100644 express/public/images/superscript.svg create mode 100644 express/public/images/threedots.svg create mode 100644 express/public/images/trash-2.svg create mode 100644 express/public/images/u_comment-alt.svg create mode 100644 express/public/images/u_edit-alt.svg create mode 100644 express/public/images/u_redo.svg create mode 100644 express/public/images/user-gray.svg create mode 100644 express/public/images/user.svg create mode 100644 express/public/images/users-blue.svg create mode 100644 express/public/images/users.svg create mode 100644 express/public/images/valid.svg create mode 100644 express/public/images/vector.svg create mode 100644 express/public/images/x-black.svg create mode 100644 express/public/images/x-checkbox.svg create mode 100644 express/public/images/x-circle-blue.svg create mode 100644 express/public/images/x-circle-red.svg create mode 100644 express/public/images/x-circle.svg create mode 100644 express/public/images/x-gray.svg create mode 100644 express/public/images/x.svg create mode 100644 express/public/images/x_red.svg create mode 100644 express/public/javascripts/admin-portals.js create mode 100644 express/public/javascripts/admin.js create mode 100644 express/public/javascripts/collapsable-comments.js create mode 100644 express/public/javascripts/comments.js create mode 100644 express/public/javascripts/consultancy-edit.js create mode 100644 express/public/javascripts/consultancy-handle-unsaved.js create mode 100644 express/public/javascripts/consultancy-search-mechanism.js create mode 100644 express/public/javascripts/consultancy.js create mode 100644 express/public/javascripts/demo-paginacija.js create mode 100644 express/public/javascripts/dictionaries.js create mode 100644 express/public/javascripts/dictionary-import-extraction.js create mode 100644 express/public/javascripts/extraction-files-edit.js create mode 100644 express/public/javascripts/extraction-list.js create mode 100644 express/public/javascripts/extraction-oss-edit.js create mode 100644 express/public/javascripts/extraction-poc-files-edit.js create mode 100644 express/public/javascripts/extraction-poc-list.js create mode 100644 express/public/javascripts/extraction-poc-oss-edit.js create mode 100644 express/public/javascripts/extraction-poc-term-candidates.js create mode 100644 express/public/javascripts/extraction-term-candidates.js create mode 100644 express/public/javascripts/extraction.js create mode 100644 express/public/javascripts/globals.js create mode 100644 express/public/javascripts/help.js create mode 100644 express/public/javascripts/login-and-register.js create mode 100644 express/public/javascripts/main-sreach-utils.js create mode 100644 express/public/javascripts/mixed-content.js create mode 100644 express/public/javascripts/pagination-extensions.js create mode 100644 express/public/javascripts/results-index.js create mode 100644 express/public/javascripts/scripts.js create mode 100644 express/public/javascripts/search-dictionary.js create mode 100644 express/public/javascripts/search-results-admin.js create mode 100644 express/public/javascripts/search-results-content.js create mode 100644 express/public/javascripts/search-results.js create mode 100644 express/public/javascripts/select.js create mode 100644 express/public/javascripts/side-menu-filter-languages.js create mode 100644 express/public/javascripts/tooltip-helper.js create mode 100644 express/public/javascripts/trusted-types-default-policy.js create mode 100644 express/public/javascripts/utils.js create mode 100644 express/public/sass/common/_basic-includes.scss create mode 100644 express/public/sass/common/_comments-includes.scss create mode 100644 express/public/sass/common/_common.scss create mode 100644 express/public/sass/common/_dictionaries-includes.scss create mode 100644 express/public/sass/common/_index-definitions.scss create mode 100644 express/public/sass/common/_keyboard.scss create mode 100644 express/public/sass/common/_material-input.scss create mode 100644 express/public/sass/common/_mixins.scss create mode 100644 express/public/sass/components/_admin-main.scss create mode 100644 express/public/sass/components/_admin-side-menu.scss create mode 100644 express/public/sass/components/_comments-main.scss create mode 100644 express/public/sass/components/_consultancy-main.scss create mode 100644 express/public/sass/components/_content-header-section.scss create mode 100644 express/public/sass/components/_content-main.scss create mode 100644 express/public/sass/components/_content-side-menu.scss create mode 100644 express/public/sass/components/_dictionaries-main.scss create mode 100644 express/public/sass/components/_extraction-main.scss create mode 100644 express/public/sass/components/_footer.scss create mode 100644 express/public/sass/components/_header-section.scss create mode 100644 express/public/sass/components/_help.scss create mode 100644 express/public/sass/components/_mixed-content.scss create mode 100644 express/public/sass/components/_notification.scss create mode 100644 express/public/sass/components/_side-menu.scss create mode 100644 express/public/sass/components/_toolbar.scss create mode 100644 express/public/sass/components/_tooltips.scss create mode 100644 express/public/sass/components/search-filter/_res-panel.scss create mode 100644 express/public/sass/components/search-filter/_result-detail.scss create mode 100644 express/public/sass/components/search-filter/_search-filter-advanced-popup.scss create mode 100644 express/public/sass/components/search-filter/_search-filter-modal.scss create mode 100644 express/public/sass/components/search-filter/_search-filter-navigation.scss create mode 100644 express/public/sass/login-signup/_login-signup.scss create mode 100644 express/public/sass/style.scss create mode 100644 express/public/sass/text/_text-styles.scss create mode 100644 express/public/sass/variables/_variables.scss create mode 100644 express/routes/admin.js create mode 100644 express/routes/api/index.js create mode 100644 express/routes/api/v1/comments.js create mode 100644 express/routes/api/v1/consultancy.js create mode 100644 express/routes/api/v1/demo-paginacija.js create mode 100644 express/routes/api/v1/dictionaries.js create mode 100644 express/routes/api/v1/entries.js create mode 100644 express/routes/api/v1/extraction.js create mode 100644 express/routes/api/v1/index.js create mode 100644 express/routes/api/v1/portals.js create mode 100644 express/routes/api/v1/search.js create mode 100644 express/routes/api/v1/system.js create mode 100644 express/routes/api/v1/users.js create mode 100644 express/routes/consultancy.js create mode 100644 express/routes/dictionaries.js create mode 100644 express/routes/extraction-poc.js create mode 100644 express/routes/extraction.js create mode 100644 express/routes/index.js create mode 100644 express/scheduled/batch_update_linked.js create mode 100644 express/scheduled/crontab create mode 100644 express/scheduled/entrypoint.sh create mode 100644 express/utils/index.js create mode 100644 express/views/common/footer.pug create mode 100644 express/views/common/main-navigation-without-search.pug create mode 100644 express/views/common/main-navigation.pug create mode 100644 express/views/common/navigation-search-mixin.pug create mode 100644 express/views/common/side-menu-fake.pug create mode 100644 express/views/common/side-menu-mixin-admin.pug create mode 100644 express/views/common/side-menu-mixin-consultancy.pug create mode 100644 express/views/common/side-menu-mixin-dictionaries.pug create mode 100644 express/views/components/admin/admin-main-panel-content.pug create mode 100644 express/views/components/admin/admin-navigation.pug create mode 100644 express/views/components/consultancy/admin/consultancy-item-admin.pug create mode 100644 express/views/components/consultancy/consultancy-item.pug create mode 100644 express/views/components/dictionary/dictionary-list.pug create mode 100644 express/views/components/login-signup/login-signup.pug create mode 100644 express/views/components/main-panel/generic-main-panel-header.pug create mode 100644 express/views/components/main-panel/implementations/one-button.pug create mode 100644 express/views/components/main-panel/implementations/two-buttons.pug create mode 100644 express/views/components/navigation/edit-navigation.pug create mode 100644 express/views/components/navigation/main-navigation-right-mixin.pug create mode 100644 express/views/components/search-and-filter/advanced-search-modal-area-only.pug create mode 100644 express/views/components/search-and-filter/advanced-search-modal.pug create mode 100644 express/views/components/search-and-filter/inline-search.pug create mode 100644 express/views/components/search-and-filter/result-item.pug create mode 100644 express/views/components/search-and-filter/result-panel-decision-mixin.pug create mode 100644 express/views/components/search-and-filter/result-panel.pug create mode 100644 express/views/components/search-and-filter/search-filter-modal.pug create mode 100644 express/views/components/search-and-filter/search-filter-navigation-mixin.pug create mode 100644 express/views/components/search-and-filter/search-filter-navigation.pug create mode 100644 express/views/components/search-and-filter/search-with-primary-domain-filter.pug create mode 100644 express/views/components/search-and-filter/small-device-search.pug create mode 100644 express/views/email/consultancy-assigned.pug create mode 100644 express/views/email/consultancy-creation-notify.pug create mode 100644 express/views/email/consultancy-item-review.pug create mode 100644 express/views/email/dictionary-status-change.pug create mode 100644 express/views/email/extraction-done.pug create mode 100644 express/views/email/user-activation.pug create mode 100644 express/views/error.pug create mode 100644 express/views/extraction-poc/docs-edit.pug create mode 100644 express/views/extraction-poc/edit-oss.pug create mode 100644 express/views/extraction-poc/edit-own.pug create mode 100644 express/views/extraction-poc/list.pug create mode 100644 express/views/extraction-poc/stop-terms-edit.pug create mode 100644 express/views/extraction-poc/term-candidates.pug create mode 100644 express/views/layout.pug create mode 100644 express/views/pages/admin-dict-structure-demo.pug create mode 100644 express/views/pages/admin.pug create mode 100644 express/views/pages/admin/areas.pug create mode 100644 express/views/pages/admin/comments.pug create mode 100644 express/views/pages/admin/connections-list.pug create mode 100644 express/views/pages/admin/dictionaries-list.pug create mode 100644 express/views/pages/admin/dictionary-advanced.pug create mode 100644 express/views/pages/admin/dictionary-comments.pug create mode 100644 express/views/pages/admin/dictionary-description.pug create mode 100644 express/views/pages/admin/dictionary-domain-labels.pug create mode 100644 express/views/pages/admin/dictionary-export.pug create mode 100644 express/views/pages/admin/dictionary-extraction-import.pug create mode 100644 express/views/pages/admin/dictionary-import.pug create mode 100644 express/views/pages/admin/dictionary-structure.pug create mode 100644 express/views/pages/admin/dictionary-users.pug create mode 100644 express/views/pages/admin/new-connection.pug create mode 100644 express/views/pages/admin/portal-consultancy-settings.pug create mode 100644 express/views/pages/admin/portal-edit.pug create mode 100644 express/views/pages/admin/portal-list-dict.pug create mode 100644 express/views/pages/admin/portal.pug create mode 100644 express/views/pages/admin/portals-all-linked-dictionaries.pug create mode 100644 express/views/pages/admin/settings-dictionaries.pug create mode 100644 express/views/pages/admin/user-edit.pug create mode 100644 express/views/pages/admin/user-list.pug create mode 100644 express/views/pages/admin/user-portals.pug create mode 100644 express/views/pages/consultancy/admin/consultancy-admin-inheritable-module.pug create mode 100644 express/views/pages/consultancy/admin/dialogs/assign.pug create mode 100644 express/views/pages/consultancy/admin/dialogs/share.pug create mode 100644 express/views/pages/consultancy/admin/edit.pug create mode 100644 express/views/pages/consultancy/admin/in-progress.pug create mode 100644 express/views/pages/consultancy/admin/index.pug create mode 100644 express/views/pages/consultancy/admin/prepared.pug create mode 100644 express/views/pages/consultancy/admin/published.pug create mode 100644 express/views/pages/consultancy/admin/rejected.pug create mode 100644 express/views/pages/consultancy/admin/statistics.pug create mode 100644 express/views/pages/consultancy/admin/users.pug create mode 100644 express/views/pages/consultancy/ask.pug create mode 100644 express/views/pages/consultancy/index.pug create mode 100644 express/views/pages/consultancy/item-details.pug create mode 100644 express/views/pages/consultancy/search.pug create mode 100644 express/views/pages/demo-paginacija.pug create mode 100644 express/views/pages/dictionaries/advanced.pug create mode 100644 express/views/pages/dictionaries/content.pug create mode 100644 express/views/pages/dictionaries/description.pug create mode 100644 express/views/pages/dictionaries/dictionary-comments.pug create mode 100644 express/views/pages/dictionaries/dictlist.pug create mode 100644 express/views/pages/dictionaries/domain-labels.pug create mode 100644 express/views/pages/dictionaries/export.pug create mode 100644 express/views/pages/dictionaries/extraction-import.pug create mode 100644 express/views/pages/dictionaries/import.pug create mode 100644 express/views/pages/dictionaries/list.pug create mode 100644 express/views/pages/dictionaries/new.pug create mode 100644 express/views/pages/dictionaries/structure.pug create mode 100644 express/views/pages/dictionaries/users.pug create mode 100644 express/views/pages/extraction/docs-edit.pug create mode 100644 express/views/pages/extraction/edit-oss.pug create mode 100644 express/views/pages/extraction/edit-own.pug create mode 100644 express/views/pages/extraction/list.pug create mode 100644 express/views/pages/extraction/stop-terms-edit.pug create mode 100644 express/views/pages/extraction/term-candidates.pug create mode 100644 express/views/pages/help-pug-demo-frame.pug create mode 100644 express/views/pages/help-pug-demo.pug create mode 100644 express/views/pages/help.pug create mode 100644 express/views/pages/index.pug create mode 100644 express/views/pages/my-dictionaries-root.pug create mode 100644 express/views/pages/privacy-policy.pug create mode 100644 express/views/pages/profile/change-password.pug create mode 100644 express/views/pages/profile/change-profile-settings.pug create mode 100644 express/views/pages/profile/my-profile-side-menu-mixin.pug create mode 100644 express/views/pages/profile/my-profile.pug create mode 100644 express/views/pages/search-root.pug create mode 100644 express/views/pages/search/no-results.pug create mode 100644 express/views/pages/search/result-detail-dictionary.pug create mode 100644 express/views/pages/search/result-detail.pug create mode 100644 express/views/pages/search/results.pug create mode 100644 express/views/pages/search/special-keys-demo.pug create mode 100644 express/views/pages/terms-of-use.pug create mode 100644 express/views/utilities/comments-input-text.pug create mode 100644 express/views/utilities/comments-new.pug create mode 100644 express/views/utilities/comments-pager.pug create mode 100644 express/views/utilities/comments-with-collapsable-pager.pug create mode 100644 express/views/utilities/comments-with-pager.pug create mode 100644 express/views/utilities/comments-without-pager.pug create mode 100644 express/views/utilities/consultancy-admin-in-progress-panel-header.pug create mode 100644 express/views/utilities/consultancy-admin-panel-header.pug create mode 100644 express/views/utilities/consultancy-main-panel-header.pug create mode 100644 express/views/utilities/content-classic-overview.pug create mode 100644 express/views/utilities/content-date-scroller.pug create mode 100644 express/views/utilities/content-edit.pug create mode 100644 express/views/utilities/content-header.pug create mode 100644 express/views/utilities/content-selected-overview.pug create mode 100644 express/views/utilities/content-side-menu.pug create mode 100644 express/views/utilities/dictionaries-main-panel-header.pug create mode 100644 express/views/utilities/dictionary-description-header.pug create mode 100644 express/views/utilities/dictionary-info-panel.pug create mode 100644 express/views/utilities/dictionary-main-input.pug create mode 100644 express/views/utilities/dictionary-structure-input.pug create mode 100644 express/views/utilities/empty-main-panel-header.pug create mode 100644 express/views/utilities/entry-preview-mixin.pug create mode 100644 express/views/utilities/entry-preview.pug create mode 100644 express/views/utilities/help-side-nav.pug create mode 100644 express/views/utilities/help-text.pug create mode 100644 express/views/utilities/keyboard.pug create mode 100644 express/views/utilities/mixed-content.pug create mode 100644 express/views/utilities/modal-alert-mixin.pug create mode 100644 express/views/utilities/modal-alert.pug create mode 100644 express/views/utilities/modal-response.pug create mode 100644 express/views/utilities/modal-spinner.pug create mode 100644 express/views/utilities/pager.pug create mode 100644 express/views/utilities/response-pug-wrapper/dictionaryLister.pug create mode 100644 express/views/utilities/response-pug-wrapper/entryLister.pug create mode 100644 express/views/utilities/result-detail-side-menu.pug create mode 100644 express/views/utilities/side-navigation-dictionary-mixin.pug create mode 100644 express/views/utilities/table-mixin.pug create mode 100644 express/views/utilities/table-wrapper.pug create mode 100644 express/views/utilities/unordered-list-mixin.pug create mode 100644 opensearch/Dockerfile create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 postgres/Dockerfile.debug.alpine create mode 100644 postgres/Dockerfile.debug.debian create mode 100644 postgres/debugger-setup.sh create mode 100644 postgres/init/001_structure.sql create mode 100644 postgres/init/002_data-domain-primary.sql create mode 100644 postgres/init/003_data-domain-secondary.sql create mode 100644 postgres/init/004_data-language.sql create mode 100644 postgres/init/005_dummy-dictionary.sql create mode 100644 postgres/init/006_auth_and_aut.sql create mode 100644 postgres/init/007_entry.sql create mode 100644 postgres/init/008_function_entry_new.sql create mode 100644 postgres/init/009_function_entry_update.sql create mode 100644 postgres/init/010_function_dictionary_new.sql create mode 100644 postgres/init/011_comment.sql create mode 100644 postgres/init/012_consultancy.sql create mode 100644 postgres/init/013_linked_portals.sql create mode 100644 postgres/init/014_imported_dictionary_updates.sql create mode 100644 postgres/init/015_instance_settings.sql create mode 100644 postgres/init/016_function_sync_remote_dictionaries.sql create mode 100644 postgres/init/017_entry_history.sql create mode 100644 postgres/init/018_extraction.sql create mode 100644 postgres/init/500_init_user.sql create mode 100644 postgres/init/README.md create mode 100644 postgres/manual-scripts/termania.sql create mode 100644 postgres/manual-scripts/terminologisce.sql create mode 100644 redis/conf/redis.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b1f5669 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,24 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +README.md diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..5d54906 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +old_express diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..a609dbb --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,18 @@ +root: true +env: + es2021: true +extends: + - standard + - prettier +overrides: + - files: + - "*.js" + - "express/bin/www" + excludedFiles: "express/public" + env: + node: true + - files: "express/public/javascripts/*.js" + env: + browser: true +rules: + no-console: error diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3bb0ab7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,262 @@ +# Common settings that generally should always be used with your language specific settings + +# Auto detect text files and perform LF normalization +# https://www.davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ +* text=auto + +# +# The above will handle all files NOT found below +# + +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text +*.tab text +*.tsv text +*.sql text + +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as an asset (binary) by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary + +*.eps binary + +# +# Exclude files from exporting +# + +.gitattributes export-ignore +.gitignore export-ignore + +## GITATTRIBUTES FOR WEB PROJECTS +# +# These settings are for any web project. +# +# Details per file setting: +# text These files should be normalized (i.e. convert CRLF to LF). +# binary These files are binary and should be left untouched. +# +# Note that binary is a macro for -text -diff. +###################################################################### + +# Auto detect +## Handle line endings automatically for files detected as +## text and leave all files detected as binary untouched. +## This will handle all files NOT defined below. +# * text=auto + +# Source code +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.coffee text +*.css text +*.htm text diff=html +*.html text diff=html +*.inc text +*.ini text +*.js text +*.json text +*.jsx text +*.less text +*.ls text +*.map text -diff +*.od text +*.onlydata text +*.php text diff=php +*.pl text +*.ps1 text eol=crlf +*.py text diff=python +*.rb text diff=ruby +*.sass text +*.scm text +*.scss text diff=css +*.sh text eol=lf +*.sql text +*.styl text +*.tag text +*.ts text +*.tsx text +*.xml text +*.xhtml text diff=html + +# Docker +*.dockerignore text +Dockerfile text + +# Documentation +*.ipynb text +*.markdown text +*.md text +*.mdwn text +*.mdown text +*.mkd text +*.mkdn text +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text + +# Templates +*.dot text +*.ejs text +*.haml text +*.handlebars text +*.hbs text +*.hbt text +*.jade text +*.latte text +*.mustache text +*.njk text +*.phtml text +*.tmpl text +*.tpl text +*.twig text +*.vue text + +# Linters +.csslintrc text +.eslintrc text +.htmlhintrc text +.jscsrc text +.jshintrc text +.jshintignore text +.stylelintrc text + +# Configs +*.bowerrc text +*.cnf text +*.conf text +*.config text +.babelrc text +.browserslistrc text +.editorconfig text +.env text +.gitattributes text +.gitconfig text +.htaccess text +*.lock text -diff +package-lock.json text -diff +*.npmignore text +*.yaml text +*.yml text +browserslist text +Makefile text +makefile text + +# Heroku +Procfile text +.slugignore text + +# Graphics +*.ai binary +*.bmp binary +*.eps binary +*.gif binary +*.gifv binary +*.ico binary +*.jng binary +*.jp2 binary +*.jpg binary +*.jpeg binary +*.jpx binary +*.jxr binary +*.pdf binary +*.png binary +*.psb binary +*.psd binary +# SVG treated as an asset (binary) by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary +*.svgz binary +*.tif binary +*.tiff binary +*.wbmp binary +*.webp binary + +# Audio +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary + +# Video +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.ogv binary +*.swc binary +*.swf binary +*.webm binary + +# Archives +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary + +# Fonts +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary + +# Executables +*.exe binary +*.pyc binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5c6fde --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.vscode +/.env +.idea +express/public/stylesheets diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..0011463 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +old_express +express/public/stylesheets +help-pug-demo.pug diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 0000000..f74ed03 --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,19 @@ +overrides: + - files: + - "*.js" + - "*.pug" + - "express/bin/www" + options: + semi: false + singleQuote: true + trailingComma: none + arrowParens: avoid + - files: "*.pug" + options: + pugAttributeSeparator: as-needed + pugSingleQuote: false + # Disabled and solved in package.json + # Reason: bug https://github.com/prettier/prettier/issues/8924 + # - files: "express/bin/www" + # # options: + # # parser: babel diff --git a/README.md b/README.md new file mode 100644 index 0000000..1801939 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Terminološki portal + +## Navodila za namesitev + +Navodila so zaradi dinamičnih sprememb v integriranih zunanjih komponentah še v pripravi in bodo pripravljena, ko bo celota stabilnejša. diff --git a/concordancer/Dockerfile b/concordancer/Dockerfile new file mode 100644 index 0000000..2a70c6c --- /dev/null +++ b/concordancer/Dockerfile @@ -0,0 +1,6 @@ +FROM alpine:3.16 AS builder +WORKDIR /sloleks +RUN wget -qO- "https://www.clarin.si/repository/xmlui/bitstream/handle/11356/1230/Sloleks2.0.LMF.zip?sequence=3&isAllowed=y" | unzip - + +FROM ghcr.io/clarinsi/rsdo-concordancer-api:v1.0.0 +COPY --from=builder /sloleks /sloleks diff --git a/dev/.env b/dev/.env new file mode 100644 index 0000000..d148165 --- /dev/null +++ b/dev/.env @@ -0,0 +1,26 @@ +# Initial values are default vaules. +# Change if needed. + +EXPRESS_LISTEN_PORT=3000 +EXPRESS_IS_BEHIND_PROXY=false +EXPRESS_SECRET="weak_secret" + +POSTGRES_ADMIN_PASSWORD="weak_admin_password" # user: postgres +POSTGRES_EXPRESS_PASSWORD="weak_express_password" # user: express +POSTGRES_CONCORDANCER_PASSWORD="weak_concordancer_password" # user: concordancer +POSTGRES_LISTEN_PORT=5432 + +SMTP_HOST="maildev" +SMTP_PORT=1025 +SMTP_TLS_REJECT_UNAUTHORIZED=true +SMTP_FROM="Sender name " + +OS_DASHBOARDS_LISTEN_PORT=3002 + +CONCORDANCER_LISTEN_PORT=3003 + +# Development only settings +MAILDEV_WEB_GUI_PORT=3001 + +# Production only settings +URL_ORIGIN="https://mywebportal.com" diff --git a/dev/README - old.md b/dev/README - old.md new file mode 100644 index 0000000..f54af17 --- /dev/null +++ b/dev/README - old.md @@ -0,0 +1,25 @@ +_Tale dokument se bo dopolnjeval in bo v končni obliki v angleščini_ + +# Navodila za zagon aplikacije v razvojnem okolju + +**Na sistemu potrebuješ imeti naložen Docker.** + +1. Z Git repozitorija https://git.amebis.si/TerminoloskiPortal.git preneseš (najnovejšo) kodo (git clone, git pull, ...). + +2. `/dev/.env` skopiraš en nivo višje, v koren projekta, in po želji prilagodiš vrednosti. + +3. Za zagon celotne aplikacije v terminalu v korenu projekta poženeš `docker-compose up` + +4. Za ustavitev zgolj zapreš proces. + +**Dodatno** + +- Za vsak nadaljni zagon uporabljaš `docker-compose up`. + +- Ob spremembi _node modulov_ je najprej treba pognati `docker-compose down`, nato pa `docker-compose up --build`. + +- Če kadarkoli želiš sprostiti disk oz. ponastaviti aplikacijo, uporabiš `docker-compose down`. Podatki iz baze se ohranijo. Za izbris tudi njih, poženi raje `docker-compose down --volumes`. + +- Ob razvoju upoštevaj razvojne konvencije, navedene v `dev/razvojne_konvencije.md` + +- Odjemalec elektronske pošte je privzeto dosegljiv na portu 3001 (nastavljivo z variablo MAILDEV_WEB_GUI_PORT) diff --git a/dev/razvojne_konvencije.md b/dev/razvojne_konvencije.md new file mode 100644 index 0000000..4d836f2 --- /dev/null +++ b/dev/razvojne_konvencije.md @@ -0,0 +1,51 @@ +# Razvojne konvencije Terminološkega portala + +_Tale dokument se bo dopolnjeval in ga v končnem repozitoriju ne bo ali pa bo v končni obliki v angleščini._ + +## Priporočen editor, nastavitve in razširitve + +- Visual Studio Code ima za razvoj Node.js aplikacij ogromno uporabnih funkcionalnosti že vgrajenih + +- Nastavitve in razširitve niso vključene v Git repozitorij, vendar jih Luka z veseljem priporoči/deli. Še posebej je uporabna launch konfiguracija za debugiranje kode v kontejnerju v realnem času. + +- V VS Codu se da ta dokument brati v formatirani obliki z zagonom (_Ctrl + Shift + P_) ukaza `Markdown: Open Preview` + +## Git workflow + +- Commit messagi naj spoštujejo [to konvencijo](https://chris.beams.io/posts/git-commit/#seven-rules) in naj bodo v angleščini. + +- Za začetek ne commitajmo direktno v _master_ vejo. Vsakršno delo naj bo opravljeno na ločeni veji, ki pa jo bo Luka po potrebi dopolnil/prilagodil in dodal v _master_. Tipičen tok naj torej sledi naslednjemu vzorcu: + - Posodobiš _master_ na najnovejšo verzijo: `git pull origin master` + - Narediš novo vejo za dopolnitve: `git checkout -b ` + - Ime veje naj bo formata _\/\_ + - Primer imena veje: _jure/admin-console_ + - Narediš potrebne popravke v kodi in jih poljubnokrat, toda vsaj enkrat, commitaš: `git commit -m ""` + - Vejo porineš na remote repositorij: `git push origin ` + - Luku sporočiš, da je veja končana in pripravljena za integracijo v _master_ + - Ko Luka sporoči, da je bila veja integrirana, jo izbrišeš lokalno in na remote repozitoriju + - Greš na _master_: `git checkout master` + - Lokalni izbris: `git branch -D ` + - Remote izbris: `git push origin --delete ` + +## Sintaksa + +### Splošno + +- Za večino znanih tipov datotek za enotno formatiranje skrbi kombinacija ESLint-a in Prettier-ja. Kljub temu je spodaj navedenih nekaj splošnih smernic, ki jih upoštevajmo na splošno, v vseh datotekah. +- Za integracijo zgoraj navedenih orodij v VS Code in poenastavitev workflowa vam lahko pomaga Luka +- Če ne uporabljate integracije teh orodij v text editor, pred vsakim git commitom poženite `npm run format` +- Če se bo v git repozitorij začela objavljati neformatirana koda, bomo morali uporabiti git hooke; najraje na klientovi strani, sicer na strežniški + +#### Splošne smernice + +- Zamik enega nivoja naj bo povsod 2 presledka (JS, CSS, Pug, ...) +- Datoteke naj se končajo z newlinom. +- Komentarji se povedi. Začnejo se z veliko začetnico in končajo z ločilom. + +### JS + +- smernice in oblikovanje temeljijo na [JavaScript Standard Stilu](https://standardjs.com) z dodatnimi dopolnitvami +- uporaba console metod (log, warn, error, ...) v _končni_ kodi ni dovoljena + - ker je končnemu uporabniku (na klientovi strani) neuporabna in lahko kvečjemu razkrije neželene detajle + - ker je sinhrona in zato neprimerna za strežniško stran (Node) + - za debugiranje lahko uporabljamo debug modul ali log pointe debuggerskega orodja. V skrajnem primeru lahko uporabite console metode, a jih pred git commitom odstranite diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..1914a2d --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,150 @@ +version: "3.4" + +services: + express: + build: + context: express + dockerfile: Dockerfile.prod + depends_on: + - postgres + - redis + - opensearch + restart: always + environment: + NODE_ENV: production + IS_BEHIND_PROXY: "${EXPRESS_IS_BEHIND_PROXY:?}" + SECRET: "${EXPRESS_SECRET:?}" + COOKIES_SECURE: "true" + PGHOST: postgres + PGUSER: express + PGPASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + PGDATABASE: term_portal + SMTP_HOST: "${SMTP_HOST:?}" + SMTP_PORT: "${SMTP_PORT:?}" + SMTP_TLS_REJECT_UNAUTHORIZED: "${SMTP_TLS_REJECT_UNAUTHORIZED:?}" + SMTP_FROM: "${SMTP_FROM:?}" + ORIGIN: "${URL_ORIGIN:?}" + volumes: + - express-data:/usr/src/app/data_files + ports: + - "127.0.0.1:${EXPRESS_LISTEN_PORT:?}:3000" + + postgres: + image: postgres:15-alpine + restart: always + environment: + POSTGRES_PASSWORD: "${POSTGRES_ADMIN_PASSWORD:?}" + POSTGRES_DB: term_portal + POSTGRES_EXPRESS_PASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + POSTGRES_CONCORDANCER_PASSWORD: "${POSTGRES_CONCORDANCER_PASSWORD:?}" + POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=sl-SI" + volumes: + - postgres-data:/var/lib/postgresql/data + - ./postgres/init:/docker-entrypoint-initdb.d + ports: + - "127.0.0.1:${POSTGRES_LISTEN_PORT:?}:5432" + + redis: + image: redis:6-alpine + restart: always + volumes: + - redis-data:/data + - ./redis/conf:/usr/local/etc/redis + command: redis-server /usr/local/etc/redis/redis.conf + + opensearch: + build: opensearch + restart: always + environment: + - cluster.name=term-portal + - node.name=node-1 + # - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping + # - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM + - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch + - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml + - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address + # ulimits: + # memlock: + # soft: -1 + # hard: -1 + # nofile: + # soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems + # hard: 65536 + volumes: + - opensearch-data:/usr/share/opensearch/data + + # Disabled by default. Enable if needed. + opensearch-dashboards: + image: opensearchproject/opensearch-dashboards:2.3.0 + profiles: + - opensearch-dashboards + depends_on: + - opensearch + restart: always + environment: + - 'OPENSEARCH_HOSTS=["http://opensearch:9200"]' + - "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards + ports: + - "127.0.0.1:${OS_DASHBOARDS_LISTEN_PORT:?}:5601" + + concordancer: + # image: ghcr.io/clarinsi/rsdo-concordancer-api:v1.0.0 + build: concordancer + depends_on: + - postgres + - opensearch + restart: always + environment: + - "RSDO:Database:MasterConnectionString=Host=postgres;Username=concordancer;Password=${POSTGRES_CONCORDANCER_PASSWORD:?};Database=Concordancer" + - "RSDO:Elastic:ConnectionString=http://opensearch:9200" + - "RSDO:Tokenizer:ClasslaUrl=https://orodja.cjvt.si/oznacevalnik/ajax_api/v1/slv/process" + ports: + - "127.0.0.1:${CONCORDANCER_LISTEN_PORT:?}:5000" + volumes: + - express-data:/data + - sloleks:/sloleks + + # Disabled by default. Enable if needed. + concordancer-manager: + image: ghcr.io/clarinsi/rsdo-concordancer-systemmanager:v1.0.0 + profiles: + - concordancer-manager + depends_on: + - postgres + - opensearch + restart: always + environment: + - "RSDO:Database:MasterConnectionString=Host=postgres;Username=concordancer;Password=${POSTGRES_CONCORDANCER_PASSWORD:?};Database=Concordancer" + - "RSDO:Elastic:ConnectionString=http://opensearch:9200" + volumes: + - sloleks:/sloleks + + cron: + build: + context: express + dockerfile: Dockerfile.prod + init: true + depends_on: + - postgres + - redis + - opensearch + restart: always + environment: + NODE_ENV: production + PGHOST: postgres + PGUSER: express + PGPASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + PGDATABASE: term_portal + SMTP_HOST: "${SMTP_HOST:?}" + SMTP_PORT: "${SMTP_PORT:?}" + SMTP_TLS_REJECT_UNAUTHORIZED: "${SMTP_TLS_REJECT_UNAUTHORIZED:?}" + SMTP_FROM: "${SMTP_FROM:?}" + entrypoint: ["scheduled/entrypoint.sh"] + command: ["crond", "-f", "-l", "2"] + +volumes: + express-data: + postgres-data: + redis-data: + opensearch-data: + sloleks: diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..047b69e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,173 @@ +version: "3.4" + +services: + express: + build: express + depends_on: + - postgres + - redis + - opensearch + - maildev + environment: + NODE_ENV: development + DEBUG: termPortal:* + IS_BEHIND_PROXY: "${EXPRESS_IS_BEHIND_PROXY:?}" + SECRET: "${EXPRESS_SECRET:?}" + COOKIES_SECURE: "false" + PGHOST: postgres + PGUSER: express + PGPASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + PGDATABASE: term_portal + SMTP_HOST: "${SMTP_HOST:?}" + SMTP_PORT: "${SMTP_PORT:?}" + SMTP_TLS_REJECT_UNAUTHORIZED: "${SMTP_TLS_REJECT_UNAUTHORIZED:?}" + SMTP_FROM: "${SMTP_FROM:?}" + ORIGIN: http://localhost:${EXPRESS_LISTEN_PORT:?} + volumes: + # When developing/debugging concordancer, disable express bind mount and node_modules volume and enable express-data. + # - express-data:/usr/src/app/data_files + - ./express:/usr/src/app + - /usr/src/app/node_modules + ports: + - "127.0.0.1:${EXPRESS_LISTEN_PORT:?}:3000" + - "127.0.0.1:9229:9229" + # Enabling TTY makes the npm module "debug" output display properly in container logs + tty: true + + postgres: + image: postgres:15-alpine + # Use any of the two custom Dockerfiles below for debugging PL/pgSQL functions. + # Disable docker-entrypoint-initdb.d bind mount when doing so. + # build: + # context: postgres + # dockerfile: Dockerfile.debug.alpine + # # dockerfile: Dockerfile.debug.debian + environment: + POSTGRES_PASSWORD: "${POSTGRES_ADMIN_PASSWORD:?}" + POSTGRES_DB: term_portal + POSTGRES_EXPRESS_PASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + POSTGRES_CONCORDANCER_PASSWORD: "${POSTGRES_CONCORDANCER_PASSWORD:?}" + POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=sl-SI" + volumes: + - postgres-data:/var/lib/postgresql/data + - ./postgres/init:/docker-entrypoint-initdb.d + ports: + - "127.0.0.1:${POSTGRES_LISTEN_PORT:?}:5432" + + redis: + image: redis:6-alpine + volumes: + - redis-data:/data + - ./redis/conf:/usr/local/etc/redis + command: redis-server /usr/local/etc/redis/redis.conf + + opensearch: + build: opensearch + environment: + - cluster.name=term-portal + - node.name=node-1 + # - bootstrap.memory_lock=true # along with the memlock settings below, disables swapping + # - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM + - "DISABLE_INSTALL_DEMO_CONFIG=true" # disables execution of install_demo_configuration.sh bundled with security plugin, which installs demo certificates and security configurations to OpenSearch + - "DISABLE_SECURITY_PLUGIN=true" # disables security plugin entirely in OpenSearch by setting plugins.security.disabled: true in opensearch.yml + - "discovery.type=single-node" # disables bootstrap checks that are enabled when network.host is set to a non-loopback address + # ulimits: + # memlock: + # soft: -1 + # hard: -1 + # nofile: + # soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems + # hard: 65536 + volumes: + - opensearch-data:/usr/share/opensearch/data + + # Disabled by default. Enable if needed. + opensearch-dashboards: + image: opensearchproject/opensearch-dashboards:2.3.0 + profiles: + - debug-opensearch + depends_on: + - opensearch + environment: + - 'OPENSEARCH_HOSTS=["http://opensearch:9200"]' + - "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards + ports: + - "127.0.0.1:${OS_DASHBOARDS_LISTEN_PORT:?}:5601" + + concordancer: + # image: ghcr.io/clarinsi/rsdo-concordancer-api:v1.0.0 + build: concordancer + profiles: + - develop-concordancer + depends_on: + - postgres + - opensearch + restart: always + environment: + - "RSDO:Database:MasterConnectionString=Host=postgres;Username=concordancer;Password=${POSTGRES_CONCORDANCER_PASSWORD:?};Database=Concordancer" + - "RSDO:Elastic:ConnectionString=http://opensearch:9200" + - "RSDO:Tokenizer:ClasslaUrl=https://orodja.cjvt.si/oznacevalnik/ajax_api/v1/slv/process" + ports: + - "127.0.0.1:${CONCORDANCER_LISTEN_PORT:?}:5000" + volumes: + - express-data:/data + - sloleks:/sloleks + + concordancer-manager: + image: ghcr.io/clarinsi/rsdo-concordancer-systemmanager:v1.0.0 + profiles: + - develop-concordancer + depends_on: + - postgres + - opensearch + restart: always + environment: + - "RSDO:Database:MasterConnectionString=Host=postgres;Username=concordancer;Password=${POSTGRES_CONCORDANCER_PASSWORD:?};Database=Concordancer" + - "RSDO:Elastic:ConnectionString=http://opensearch:9200" + volumes: + - sloleks:/sloleks + + # Disabled by default. Enable for scheduled task testing. + # Manual testing can be done by running tasks inside express container directly. + # cron: + # build: express + # init: true + # depends_on: + # - postgres + # - redis + # - opensearch + # - maildev + # environment: + # NODE_ENV: development + # DEBUG: termPortal:* + # PGHOST: postgres + # PGUSER: express + # PGPASSWORD: "${POSTGRES_EXPRESS_PASSWORD:?}" + # PGDATABASE: term_portal + # SMTP_HOST: "${SMTP_HOST:?}" + # SMTP_PORT: "${SMTP_PORT:?}" + # SMTP_TLS_REJECT_UNAUTHORIZED: "${SMTP_TLS_REJECT_UNAUTHORIZED:?}" + # SMTP_FROM: "${SMTP_FROM:?}" + # volumes: + # - /usr/src/app/node_modules + # - /usr/src/app/scheduled + # - ./express:/usr/src/app + # # Enabling TTY makes the npm module "debug" output display properly in container logs + # tty: true + # entrypoint: ["scheduled/entrypoint.sh"] + # command: ["crond", "-f", "-l", "2"] + + maildev: + image: maildev/maildev:2.0.0-beta3 + volumes: + - maildev-data:/var/lib/maildev + ports: + - "127.0.0.1:${MAILDEV_WEB_GUI_PORT:?}:1080" + +volumes: + express-data: + postgres-data: + redis-data: + opensearch-data: + maildev-data: + sloleks: diff --git a/express/Dockerfile b/express/Dockerfile new file mode 100644 index 0000000..51f2ec0 --- /dev/null +++ b/express/Dockerfile @@ -0,0 +1,26 @@ +# syntax=docker/dockerfile:1 + +# Use the non-alpine base image for easier container debugging. +# FROM node:14 +FROM node:16-alpine + +# Curl is used in cron batch file. +RUN apk --no-cache add curl + +WORKDIR /usr/src/app + +COPY package*.json . +RUN npm install + +COPY . . + +COPY scheduled/crontab /var/spool/cron/crontabs/root +RUN which crond && \ + rm -rf /etc/periodic && \ + chmod 0744 scheduled/entrypoint.sh + +EXPOSE 3000 + +# Use devstart-wait if you need code execution to pause until a debugger is attached. +# CMD ["npm", "run", "devstart-wait"] +CMD ["npm", "run", "devstart"] diff --git a/express/Dockerfile.prod b/express/Dockerfile.prod new file mode 100644 index 0000000..be851b5 --- /dev/null +++ b/express/Dockerfile.prod @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 + +FROM node:16-alpine + +# Curl is used in cron batch file. +RUN apk --no-cache add curl + +WORKDIR /usr/src/app + +COPY package*.json ./ +RUN npm install --production --silent + +COPY . . + +COPY scheduled/crontab /var/spool/cron/crontabs/root +RUN which crond && \ + rm -rf /etc/periodic && \ + chmod 0744 scheduled/entrypoint.sh + +EXPOSE 3000 + +CMD ["node", "bin/www"] diff --git a/express/app.js b/express/app.js new file mode 100644 index 0000000..c97fe8f --- /dev/null +++ b/express/app.js @@ -0,0 +1,105 @@ +// Import 3rd party node modules. +const express = require('express') +const path = require('path') +const logger = require('morgan') +const helmet = require('helmet') +const favicon = require('serve-favicon') +const cookieParser = require('cookie-parser') +const createError = require('http-errors') +const debug = require('debug')('termPortal:app') + +// Import own modules. +const { isBehindProxy, secret } = require('./config/keys') +const helmetConfig = require('./config/helmet') +const session = require('./middleware/session') +const passport = require('./middleware/auth') +const user = require('./middleware/user') +const settings = require('./middleware/settings') +const { enhanceLocals } = require('./middleware') + +// Import Routers. +const apiRouter = require('./routes/api') +const adminRouter = require('./routes/admin') +const dictionariesRouter = require('./routes/dictionaries') +const extractionRouter = require('./routes/extraction') +const consultancyRouter = require('./routes/consultancy') +const indexRouter = require('./routes/index') + +// Create express app. +const app = express() + +// View engine setup. +const viewsPath = path.join(__dirname, 'views') +app.set('view engine', 'pug') +app.set('views', viewsPath) +app.locals.basedir = viewsPath + +// Other settings. +const inDevEnv = app.get('env') === 'development' +if (isBehindProxy) app.set('trust proxy', 1) // Trust first proxy. + +// Mount middleware. +app.use(logger('dev')) +app.use(helmet(helmetConfig)) +app.use(favicon(path.join(__dirname, 'public', 'images', 'favicon.ico'))) +app.use(express.static(path.join(__dirname, 'public'))) +app.use(express.json({ type: ['application/json', 'application/csp-report'] })) +app.use(express.urlencoded({ extended: true })) +app.use(cookieParser(secret)) +app.use(session) +app.use(passport.initialize()) +app.use(passport.session()) +app.use(passport.authenticate('remember-me')) +app.use(user.enhance) +app.use(settings.prepareRequiredSettings) +app.use(enhanceLocals) + +// Apparently express-debug can't be run inside another middleware and must be run in this file. +// To help you debug, temporarily uncomment the next line, but comment the helmet line due to strict CSP. +// if (app.get('env') === 'development') require('express-debug')(app) + +// Pretty printing pug output is strongly ill-advised and deprecated, since too often, it creates subtle bugs. +// But if you really need it to help you debug, you can temporarily enable the next line. +// app.locals.pretty = true + +// Mount routers. +app.use('/api', apiRouter) +app.use('/admin', adminRouter) +app.use('/slovarji', dictionariesRouter) +app.use('/luscenje', extractionRouter) +app.use('/svetovanje', consultancyRouter) +app.use('/', indexRouter) + +// Catch 404 and forward to error handler. +app.use((req, res, next) => next(createError(404))) + +// Error handler. +app.use((err, req, res, next) => { + if (err.status !== 404) debug(err) + + // Set error info to be displayed to user depending on environment. + let message, error + + if (inDevEnv || err.displayInProd) { + message = err.message + error = err + } else { + message = + err.status === 404 + ? 'Stran ne obstaja' + : 'Prišlo je do strežniške napake. Poskusite kasneje.' + error = {} + } + + res.status(err.status || 500) + + // Send plain error message for ajax requests. + if (req.isAjax) { + return res.send(message) + } + + // Render the error page. + res.render('error', { title: 'Napaka', message, error }) +}) + +module.exports = app diff --git a/express/bin/www b/express/bin/www new file mode 100755 index 0000000..a0b2311 --- /dev/null +++ b/express/bin/www @@ -0,0 +1,106 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +const db = require('../models/db') +const cache = require('../models/cache') +const searchEngine = require('../models/search-engine') +const email = require('../models/email') +const { seedDummyData } = require('../models/comment') +const { initDemoData } = require('../models/demo-paginacija') +const app = require('../app') +const debug = require('debug')('termPortal:server') +const http = require('http') + +/** + * Get port from environment and store in Express. + */ + +const port = normalizePort(process.env.PORT || '3000') +app.set('port', port) + +/** + * Create HTTP server. + */ + +const server = http.createServer(app) + +/** + * Listen on provided port, on all network interfaces. + */ + +// Wait for all dependancy connections before seeding data and starting to serve requests. +;(async () => { + await Promise.all([ + db.waitForConnection(), + cache.waitForConnection(), + searchEngine.waitForConnection(), + email.waitForConnection() + ]) + await searchEngine.initEntryIndex() + await searchEngine.initConsultancyEntryIndex() + seedDummyData() + // initDemoData() + server.listen(port) +})() + +server.on('error', onError) +server.on('listening', onListening) + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + const port = parseInt(val, 10) + + if (isNaN(port)) { + // Named pipe. + return val + } + + if (port >= 0) { + // Port number. + return port + } + + return false +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error + } + + const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port + + // Handle specific listen errors with friendly messages. + switch (error.code) { + case 'EACCES': + // eslint-disable-next-line no-console + console.error(bind + ' requires elevated privileges') + process.exit(1) + case 'EADDRINUSE': + // eslint-disable-next-line no-console + console.error(bind + ' is already in use') + process.exit(1) + default: + throw error + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + const addr = server.address() + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port + debug('Listening on ' + bind) +} diff --git a/express/config/helmet.js b/express/config/helmet.js new file mode 100644 index 0000000..85ac516 --- /dev/null +++ b/express/config/helmet.js @@ -0,0 +1,41 @@ +const crypto = require('crypto') + +module.exports = { + contentSecurityPolicy: { + useDefaults: false, + directives: { + defaultSrc: ["'none'"], + objectSrc: ["'none'"], + baseUri: ["'none'"], + scriptSrc: [ + generateCspNonce, + "'strict-dynamic'", + 'https:', + "'unsafe-inline'" + ], + connectSrc: ["'self'"], + styleSrc: ["'self'", 'https:', "'unsafe-inline'"], + fontSrc: ["'self'", 'https:'], + imgSrc: ["'self'", 'data:'], + // Disabled TT due to jQuery using sink functions and trying to sanitize + // produced HTML with DOMPurify breaks functionality of summernote. + // requireTrustedTypesFor: ["'script'"], + reportUri: ['/api/v1/system/csp-reports'] + } + }, + + referrerPolicy: { + policy: ['no-referrer', 'strict-origin-when-cross-origin'] + } +} + +// TODO CSP nonce is generated for every request. +// It would only really be needed (CSP in general) for the ones which return HTML documents +// and not for all the other (static) resources (styles, scrips, images, ...) +// Consider: caching static resources, using hash based policy instead of nonce or other ... + +function generateCspNonce(req, res) { + const cspNonce = crypto.randomBytes(16).toString('base64') + res.locals.cspNonce = cspNonce + return `'nonce-${cspNonce}'` +} diff --git a/express/config/keys.js b/express/config/keys.js new file mode 100644 index 0000000..52dd4b4 --- /dev/null +++ b/express/config/keys.js @@ -0,0 +1,11 @@ +module.exports = { + isBehindProxy: process.env.IS_BEHIND_PROXY === 'true', + secret: process.env.SECRET, + cookiesSecure: process.env.COOKIES_SECURE === 'true', + smtpHost: process.env.SMTP_HOST, + smtpPort: process.env.SMTP_PORT, + smtpTlsRejectUnauthorized: + process.env.SMTP_TLS_REJECT_UNAUTHORIZED === 'true', + smtpFrom: process.env.SMTP_FROM, + origin: process.env.ORIGIN +} diff --git a/express/config/settings.js b/express/config/settings.js new file mode 100644 index 0000000..60459eb --- /dev/null +++ b/express/config/settings.js @@ -0,0 +1,22 @@ +const { cookiesSecure } = require('../config/keys') + +// Duration of validity of a remember me token. 1 year. +const REMEMBER_ME_DURATION_JS = 365 * 24 * 60 * 60 * 1000 +exports.REMEMBER_ME_DURATION_SQL = '365 days' + +exports.rememberMeCookieSettings = { + httpOnly: true, + maxAge: REMEMBER_ME_DURATION_JS, + secure: cookiesSecure, + signed: true, + sameSite: 'lax' +} + +exports.DEFAULT_HITS_PER_PAGE = 10 + +exports.EDITOR_MAX_HITS = 10000 + +// If you change this one, don't forget to also update the volume mount in docker-compose.prod.yml. +exports.DATA_FILES_PATH = 'data_files' + +exports.MAX_EXTRACTIONS_PER_USER = 5 diff --git a/express/controllers/api/v1/comments.js b/express/controllers/api/v1/comments.js new file mode 100644 index 0000000..a4383a0 --- /dev/null +++ b/express/controllers/api/v1/comments.js @@ -0,0 +1,57 @@ +const Comment = require('../../../models/comment') +const Entry = require('../../../models/entry') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +exports.listComments = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = +req.query.p > 0 ? +req.query.p : 1 + const filters = { ctxType: req.query.ctx_type, ctxId: req.query.ctx_id } + + if (filters.ctxId === 'null') { + filters.ctxId = null + } + + const { + pages_total: numberOfAllPages, + comments, + comment_count: commentCount + } = await Comment.list(filters, req.user, resultsPerPage, page) + + res.send({ page, numberOfAllPages, comments, commentCount }) +} + +exports.createComment = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const receivedComment = req.body + const { ctxType, ctxId } = receivedComment + await Comment.create(receivedComment, req.user?.id) + const filters = { ctxType, ctxId } + const { pages_total: pagesTotal, comments } = await Comment.list( + filters, + req.user, + resultsPerPage, + 'last' + ) + if (ctxType === 'entry_dict_int' || ctxType === 'entry_dict_ext') { + await Entry.indexIntoSearchEngine(ctxId) + } + res.send({ comments, pagesTotal }) +} + +exports.seedComments = async (req, res) => { + const { commentCount } = req.params + await Comment.seed(commentCount) + res.send(`${commentCount} new comments generated`) +} + +exports.clearComments = async (req, res) => { + await Comment.clear() + res.send('All comments cleared') +} + +exports.updateStatus = async (req, res) => { + const commentId = req.body.params.id + const commentStatus = req.body.params.status + await Comment.updateStatus(commentId, commentStatus) + res.send('Visibility changed') +} diff --git a/express/controllers/api/v1/consultancy.js b/express/controllers/api/v1/consultancy.js new file mode 100644 index 0000000..62c7360 --- /dev/null +++ b/express/controllers/api/v1/consultancy.js @@ -0,0 +1,321 @@ +const ConsultancyEntry = require('../../../models/consultancy-entry') +const User = require('../../../models/user') +const { promisify } = require('util') +const { + deleteConsultancyEntryFromIndex +} = require('../../../models/search-engine') +const email = require('../../../models/email') +const helper = require('../../../models/helpers') + +const consultancy = {} + +consultancy.listEntries = async (req, res) => { + const consultancyEntryList = await ConsultancyEntry.fetchAll() + const data = {} + data.consEntryList = consultancyEntryList + res.send(data) +} + +consultancy.listNewEntries = async (req, res) => { + const consultancyNewEntryList = await ConsultancyEntry.fetchAllNew() + const data = {} + data.consultancyNewEntryList = consultancyNewEntryList + res.send(data) +} + +consultancy.createQuestion = async (req, res) => { + const q = req.body + const consultancyEntry = {} + + consultancyEntry.status = 'new' + + consultancyEntry.authorId = req.user.id + + consultancyEntry.institution = q.institution + + const { description } = q + if (!description) { + return res.status(400).send('description is a required parameter!') + } + consultancyEntry.description = description + + consultancyEntry.domainPrimaryIdInitial = q.domainPrimary + + if (!consultancyEntry.domainPrimaryIdInitial || q.domainPrimary === '-1') { + consultancyEntry.domainPrimaryIdInitial = null // undefined + } + consultancyEntry.existingSolutions = q.existing_solutions + + consultancyEntry.examplesOfUse = q.examples_of_use + + Object.keys(consultancyEntry).forEach(key => { + consultancyEntry[key] = helper.removeHtmlTags(consultancyEntry[key]).trim() + }) + + const questionId = await ConsultancyEntry.createQuestion(consultancyEntry) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + // TODO SEND EMAIL + // TODOOOOOOOOO + + const emails = await ConsultancyEntry.fetchConsultancyAdminEmails() + + const renderAsync = promisify(req.app.render.bind(req.app)) + const emailHtml = await renderAsync('email/consultancy-creation-notify', { + propertyToPassGoesHere: 'test1234' + }) + await email.send({ + to: emails, + subject: 'Ustvarjeno novo vprašanje v svetovalnici', + html: emailHtml + }) + /// ///////////////// + + res.status(201).send() +} + +consultancy.updateDomain = async (req, res) => { + const { id, value } = req.body + + if (!id) return res.status(400).send() + + await User.updateConsultancyDomains(id, value) + res.status(204).send() +} + +consultancy.insertConsultantAndHisDomainsByUsername = async (req, res) => { + const { username, domains } = req.body + + if (!username) { + return res.status(400).send() + } + + await User.insertNewConsultantWithDomainByUsername(username, domains) + res.status(204).send() +} + +consultancy.removeConsultant = async (req, res) => { + const { id } = req.body + + if (!id) return res.status(400).send() + + await User.removeConsultant(id) + + res.send() +} + +consultancy.getSharedAuthors = async (req, res) => { + const { id } = req.query + + if (!id) return res.status(400).send() + + const authors = await ConsultancyEntry.getSharedAuthorsArray(id) + + res.send(authors) +} + +consultancy.insertNonModerator = async (req, res) => { + const userId = req.body.user_id + const entryId = req.body.entry_id + + if (!userId || !entryId) return res.status(400).send() + + await ConsultancyEntry.insertNonModerator(entryId, userId) + await ConsultancyEntry.indexIntoSearchEngine(entryId, true) + + res.status(201).send() +} + +consultancy.getSharedAuthorsBeforePublish = async (req, res) => { + const { id } = req.query + + if (!id) return res.status(400).send() + + const authors = await ConsultancyEntry.getSharedAuthorsArrayBeforePublish(id) + + res.send(authors) +} + +consultancy.updateSharedAuthors = async (req, res) => { + const { id, authors } = req.body + + if (!id || !authors.length) return res.status(400).send() + + await ConsultancyEntry.updateSharedAuthorsArray(id, authors) + await ConsultancyEntry.indexIntoSearchEngine(id, true) + + res.send({}) +} + +/* +function assign - assigns from any state of the consultancy +question to work in-progress + +inputs: +id -> id of the question +*/ +consultancy.assign = async (req, res) => { + const questionId = req.body.question_id + let userId = req.body.user_id + + if (!questionId) return res.status(400).send() + + if (!userId) { + const user = await ConsultancyEntry.getModerator(questionId) + userId = user.id + if (!userId) return res.status(400).send({}) + } + + await ConsultancyEntry.assignWorkInProgress(questionId, userId) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + // TODO SEND MAIL TO MODERATOR + /* + Skrbnik svetovalnice vam je v urejanje dodelil novo terminološko vprašanje. + */ + + const emails = await ConsultancyEntry.fetchModeratorEmail(questionId) + + const renderAsync = promisify(req.app.render.bind(req.app)) + const emailHtml = await renderAsync('email/consultancy-assigned') + + await email.send({ + to: emails, + subject: 'Novo terminološko vprašanje', + html: emailHtml + }) + + res.send() +} + +consultancy.reject = async (req, res) => { + const questionId = req.body.question_id + + if (!questionId) return res.status(400).send() + + await ConsultancyEntry.rejectEntry(questionId) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + res.send() +} + +consultancy.sendToReview = async (req, res) => { + const questionId = req.body.question_id + + if (!questionId) return res.status(400).send() + + await ConsultancyEntry.sendToReview(questionId) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + /* SEND MAIL TO ALL CONSULTANCY ADMINS + Za potrditev objave ste prejeli novo terminološko vprašanje. + + + const allEmailsSet = new Set([...adminEmails, ...dictionariesAdminEmails]) + const allEmails = [] + for (const email of allEmailsSet) allEmails.push(email) + + const type = 'delete' + const renderAsync = promisify(appRef.render.bind(appRef)) + const emailHtml = await renderAsync('email/dictionary-status-change', { + type, + nameSl + }) + + await email.send({ + to: allEmails, + subject: 'Obvestilo o številu gesel', + html: emailHtml + }) + */ + + const emails = await ConsultancyEntry.fetchConsultancyAdminEmails() + + const renderAsync = promisify(req.app.render.bind(req.app)) + const emailHtml = await renderAsync('email/consultancy-item-review') + + await email.send({ + to: emails, + subject: 'Potrditev objave', + html: emailHtml + }) + + res.send() +} + +consultancy.publish = async (req, res) => { + const questionId = req.body.question_id + const answerAuthors = req.body.answer_authors + + if (!questionId) return res.status(400).send() + + const entry = await ConsultancyEntry.fetchById(questionId) + + if (!entry.title) { + return res.status(400).send('Answer not completed') + } + + await ConsultancyEntry.publish(questionId, answerAuthors) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + res.send() +} + +consultancy.updateQuestion = async (req, res) => { + const { id, questionTitle, domain: domainId, question, answer } = req.body + + if (!id) return res.status(400).send({}) + + if (questionTitle === '' || question === '' || answer === '') { + return res.status(422).send('Polja naslov, vprašanje in mnenje so obvezna!') + } + + const entry = await ConsultancyEntry.fetchById(id) + entry.domainPrimaryId = domainId > 0 ? domainId : null + entry.question = question + entry.answer = answer // helper.removeHtmlTags(answer).trim() + entry.title = questionTitle + + // TODO Luka: Miha, update only fields that were updated. + await ConsultancyEntry.updateQuestion(entry) + await ConsultancyEntry.indexIntoSearchEngine(id, true) + + res.send({}) +} + +consultancy.insertNonModerator = async (req, res) => { + const questionId = req.body.question_id + const userId = req.body.user_id + + if (!questionId || !userId) return res.status(400).send() + + await ConsultancyEntry.insertNonModerator(questionId, userId) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + res.send({}) +} + +consultancy.deleteConsultantForEntry = async (req, res) => { + const questionId = req.body.question_id + const userId = req.body.user_id + + if (!questionId || !userId) return res.status(400).send() + + await ConsultancyEntry.removeConsultantForEntry(questionId, userId) + await ConsultancyEntry.indexIntoSearchEngine(questionId, true) + + res.send({}) +} + +consultancy.deleteQuestion = async (req, res) => { + const { id } = req.body // question/entry id + + if (!id) return res.status(400).send() + + await ConsultancyEntry.removeEntry(id) + await deleteConsultancyEntryFromIndex(id, true) + + res.send() +} + +module.exports = consultancy diff --git a/express/controllers/api/v1/demo-paginacija.js b/express/controllers/api/v1/demo-paginacija.js new file mode 100644 index 0000000..0c7d2b4 --- /dev/null +++ b/express/controllers/api/v1/demo-paginacija.js @@ -0,0 +1,15 @@ +const DemoPaginacija = require('../../../models/demo-paginacija') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +exports.list = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = await DemoPaginacija.fetch( + resultsPerPage, + page + ) + + res.send({ page, numberOfAllPages, results }) +} diff --git a/express/controllers/api/v1/dictionaries.js b/express/controllers/api/v1/dictionaries.js new file mode 100644 index 0000000..dc73630 --- /dev/null +++ b/express/controllers/api/v1/dictionaries.js @@ -0,0 +1,189 @@ +const Dictionary = require('../../../models/dictionary') +const Entry = require('../../../models/entry') +const { + searchEntryIndex, + deleteEntryFromIndex, + deleteDictionaryEntriesFromIndex +} = require('../../../models/search-engine') +const genEditorAllQuery = require('../../../models/helpers/search/generate-query/editor/all') +const { prepareEditorEntries } = require('../../../models/helpers/search') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') +const { minEntriesRequirementCheckAndAct } = require('../../helpers/dictionary') + +const dictionary = {} + +dictionary.getEntry = async (req, res) => { + const entryId = req.query.id + const [entry, domainLabels] = await Promise.all([ + Entry.fetchFull(entryId), + Dictionary.fetchDomainLabelsFromEntryId(entryId) + ]) + + const data = { + entry, + allDomainLabels: domainLabels + } + res.send(data) +} + +dictionary.createEntry = async (req, res) => { + const { body } = req + const { dictionaryId } = body + + const entryId = await Entry.create(req.user.id, dictionaryId, body) + await Promise.all([ + Dictionary.updateMetadataAfterModifyingEntries(dictionaryId), + Entry.indexIntoSearchEngine(entryId, true) + ]) + + res.send({ entryId }) +} + +dictionary.updateEntry = async (req, res) => { + const { entryId } = req.body + const dictionaryId = await Entry.update(req.user.id, req.body) + await Promise.all([ + Dictionary.updateMetadataAfterModifyingEntry(entryId), + Entry.indexIntoSearchEngine(entryId, true), + minEntriesRequirementCheckAndAct.onUpdate(dictionaryId) + ]) + res.end() +} + +dictionary.fetchEntries = async (req, res) => { + const dictionaryId = req.query.id + const hitsQuery = genEditorAllQuery(dictionaryId) + const hits = await searchEntryIndex(hitsQuery) + + const terms = prepareEditorEntries(hits) + res.send(terms) +} + +// This function deletes selected entry. +dictionary.deleteEntry = async (req, res) => { + const { entryId } = req.query + const dictionaryId = await Entry.delete(entryId) + await Promise.all([ + Dictionary.updateMetadataAfterModifyingEntries(dictionaryId), + deleteEntryFromIndex(entryId, true), + minEntriesRequirementCheckAndAct.onDelete(dictionaryId, req.app) + ]) + + res.end() +} + +// This function deletes all entries in seleceted dictionary. +dictionary.deleteAllEntries = async (req, res) => { + // TODO This method executes all delete operations before sending the response, + // TODO after which the client tells the user it might take a few minutes. + const dictionaryId = +req.params.dictionaryId + await Entry.deleteAll(dictionaryId) + await Promise.all([ + Dictionary.updateMetadataAfterModifyingEntries(dictionaryId), + deleteDictionaryEntriesFromIndex(dictionaryId), + minEntriesRequirementCheckAndAct.onDelete(dictionaryId, req.app) + ]) + + res.end() +} + +dictionary.publishAllEntries = async (req, res) => { + // // TODO This method executes all operations before sending the response, + // // TODO after which the client tells the user it might take a few minutes. + // // TODO Also, the message is generic and the same as with deleting a dictionary or all of its entries. + + const dictionaryId = +req.params.dictionaryId + + await Entry.publishAllQualified(dictionaryId) + + // TODO Consider reducing the following two index operations into a single one. + await Promise.all([ + Dictionary.updateMetadataAfterModifyingEntries(dictionaryId), + deleteDictionaryEntriesFromIndex(dictionaryId) + ]) + + await Dictionary.indexIntoSearchEngine(dictionaryId) + + res.end() +} + +dictionary.delete = async (req, res) => { + // TODO This method executes all operations before sending the response, + // TODO after which the client tells the user it might take a few minutes. + // TODO It also keeps the user on a page which shouldn't exist anymore. + // TODO In fact, any value is apparently valid as dictionaryId URL parameter (no validation yet). + const dictionaryId = +req.params.dictionaryId + await Dictionary.delete(dictionaryId) + await deleteDictionaryEntriesFromIndex(dictionaryId) + + res.end() +} + +dictionary.updateDomainLabels = async (req, res) => { + const { dictionaryId, payload } = req.body.params + + await Dictionary.updateDomainLabel(dictionaryId, payload) + res.end() +} + +dictionary.renovateSecondaryDomains = async (req, res) => { + const data = req.body.params.payload + + await Dictionary.renovateSecondaryDomains(data) + res.end() +} + +dictionary.getEntryVersionSnapshot = async (req, res) => { + const { entryId, version } = req.params + + const historySnapshot = await Entry.fetchVersionSnapshot(entryId, version) + + res.send(historySnapshot) +} + +dictionary.listDictionaries = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = + await Dictionary.fetchAllAdminDictionaries(resultsPerPage, page) + + res.send({ page, numberOfAllPages, results }) +} + +dictionary.listDomainLabels = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const { dictionaryId } = req.params + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = + await Dictionary.fetchPaginationDomainLabels( + dictionaryId, + resultsPerPage, + page + ) + + res.send({ page, numberOfAllPages, results }) +} + +dictionary.listSecondaryDomains = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = +req.query.p > 0 ? +req.query.p : 1 + const { pages_total: numberOfAllPages, results } = + await Dictionary.fetchAllSecondaryDomains(resultsPerPage, page) + + res.send({ page, numberOfAllPages, results }) +} + +dictionary.extractionImport = async (req, res) => { + // TODO Import logic (Luka's task) + // const { id: dictionaryId, extractionId } = req.params + // const { from, to } = req.query + // const fromIndex = +from > 1 ? Math.floor(from) - 1 : 0 + // const toIndex = Number.isInteger(+to) ? Math.abs(to) : undefined + // console.log({ dictionaryId, extractionId, fromIndex, toIndex }) + res.send('IMPORTING') +} + +module.exports = dictionary diff --git a/express/controllers/api/v1/extraction.js b/express/controllers/api/v1/extraction.js new file mode 100644 index 0000000..f6e3a92 --- /dev/null +++ b/express/controllers/api/v1/extraction.js @@ -0,0 +1,328 @@ +const { unlink, rm, mkdir } = require('fs/promises') +const { promisify } = require('util') +const { URLSearchParams } = require('url') +const multer = require('multer') +const validator = require('validator') +const axios = require('axios') +const { + getExtractionFilesPath, + getDocumentsPath, + getStopTermsPath, + getConllusPath +} = require('../../../models/helpers/extraction') +const { checkIfcanBegin } = require('../../helpers/extraction') +const Extraction = require('../../../models/extraction') +const Domain = require('../../../models/domain') +const email = require('../../../models/email') +const { intoDbArray } = require('../../../models/helpers') +const { origin } = require('../../../config/keys') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +const MAX_FILE_NAME_LENGTH = 100 +const MAX_FILE_SIZE = 10 ** 9 // 1 GB +const VALID_DOCUMENT_EXTENSIONS = ['txt', 'doc', 'docx', 'pdf'] +const VALID_STOP_TERMS_FILE_EXTENSION = 'txt' +const MAX_OSS_DOCUMENT_COUNT = 500 + +const extractionFileStorage = multer.diskStorage({ + destination: (req, file, cb) => { + const { + params: { id: extractionId }, + fileType + } = req + const destinationPath = + fileType === 'stopTerms' + ? getStopTermsPath(extractionId) + : getDocumentsPath(extractionId) + cb(null, destinationPath) + }, + filename: (req, file, cb) => cb(null, file.originalname) +}) + +const extractionFileBodyParser = multer({ + storage: extractionFileStorage, + limits: { + fieldNameSize: 15, + fieldSize: 10, + fields: 1, + fileSize: MAX_FILE_SIZE, + headerPairs: 500 + }, + fileFilter: extractionFileFilter +}).single('extractionFile') +const parseExtractionFileBody = promisify(extractionFileBodyParser) + +const extraction = {} + +extraction.delete = async (req, res) => { + const extractionId = req.params.id + const corpusId = await Extraction.delete(extractionId) + + if (corpusId) { + await axios.delete(`http://concordancer:5000/dashboard/corpus/${corpusId}`) + } + + const extractionFilesPath = getExtractionFilesPath(extractionId) + await rm(extractionFilesPath, { recursive: true }) + + res.end() +} + +extraction.docsList = async (req, res) => { + const extractionId = req.params.id + const documentsStats = await Extraction.fetchAllDocumentsStats(extractionId) + res.send(documentsStats) +} + +extraction.docsUpdate = async (req, res) => { + try { + await parseExtractionFileBody(req, res) + } catch (error) { + if ( + error instanceof multer.MulterError && + error.code === 'LIMIT_FILE_SIZE' + ) { + throw Error('File too large. Must not be over 1 GB.') + } + throw error + } + res.end() +} + +extraction.docDelete = async (req, res) => { + const { id: extractionId, filename } = req.params + const documentsPath = getDocumentsPath(extractionId) + const filePath = `${documentsPath}/${filename}` + await unlink(filePath) + res.end() +} + +extraction.stopTermsList = async (req, res) => { + const extractionId = req.params.id + const stopTermsFilesStats = await Extraction.fetchAllStopTermsFilesStats( + extractionId + ) + res.send(stopTermsFilesStats) +} + +extraction.stopTermsUpdate = async (req, res) => { + try { + await parseExtractionFileBody(req, res) + } catch (error) { + if ( + error instanceof multer.MulterError && + error.code === 'LIMIT_FILE_SIZE' + ) { + throw Error('File too large. Must not be over 1 GB.') + } + throw error + } + res.end() +} + +extraction.stopTermDelete = async (req, res) => { + const { id: extractionId, filename } = req.params + const stopTermsPath = getStopTermsPath(extractionId) + const filePath = `${stopTermsPath}/${filename}` + await unlink(filePath) + res.end() +} + +extraction.ossSaveParams = [saveOssParams, (req, res) => res.end()] + +extraction.ossSearch = [ + saveOssParams, + async (req, res) => { + const { id: extractionId } = req.params + const { ossParams } = req + const searchParams = new URLSearchParams({ + ...(ossParams.year && { leta: ossParams.year }), + ...(ossParams.documentType && { vrste: ossParams.documentType }), + ...(ossParams.keywords && { kljucneBesede: ossParams.keywords }), + ...(ossParams.domainUdk && { udk: ossParams.domainUdk }) + }) + const searchApiUrl = `http://rsdo.lhrs.feri.um.si:8080/oss/steviloBesedilPoIskanju?${searchParams}` + + const { data: documentCount } = await axios.get(searchApiUrl) + const canSave = documentCount && documentCount <= MAX_OSS_DOCUMENT_COUNT + await Extraction.updateOssParams(extractionId, { + params: ossParams, + status: canSave ? 'valid' : 'invalid' + }) + res.send({ documentCount, canSave }) + } +] + +extraction.ossConfirmParams = async (req, res) => { + const { id: extractionId } = req.params + const { ossParams } = await Extraction.fetch(extractionId) + if (ossParams.status !== 'valid') throw Error('OSS params not valid') + await Extraction.updateOssParams(extractionId, { + params: ossParams.params, + status: 'confirmed' + }) + res.end() +} + +extraction.begin = async (req, res) => { + const extractionId = req.params.id + const extraction = await Extraction.fetch(extractionId) + const canBegin = await checkIfcanBegin(extraction) + if (!canBegin) throw Error('Extraction does not qualify to be ran') + + let timeStarted + const { ossParams, name: extractionName } = extraction + if (ossParams) { + timeStarted = await Extraction.beginOss(extractionId) + } else { + const conllusPath = getConllusPath(extractionId) + await mkdir(conllusPath, { recursive: true }) + const documentsNames = await Extraction.fetchAllDocumentsNames(extractionId) + timeStarted = await Extraction.beginOwn(extractionId, documentsNames) + } + + res.send(timeStarted) + + if (ossParams) { + // TODO This next method is only a temporary solution. + // TODO It should be called before response and its execution delegated to a seperate process or at least a seperate thread. + await Extraction.processOss(extractionId, ossParams.params) + } else { + // TODO This next method is only a temporary solution. + // TODO It should be called before response and its execution delegated to a seperate process or at least a seperate thread. + await Extraction.processOwn(extractionId, extractionName) + } + + const extractionLink = new URL('/luscenje', origin) + const renderAsync = promisify(req.app.render.bind(req.app)) + const authorEmail = await Extraction.fetchAuthorEmail(extractionId) + const emailHtml = await renderAsync('email/extraction-done', { + extractionName, + extractionLink + }) + await email.send({ + to: authorEmail, + subject: 'Luščenje končano', + html: emailHtml + }) +} + +extraction.duplicate = async (req, res) => { + // TODO Validate, if can be duplicated: status = finished or failed. + // TODO Execute duplication. + res.send('DUPLICATING!') +} + +extraction.termCandidatesExport = async (req, res) => { + // TODO CSV logic (Luka's task) + // const extractionId = req.params.id + // const { from, to } = req.query + // const fromIndex = +from > 1 ? Math.floor(from) - 1 : 0 + // const toIndex = Number.isInteger(+to) ? Math.abs(to) : undefined + // console.log({ extractionId, fromIndex, toIndex }) + res.download('public/images/help-amebis-logo-pug-demo.png') +} + +extraction.listFinishedForUser = async (req, res) => { + const extractions = await Extraction.fetchFinishedForUser(req.user.id) + res.send(extractions) +} + +extraction.listTermCandidates = async (req, res) => { + const extractionId = req.params.id + const termCandidatesJson = await Extraction.fetchTermCandidatesJson( + extractionId + ) + const termCandidates = JSON.parse(termCandidatesJson).terminoloski_kandidati + const hitsPerPage = +req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const numberOfAllPages = Math.ceil(termCandidates.length / hitsPerPage) + + res.send({ hitsPerPage, numberOfAllPages, termCandidates }) +} + +function extractionFileFilter(req, file, cb) { + let fileType + switch (req.path.split('/').at(-1)) { + case 'documents': + fileType = 'document' + break + + case 'stop-terms': + fileType = 'stopTerms' + break + + default: + return cb(Error('Invalid API endpoint')) + } + + const filenamePartsArray = file.originalname.split('.') + + const fileExtension = filenamePartsArray.pop() + if ( + (fileType === 'document' && + !VALID_DOCUMENT_EXTENSIONS.includes(fileExtension)) || + (fileType === 'stopTerms' && + fileExtension !== VALID_STOP_TERMS_FILE_EXTENSION) + ) { + return cb(Error('Invalid file type')) + } + + const fileName = filenamePartsArray.join('.') + if (!fileName || fileName.length > MAX_FILE_NAME_LENGTH) { + return cb( + Error( + `Filename must be between 1 and ${MAX_FILE_NAME_LENGTH} characters long.` + ) + ) + } + if (!validator.isAlphanumeric(fileName[0], 'sl-SI', { ignore: '_' })) { + return cb( + Error( + 'Filename must begin with an alphanumeric character or an underscore.' + ) + ) + } + if (!validator.isAlphanumeric(fileName, 'sl-SI', { ignore: ' _-.' })) { + return cb( + Error( + 'Filename can only contain alphanumeric characters, spaces, underscores, minuses and periods.' + ) + ) + } + + req.fileType = fileType + cb(null, true) +} + +async function saveOssParams(req, res, next) { + const { id: extractionId } = req.params + const { body } = req + const ossParams = { + ...(body.domain && { + domainUdk: intoDbArray( + (await Domain.fetchById(body.domain)).udkCode, + 'always' + ) + }), + ...(body.documentType && { + documentType: intoDbArray(body.documentType, 'always').map(type => +type) + }), + ...(body.year && { + year: intoDbArray(body.year, 'always').map(year => +year) + }), + ...(body.keywords && { + keywords: intoDbArray(body.keywords, 'always') + }) + } + + await Extraction.update(extractionId, body.name) + await Extraction.updateOssParams(extractionId, { + params: ossParams, + status: 'unvalidated' + }) + + req.ossParams = ossParams + next() +} + +module.exports = extraction diff --git a/express/controllers/api/v1/inter_instance_sync.js b/express/controllers/api/v1/inter_instance_sync.js new file mode 100644 index 0000000..719dad6 --- /dev/null +++ b/express/controllers/api/v1/inter_instance_sync.js @@ -0,0 +1,18 @@ +const InterInstanceSync = require('../../../models/inter_instance_sync') + +exports.listDictionaries = async (req, res) => { + const dictionaries = await InterInstanceSync.listDictionaries() + res.send(dictionaries) +} + +exports.syncDictionary = async (req, res) => { + const did = req.params.dictionaryId + const since = req.query.lastSynced + ? req.query.lastSynced + : '2000-01-01 00:00:00' + const entriesToSync = await InterInstanceSync.getUpdatedEntriesSince( + did, + since + ) + res.send(entriesToSync) +} diff --git a/express/controllers/api/v1/portals.js b/express/controllers/api/v1/portals.js new file mode 100644 index 0000000..0de7e4c --- /dev/null +++ b/express/controllers/api/v1/portals.js @@ -0,0 +1,63 @@ +const Portal = require('../../../models/portal') +const axios = require('axios') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +const portal = {} + +portal.create = async (req, res) => { + const portal = await Portal.create(req.body) + res.send(portal) +} + +portal.syncRemoteDictionaries = async (req, res) => { + const { linkedPortalId } = req.params + const { indexURL } = await Portal.fetchPortal(linkedPortalId) + + const { data: dictionaries } = await axios.get(indexURL) + + await Portal.syncRemoteDictionaries(linkedPortalId, dictionaries) + + res.end() +} + +portal.deleteLinkedDictionary = async (req, res) => { + const { linkedPortalId } = req.params + await Portal.deleteLinkedDictionary(linkedPortalId) + res.end() +} + +portal.fetchDictionary = async (req, res) => { + const portalId = req.query.id + const dictionaries = await Portal.fetchDictionaries(portalId) + res.send(dictionaries) +} + +portal.updatePortalStatus = async (req, res) => { + const portalId = req.body.params.id + const isEnabled = req.body.params.isEnabled + await Portal.updatePortalStatus(portalId, isEnabled) + res.end() +} + +portal.listSelectedLinkedDicts = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const { portalId } = req.params + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = + await Portal.fetchSelectedLinkedDictionaries(portalId, resultsPerPage, page) + + res.send({ page, numberOfAllPages, results }) +} + +portal.listAllLinkedDicts = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = + await Portal.fetchAllLinkedDictionaries(resultsPerPage, page) + + res.send({ page, numberOfAllPages, results }) +} + +module.exports = portal diff --git a/express/controllers/api/v1/search.js b/express/controllers/api/v1/search.js new file mode 100644 index 0000000..6c24609 --- /dev/null +++ b/express/controllers/api/v1/search.js @@ -0,0 +1,230 @@ +const Dictionary = require('../../../models/dictionary') +const { searchEntryIndex } = require('../../../models/search-engine') +const { intoDbArray } = require('../../../models/helpers') +const { + prepareEntries, + prepareEditorEntries, + prepareAggregation, + prepareSeachFilterData +} = require('../../../models/helpers/search') +const generateQuery = require('../../../models/helpers/search/generate-query') +const { getInstanceSetting } = require('../../../models/helpers') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +exports.listMainEntries = async (req, res) => { + const searchString = req.query.q?.trim() + + if (!searchString) return res.status(400).end() + + const filters = { + sourceLanguages: intoDbArray(req.query.sl, 'always'), + targetLanguages: intoDbArray(req.query.tl, 'always'), + primaryDomains: intoDbArray(req.query.pd, 'always'), + dictionaries: intoDbArray(req.query.d, 'always'), + sources: intoDbArray(req.query.s, 'always') + } + + const hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const hitsQuery = await generateQuery.main( + searchString, + filters, + hitsPerPage, + page + ) + + const hits = await searchEntryIndex(hitsQuery) + + const numberOfAllHits = hits.body.hits.total.value + const numberOfAllPages = Math.ceil(numberOfAllHits / hitsPerPage) + + let entriesByCategory = prepareEntries(hits) + + // TODO Luka (note to self): Consider reworking Miha's logic below. It's hacky and possibly error prone. + // TODO copied code below, maybe refactor to a helper function? + // check express/controllers/index.js search + entriesByCategory = Object.entries(entriesByCategory).reduce( + (acc, category, index) => { + acc[category[0]] = category[1].map(entry => { + if (entry.foreignEntries) { + entry.foreignEntries = entry.foreignEntries.map(fe => { + fe.terms = fe.terms ? fe.terms.filter(term => !!term) : [] + fe.synonyms = fe.synonyms + ? fe.synonyms.filter(synonym => !!synonym) + : [] + fe.nbspCount = fe.terms.length + fe.synonyms.length - 1 + return fe + }) + } + + return entry + }) + return acc + }, + {} + ) + + // res.send({ page, numberOfAllPages, entries }) + res.append('page', page) + res.append('number-of-all-pages', numberOfAllPages) + res.render('utilities/response-pug-wrapper/entryLister', { + entriesByCategory + }) +} + +exports.listEditorEntries = async (req, res) => { + const { dictionaryId } = req.params + + if (!dictionaryId) return res.status(400).end() + + const qs = req.query + + const searchField = qs.field + const searchString = qs.q?.trim() ?? '' + + const filters = { + isValid: qs.isValid === undefined ? undefined : qs.isValid !== 'false', + isPublished: + qs.isPublished === undefined ? undefined : qs.isPublished !== 'false', + hasComments: + qs.hasComments === undefined ? undefined : qs.hasComments !== 'false', + isComplete: + qs.isComplete === undefined ? undefined : qs.isComplete !== 'false', + isTerminologyReviewed: + qs.isTerminologyReviewed === undefined + ? undefined + : qs.isTerminologyReviewed !== 'false', + isLanguageReviewed: + qs.isLanguageReviewed === undefined + ? undefined + : qs.isLanguageReviewed !== 'false' + } + + const hitsQuery = generateQuery.editor( + dictionaryId, + searchField, + searchString, + filters + ) + + const hits = await searchEntryIndex(hitsQuery) + + const entries = prepareEditorEntries(hits) + + res.send(entries) +} + +exports.listFilteredDictionaries = async (req, res) => { + let searchString = req.query.q?.trim() + + if (!searchString) { + searchString = '' + } + + const filters = { + // sourceLanguages: intoDbArray(req.query.sl, 'always'), + // targetLanguages: intoDbArray(req.query.tl, 'always'), + primaryDomains: intoDbArray(req.query.pd, 'always') + // sources: intoDbArray(req.query.s, 'always') + } + + const orderType = req.query.orderType + const orderIndex = req.query.orderIndex === 'true' + + // TODO: User another constant since this one is also user in the search results + const hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + // const defaultportalname = await getInstanceSetting('portal_name') + const defaultportalcode = await getInstanceSetting('portal_code') + + let dictionaries + + // mapping done here to not expose database info to public + let orderAttribute + if (orderType === 'domainName') { + orderAttribute = 'dp' + } else { + orderAttribute = 'd' + } + + dictionaries = await Dictionary.fetchBasicInfoPerPageFilteredWithOrdering( + searchString, + filters.primaryDomains, + hitsPerPage, + page, + orderAttribute, + orderIndex + ) + + dictionaries = dictionaries.map(e => { + if (!e.portalcode) { + e.portalcode = defaultportalcode + // e.portalname = defaultportalname + } + return e + }) + + const numberOfAllHits = parseInt( + (await Dictionary.fetchFilteredCount(searchString, filters.primaryDomains)) + .count + ) + const numberOfAllPages = Math.ceil(numberOfAllHits / hitsPerPage) + + // res.send({ page, numberOfAllPages, entries }) + res.append('page', page) + res.append('number-of-all-pages', numberOfAllPages) + res.render('utilities/response-pug-wrapper/dictionaryLister', { + dictionaries + }) +} + +exports.showModalFilterResults = async (req, res) => { + const searchString = req.query.q?.trim() + + if (!searchString) return res.status(400).end() + + const selectedFilter = req.query.selectedFilter + + // The selected + const filters = { + sourceLanguages: + selectedFilter === 'sourceLanguages' + ? [] + : intoDbArray(req.query.sl, 'always'), + targetLanguages: + selectedFilter === 'targetLanguages' + ? [] + : intoDbArray(req.query.tl, 'always'), + primaryDomains: + selectedFilter === 'primaryDomains' + ? [] + : intoDbArray(req.query.pd, 'always'), + dictionaries: + selectedFilter === 'dictionaries' + ? [] + : intoDbArray(req.query.d, 'always'), + sources: + selectedFilter === 'sources' ? [] : intoDbArray(req.query.s, 'always') + } + + const hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const [, aggregateQuery] = await generateQuery.main( + searchString, + filters, + hitsPerPage, + page, + true + ) + + const aggregationRaw = await searchEntryIndex(aggregateQuery) + + const aggregation = await prepareAggregation(aggregationRaw) + res.send(prepareSeachFilterData(aggregation, filters)) +} diff --git a/express/controllers/api/v1/system.js b/express/controllers/api/v1/system.js new file mode 100644 index 0000000..535b48d --- /dev/null +++ b/express/controllers/api/v1/system.js @@ -0,0 +1,16 @@ +const debug = require('debug')('termPortal:controllers/api/v1/system') +const Eurotermbank = require('../../../models/system/eurotermbank') + +exports.handleCspReports = (req, res) => { + debug(req.body) + res.sendStatus(200) +} + +exports.syncWithEurotermbank = async (req, res) => { + try { + await Eurotermbank.push() + res.send('Sync successful') + } catch (error) { + res.send('Sync failed') + } +} diff --git a/express/controllers/api/v1/users.js b/express/controllers/api/v1/users.js new file mode 100644 index 0000000..406c9a3 --- /dev/null +++ b/express/controllers/api/v1/users.js @@ -0,0 +1,35 @@ +const User = require('../../../models/user') +const { DEFAULT_HITS_PER_PAGE } = require('../../../config/settings') + +const users = {} +users.listUsers = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const { pages_total: numberOfAllPages, results } = await User.fetchAll( + resultsPerPage, + page + ) + + res.send({ page, numberOfAllPages, results }) +} + +users.updateHitsPerPage = async (req, res) => { + const hitAmount = req.body.hitAmount + + await User.updateHitsPerPage(req.user.userName, hitAmount) + + res.status(200).send() +} + +users.updateFristNameAndSurname = async (req, res) => { + const firstname = req.body.name + const surname = req.body.surname + + await User.updateFirstNameAndLastName(req.user.userName, firstname, surname) + + res.status(200).send() +} + +module.exports = users diff --git a/express/controllers/consultancy.js b/express/controllers/consultancy.js new file mode 100644 index 0000000..4080805 --- /dev/null +++ b/express/controllers/consultancy.js @@ -0,0 +1,408 @@ +const Dictionary = require('../models/dictionary') +const ConsultancyEntry = require('../models/consultancy-entry') +const Domain = require('../models/domain') +const User = require('../models/user') +const utils = require('../utils') +// const helpers = require('../models/helpers') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') +const generateQuery = require('../models/helpers/search/generate-query') +const { searchConsultancyEntryIndex } = require('../models/search-engine') +const { prepareConsultancyEntries } = require('../models/helpers/search') +// const { minEntriesRequirementCheckAndAct } = require('./helpers/dictionary') + +const consultancy = {} +const consultancyAdmin = {} + +consultancy.index = async (req, res) => { + req.indexHitPageAmount = '5' + + return await consultancyRequest( + req, + res, + 'published', + 'pages/consultancy/index' + ) +} + +consultancy.search = async (req, res) => { + return await consultancyRequest( + req, + res, + 'published', + 'pages/consultancy/search' + ) +} + +consultancy.specificQuestion = async (req, res) => { + const { id } = req.params + + const entry = await ConsultancyEntry.fetchByIdWithFormattedTime(id) + // const author = await User.fetchUser(entry.authorId) + + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + entry.answerAuthors = entry.answerAuthors.filter(author => author !== '') + + let authorString + if (entry.answerAuthors.length === 1) { + authorString = 'Avtor' + } else if (entry.answerAuthors.length === 2) { + authorString = 'Avtorja' + } else { + authorString = 'Avtorji' + } + + entry.domain = allPrimaryDomains.filter( + filt => filt.id === entry.domainPrimaryId + ) + + if (entry.domain.length > 0) { + entry.domain = entry.domain[0].nameSl + } else { + entry.domain = false + } + + res.render('pages/consultancy/item-details', { + allPrimaryDomains, + authorString, + entry + }) +} + +consultancy.new = async (req, res) => { + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + res.render('pages/consultancy/ask', { + allPrimaryDomains + }) +} + +consultancyAdmin.new = async (req, res) => { + return await consultancyRequest( + req, + res, + 'new', + 'pages/consultancy/admin/index', + true, + false + ) +} + +consultancyAdmin.users = async (req, res) => { + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + const users = await User.fetchConsultants() + + res.render('pages/consultancy/admin/users', { + allPrimaryDomains, + users + }) +} + +consultancyAdmin.rejected = async (req, res) => { + return await consultancyRequest( + req, + res, + 'rejected', + 'pages/consultancy/admin/rejected', + true, + false + ) +} + +consultancyAdmin.published = async (req, res) => { + return await consultancyRequest( + req, + res, + 'published', + 'pages/consultancy/admin/published', + true, + false + ) +} + +consultancyAdmin.prepared = async (req, res) => { + return await consultancyRequest( + req, + res, + 'review', + 'pages/consultancy/admin/prepared', + true, + false + ) +} + +consultancyAdmin.inProgress = async (req, res) => { + // TODO Below is an example use of consultancy search implemented using search engine. + // TODO Adjust and use it everywhere it's needed and delete these comments. + // *************************************** EXAMPLE START *************************************** + + return await consultancyRequest( + req, + res, + 'in progress', + 'pages/consultancy/admin/in-progress', + true, + false + ) +} + +consultancyAdmin.statistics = async (req, res) => { + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + res.render('pages/consultancy/admin/statistics', { + allPrimaryDomains + }) +} + +consultancyAdmin.edit = async (req, res) => { + const { id } = req.params + const key = req.query.sentFrom + const sentFrom = {} + sentFrom[key] = true + + const moderator = await ConsultancyEntry.getModerator(id) + const editors = await ConsultancyEntry.getEditors(id) + if ( + req.user.hasRole('consultancy admin') || + req.user.hasRole('portal admin') + ) { + console.log('Editor guard omitted due to being administrator') + } else if (editors.filter(editors => editors.id === req.user.id) < 1) { + return res.send('You do not have permsisions to edit this answer') + } + const entry = await ConsultancyEntry.fetchByIdWithFormattedTime(id) + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + const author = await User.fetchUser(entry.authorId) + + const isPublished = entry.status === 'published' + + res.render('pages/consultancy/admin/edit', { + id, + sentFrom: key, + entry: entry, + allPrimaryDomains, + moderator, + author, + isPublished, + // TODO Luka: I suspect this will not work as intended on staging or production environments. Test. + urlPrefix: req.protocol + '://' + req.get('host') + }) +} + +function dateMap(obj) { + if (!obj.formattedTimeCreated) { + obj.formattedTimeCreated = obj.timeCreated + } + + return obj +} + +async function mapDomainIdToDomainNameSlovene(obj) { + try { + const area = await Domain.fetchById( + obj.domainPrimaryId ? obj.domainPrimaryId : obj.domainPrimaryIdInitial + ) + obj.area = area.nameSl + } catch { + obj.area = 'Ni področja' + } + + return obj +} + +function mapInitialValuesAsEmpty(obj) { + if (!obj.authors) { + obj.authors = [] + } + + if (!obj.title) { + obj.title = '' + } + + if (!obj.numShared) { + obj.numShared = 0 + } + + return obj +} + +async function mapEntryList(list) { + return await Promise.all( + list.map(entry => { + let entity = utils.compose(dateMap, mapInitialValuesAsEmpty)(entry) + + // TODO Each mapDomainIdToDomainNameSlovene call leads to one DB query. + // TODO Test if and what scenarios can lead to too many calls and how it can be avoided. + entity = utils.composeAsync(mapDomainIdToDomainNameSlovene)(entry) + + return entity + }) + ) +} + +function summaryDisplay(str) { + if (str.split('\n').length > 3) { + return splitLine(str, 3) + } else { + return cropLongString(str) + } +} + +function splitLine(str, countLines) { + if (!str) { + return str + } + if (countLines <= 0) { + return '' + } + let nlIndex = -1 + let newLinesFound = 0 + while (newLinesFound < countLines) { + const nextIndex = str.indexOf('\n', nlIndex + 1) + if (nextIndex === -1) { + return str + } + nlIndex = nextIndex + newLinesFound++ + } + + const nextIndex = str.indexOf('\n', nlIndex + 1) + return str.slice(0, nlIndex) + (nextIndex !== -1 ? '...' : '') +} + +function cropLongString(str) { + if (str.length > 500) { + return str.slice(0, 500) + '...' + } + return str +} + +async function consultancyRequest( + req, + res, + type, + url, + isAdminPage = false, + privilegeToSeAll = true // this method seperates consultancy main from admin, so all results get visible TO ALL REGISTERED USERS, not just admins +) { + const searchString = req.query.q?.trim() ?? '' + + let assignedConsultant + + if ( + !privilegeToSeAll && + req.user && + !(req.user.hasRole('portal admin') || req.user.hasRole('consultancy admin')) + ) { + assignedConsultant = req.user.id + } else { + assignedConsultant = undefined + } + + const filters = { + status: type, + assignedConsultant, + primaryDomain: req.query.pd + } + + if (!isAdminPage) { + filters.assignedConsultant = undefined + filters.status = 'published' // guard + } + + let hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + if (req.indexHitPageAmount) { + hitsPerPage = req.indexHitPageAmount + } + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const hitsQuery = generateQuery.consultancy( + searchString, + filters, + hitsPerPage, + page + ) + + const hits = await searchConsultancyEntryIndex(hitsQuery) + + const numberOfAllHits = hits.body.hits.total.value + const numberOfAllPages = Math.ceil(numberOfAllHits / hitsPerPage) + + let entries = prepareConsultancyEntries(hits) + // console.log({ entries, numberOfAllHits, numberOfAllPages }) + + entries = entries.map(entry => { + entry.primaryDomain = entry.primaryDomain + ? entry.primaryDomain.nameSl + : 'nedefinirano' + + if (entry.assignedConsultants) { + entry.firstName = entry.assignedConsultants[0]?.firstName + entry.lastName = entry.assignedConsultants[0]?.lastName + } + + if (entry.assignedConsultants && entry.assignedConsultants.length > 1) { + entry.sharedAuthors = [] + for (let i = 1; i < entry.assignedConsultants.length; i++) { + // skip first element (moderator) + entry.sharedAuthors.push( + `${entry.assignedConsultants[i].firstName} ${entry.assignedConsultants[i].lastName}` + ) + } + } + + if (entry.timeCreated) { + const date = new Date(entry.timeCreated) + + entry.formattedTimeCreated = `${date.getDate()}. ${ + date.getMonth() + 1 + }. ${date.getFullYear()}` + } + + return entry + }) + + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + // const entryList = await mapEntryList(inProgressEntryList) + const userList = await User.fetchConsultants() + + if (!isAdminPage) { + entries.map(entry => { + const MAX_CHARACTER_LENGTH = 200 + let appendAnswer = '' + let appendQuestion = '' + if (entry.answer && entry.answer.length > MAX_CHARACTER_LENGTH) { + appendAnswer = '...' + } + if (entry.question && entry.question.length > MAX_CHARACTER_LENGTH) { + appendQuestion = '...' + } + + entry.answerSummary = `${entry.answer.slice( + 0, + MAX_CHARACTER_LENGTH + )}${appendAnswer}` + + entry.question = `${entry.question.slice( + 0, + MAX_CHARACTER_LENGTH + )}${appendQuestion}` + + return entry + }) + } + + res.render(url, { + allPrimaryDomains, + entries, // entryList, + userList, + numberOfAllPages, + queryCount: numberOfAllHits + }) +} + +module.exports = { consultancy, consultancyAdmin } diff --git a/express/controllers/demo-paginacija.js b/express/controllers/demo-paginacija.js new file mode 100644 index 0000000..6b3cdbe --- /dev/null +++ b/express/controllers/demo-paginacija.js @@ -0,0 +1,17 @@ +const DemoPaginacija = require('../models/demo-paginacija') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') + +const demoPaginacija = {} + +demoPaginacija.izrišiStran = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = await DemoPaginacija.fetch( + resultsPerPage, + 1 + ) + + res.render('pages/demo-paginacija', { numberOfAllPages, results }) +} + +module.exports = demoPaginacija diff --git a/express/controllers/dictionaries.js b/express/controllers/dictionaries.js new file mode 100644 index 0000000..13762ff --- /dev/null +++ b/express/controllers/dictionaries.js @@ -0,0 +1,699 @@ +const { unlink } = require('fs/promises') +const { promisify } = require('util') +const multer = require('multer') +const debug = require('debug')('termPortal:controllers/dictionary') +const Dictionary = require('../models/dictionary') +const Entry = require('../models/entry') +const User = require('../models/user') +const Comment = require('../models/comment') +const genEditorAllQuery = require('../models/helpers/search/generate-query/editor/all') +const { searchEntryIndex } = require('../models/search-engine') +const { prepareEditorEntries } = require('../models/helpers/search') +const { getInstanceSetting } = require('../models/helpers') +const { DEFAULT_HITS_PER_PAGE, DATA_FILES_PATH } = require('../config/settings') +const { + statusChangeCheckAndAct, + determineNewStatus +} = require('./helpers/dictionary') +const SFDSuggestionImporter = require('./helpers/search-filter-data-suggestion-importer') +const Extraction = require('../models/extraction') + +const importFileBodyParser = multer({ + dest: `${DATA_FILES_PATH}/dict_import_temp`, + limits: { + fieldNameSize: 21, + fieldSize: 9, + fields: 3, + fileSize: 1000 * 1000 * 1000, // 1GB + headerPairs: 500 + }, + fileFilter: importFileFilter +}).single('dictionaryImportFile') +const parseImportFileBody = promisify(importFileBodyParser) + +const dictionary = {} + +dictionary.list = async (req, res) => { + let dictionaries + if (req.isAuthenticated()) { + dictionaries = await Dictionary.fetchAllByUser(req.user.id) + } + res.render('pages/dictionaries/list', { + title: 'Seznam slovarjev', + dictionaries + }) +} + +dictionary.new = async (req, res) => { + // TODO Once english language is implemented, gather selected language (sl/en) from request ~ (cookies?) + const language = 'name_sl' + const [allPrimaryDomains, allSecondaryDomains, allLanguages] = + await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Dictionary.fetchAllApprovedSecondaryDomains(), + Dictionary.fetchAllLanguages(language) + ]) + + res.render('pages/dictionaries/new', { + title: 'Nov slovar', + allPrimaryDomains, + allSecondaryDomains, + allLanguages + }) +} + +dictionary.create = async (req, res) => { + await Dictionary.create(req.body, req.user.id) + res.redirect('/slovarji/moji') +} + +dictionary.editDescription = async (req, res) => { + const { dictionaryId } = req.params + const [ + allPrimaryDomains, + allSecondaryDomains, + dictionary, + associatedSecondaryDomains + ] = await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Dictionary.fetchAllApprovedSecondaryDomains(), + Dictionary.fetchEditDescription(dictionaryId), + Dictionary.fetchSecondaryDomains(dictionaryId) + ]) + + res.render('pages/dictionaries/description', { + title: 'Ime in opis', + allPrimaryDomains, + allSecondaryDomains, + dictionary, + associatedSecondaryDomains + }) +} + +dictionary.updateDescription = async (req, res) => { + const { dictionaryId } = req.params + const { body } = req + + // TODO Consider using a transaction. + await Promise.all([ + Dictionary.updateDescription(dictionaryId, body), + Dictionary.deleteSecondaryDomains(dictionaryId, body), + Dictionary.updateSecondaryDomains(dictionaryId, body) + ]) + + res.redirect('back') +} + +dictionary.editUsers = async (req, res) => { + const dictionaryId = req.params.dictionaryId + const [dictionary, userRights, entriesCount, minEntries, publishApproval] = + await Promise.all([ + Dictionary.fetchEditUsers(dictionaryId), + User.fetchAllWithDictionaryRights(dictionaryId), + Dictionary.countPublishedEntries(dictionaryId), + getInstanceSetting('min_entries_per_dictionary'), + getInstanceSetting('dictionary_publish_approval') + ]) + + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/users' + break + case '/admin': + viewPath = 'pages/admin/dictionary-users' + } + + res.render(viewPath, { + title: 'Uporabniki', + dictionary, + userRights, + entriesCount, + minEntries, + publishApproval + }) +} + +dictionary.updateUsers = async (req, res) => { + // TODO Due to reindexing of all of dictionary entries on status change, this operation might take a while. + // TODO Stress test and consider either a notification to user or alteast a progress indicator while they wait. + const { dictionaryId } = req.params + const isPublished = req.body.isPublished === 'on' + + const newDictStatus = await determineNewStatus(isPublished) + + const { nameSl, status: oldDictStatus } = await Dictionary.fetchEditUsers( + dictionaryId + ) + + await Promise.all([ + Dictionary.updateUsers(dictionaryId, req.body, newDictStatus), + User.updateUserRights(dictionaryId, req.body.rightsPerUser) + ]) + + if (newDictStatus !== oldDictStatus) { + if (newDictStatus === 'published') { + await Dictionary.updateTimePublished(dictionaryId) + } + await Dictionary.indexIntoSearchEngine(dictionaryId) + } + + await statusChangeCheckAndAct.updateUsers( + dictionaryId, + isPublished, + oldDictStatus, + nameSl, + req.app, + req.user + ) + + res.redirect('back') +} + +dictionary.editStructure = async (req, res) => { + // TODO Once english language is implemented, gather selected language (sl/en) from request ~ (cookies?) + const language = 'name_sl' + const { dictionaryId } = req.params + const [dictionary, associatedLanguages, allLanguages] = await Promise.all([ + Dictionary.fetchEditStructure(dictionaryId), + Dictionary.fetchLanguages(dictionaryId), + Dictionary.fetchAllLanguages(language) + ]) + + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/structure' + break + case '/admin': + viewPath = 'pages/admin/dictionary-structure' + } + + res.render(viewPath, { + title: 'Struktura slovarskega sestavka', + dictionary, + associatedLanguages, + allLanguages + }) +} + +dictionary.updateStructure = async (req, res) => { + const { body } = req + const { dictionaryId } = req.params + + // TODO Consider using a transaction. + await Promise.all([ + Dictionary.updateStructure(dictionaryId, body), + Dictionary.deleteLanguages(dictionaryId), + Dictionary.updateLanguages(dictionaryId, body) + ]) + res.redirect('back') +} + +dictionary.editAdvanced = async (req, res) => { + const { dictionaryId } = req.params + const dictionaryName = await Dictionary.fetchName(dictionaryId) + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/advanced' + break + case '/admin': + viewPath = 'pages/admin/dictionary-advanced' + } + + res.render(viewPath, { + title: 'Napredno', + dictionary: { id: req.params.dictionaryId }, + dictionaryName + }) +} + +dictionary.comments = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + let viewPath + const { dictionaryId } = req.params + const type = 'dictionary' + const filters = { ctxType: type, ctxId: dictionaryId } + const [{ comments, pages_total: numberOfAllPages }, dictionaryName] = + await Promise.all([ + Comment.list(filters, req.user, resultsPerPage, 1), + Dictionary.fetchName(dictionaryId) + ]) + + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/dictionary-comments' + break + case '/admin': + viewPath = 'pages/admin/dictionary-comments' + } + + res.render(viewPath, { + title: 'Komentarji', + numberOfAllPages, + dictionary: { id: req.params.dictionaryId }, + comments, + dictionaryName + }) +} + +dictionary.showImportFromFileForm = async (req, res) => { + const { dictionaryId } = req.params + const [imports, dictionaryName] = await Promise.all([ + Dictionary.fetchAllImports(dictionaryId), + Dictionary.fetchName(dictionaryId) + ]) + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/import' + break + case '/admin': + viewPath = 'pages/admin/dictionary-import' + } + + res.render(viewPath, { + title: 'Uvoz iz datoteke', + dictionary: { id: dictionaryId }, + imports, + dictionaryName + }) +} + +dictionary.listAdminDictionaries = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = + await Dictionary.fetchAllAdminDictionaries(resultsPerPage, 1) + + res.render('pages/admin/dictionaries-list', { + title: 'Struktura slovarjev', + numberOfAllPages, + results + }) +} + +dictionary.adminEditDescription = async (req, res) => { + const { dictionaryId } = req.params + const [ + allPrimaryDomains, + allSecondaryDomains, + dictionary, + associatedSecondaryDomains, + status + ] = await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Dictionary.fetchAllApprovedSecondaryDomains(), + Dictionary.fetchEditDescription(dictionaryId), + Dictionary.fetchSecondaryDomains(dictionaryId), + Dictionary.fetchStatus(dictionaryId) + ]) + + res.render('pages/admin/dictionary-description', { + title: 'Podatki', + allPrimaryDomains, + allSecondaryDomains, + dictionary, + associatedSecondaryDomains, + status + }) +} + +dictionary.updateAdminDescription = async (req, res) => { + // TODO Due to reindexing of all of dictionary entries on status change, this operation might take a while. + // TODO Stress test and consider either a notification to user or alteast a progress indicator while they wait. + const { dictionaryId } = req.params + const { body } = req + const newDictStatus = body.status + + const oldDictStatus = await Dictionary.fetchStatus(dictionaryId) + + // TODO Consider using a transaction. + await Promise.all([ + Dictionary.updateDescription(dictionaryId, body), + Dictionary.deleteSecondaryDomains(dictionaryId, body), + Dictionary.updateSecondaryDomains(dictionaryId, body), + Dictionary.updateStatus(dictionaryId, body) + ]) + + if (newDictStatus !== oldDictStatus) { + if (newDictStatus === 'published') { + await Dictionary.updateTimePublished(dictionaryId) + } + await Dictionary.indexIntoSearchEngine(dictionaryId) + } + + await statusChangeCheckAndAct.updateAdminDescription( + dictionaryId, + newDictStatus, + oldDictStatus, + req.app, + req.user + ) + + res.redirect('back') +} + +dictionary.showImportFromExtractionForm = async (req, res) => { + const { dictionaryId } = req.params + const dictionaryName = await Dictionary.fetchName(dictionaryId) + const extractions = await Extraction.fetchFinishedForUser(req.user.id) + let viewPath, title + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/extraction-import' + title = 'Uvoz' + break + case '/admin': + viewPath = 'pages/admin/dictionary-extraction-import' + title = 'Uvoz luščenje' + } + + res.render(viewPath, { + title, + dictionary: { id: dictionaryId }, + dictionaryName, + extractions + }) +} + +dictionary.showExportToFileForm = async (req, res) => { + const { dictionaryId } = req.params + const dictionaryName = await Dictionary.fetchName(dictionaryId) + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/export' + break + case '/admin': + viewPath = 'pages/admin/dictionary-export' + } + + res.render(viewPath, { + title: 'Izvoz', + dictionary: { id: req.params.dictionaryId }, + dictionaryName + }) +} + +dictionary.editDomainLabels = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { dictionaryId } = req.params + const [{ pages_total: numberOfAllPages, results }, dictionaryName] = + await Promise.all([ + Dictionary.fetchPaginationDomainLabels(dictionaryId, resultsPerPage, 1), + Dictionary.fetchName(dictionaryId) + ]) + + let viewPath + switch (req.baseUrl) { + case '/slovarji': + viewPath = 'pages/dictionaries/domain-labels' + break + case '/admin': + viewPath = 'pages/admin/dictionary-domain-labels' + } + + res.render(viewPath, { + title: 'Področne oznake', + dictionary: { id: dictionaryId }, + numberOfAllPages, + results, + dictionaryName + }) +} + +dictionary.showContent = async (req, res) => { + const { dictionaryId } = req.params + const hitsQuery = genEditorAllQuery(dictionaryId) + const [ + hits, + canPublishEntriesInEdit, + dictionaryName, + structure, + languages, + entryDomainLabels + ] = await Promise.all([ + searchEntryIndex(hitsQuery), + getInstanceSetting('can_publish_entries_in_edit'), + Dictionary.fetchName(dictionaryId), + Dictionary.fetchEditStructure(dictionaryId), + Dictionary.fetchLanguages(dictionaryId), + Dictionary.fetchDomainLabels(dictionaryId) + ]) + + const terms = prepareEditorEntries(hits) + + res.render('pages/dictionaries/content', { + title: 'Vsebina slovarja', + terms, + canPublishEntriesInEdit, + dictionaryName, + structure, + languages, + dictionaryId, + entryDomainLabels + }) +} + +dictionary.showSecondaryDomains = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = + await Dictionary.fetchAllSecondaryDomains(resultsPerPage, 1) + + res.render('pages/admin/areas', { + title: 'Podpodročja', + numberOfAllPages, + results + }) +} + +dictionary.dictionaryList = async (req, res) => { + /* const [allPrimaryDomains, allSecondaryDomains, allLanguages] = + await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Dictionary.fetchAllApprovedSecondaryDomains(), + Dictionary.fetchAllLanguages() + ]) */ + + // const defaultportalname = await getInstanceSetting('portal_name') + const defaultportalcode = await getInstanceSetting('portal_code') + + const hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = +req.query.p > 0 ? +req.query.p : 1 + + // initial mapping + // mapping done here to not expose database info to public + const orderIndex = false + const orderAttribute = 'd' + + let dictionaries = await Dictionary.fetchBasicInfoPerPageFilteredWithOrdering( + '', + {}, + hitsPerPage, + page, + orderAttribute, + orderIndex + ) + + const numberOfAllHits = parseInt( + (await Dictionary.fetchAllDictionariesCount()).count + ) + const numberOfAllPages = Math.ceil(numberOfAllHits / hitsPerPage) + + const allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + + dictionaries = dictionaries.map(e => { + if (!e.portalcode) { + e.portalcode = defaultportalcode + // e.portalname = defaultportalname + } + return e + }) + + const isDictionaryListPage = true + + res.render('pages/dictionaries/dictlist', { + title: 'Seznam slovarjev', + dictionaries, + allPrimaryDomains, + numberOfAllPages, + isDictionaryListPage + /* + allSecondaryDomains, + allLanguages */ + }) +} + +dictionary.dictionaryDetails = async (req, res) => { + const { absolutePrevPath, sentFromEntryId } = req.query + const dictId = req.params.dictionaryId + const { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals + } = await SFDSuggestionImporter.initialize() + + const dictionaryData = await Dictionary.fetchDictionaryBasicInfo(dictId) + + const filters = { ctxType: 'dictionary', ctxId: dictId } + // TODO: integrate numberOfAllPages, commentCount with pug + + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = 1 // +req.query.p > 0 ? +req.query.p : 1 + const { + pages_total: numberOfAllPages, + comments, + comment_count: commentCount + } = await Comment.list(filters, req.user, resultsPerPage, page) + + // check if it is a local dictionary + if (!dictionaryData.portalname && !dictionaryData.portalcode) { + dictionaryData[0].portalname = await getInstanceSetting('portal_name') + dictionaryData[0].portalcode = await getInstanceSetting('portal_code') + } + + const reducedData = dictionaryData.reduce( + (acc, x) => { + if (acc.isbegin) { + x.languages = [x.languagesl] + x.subDomains = [x.domainsecondarysl] + return x + } + if (!acc.languages.includes(x.languagesl)) { + acc.languages.push(x.languagesl) + } + if (!acc.subDomains.includes(x.domainsecondarysl)) { + acc.subDomains.push(x.domainsecondarysl) + } + + return acc + }, + { isbegin: true } + ) + + const structData = { + prevWindowTitle: 'Nazaj', + dictName: dictionaryData[0].dictionarysl, + portalCode: dictionaryData[0].portalcode, + portalName: dictionaryData[0].portalname, + fullAuthorName: reducedData.author ? reducedData.author.join(', ') : '', + areas: dictionaryData[0].domain_primary, + subareas: reducedData.subDomains ? reducedData.subDomains.join(', ') : '', + languages: reducedData.languages ? reducedData.languages.join(', ') : '' + } + + if (reducedData.author) { + if (reducedData.author.length > 2) { + structData.authorLabel = 'Avtorji' + } else if (reducedData.author.length === 2) { + structData.authorLabel = 'Avtorja' + } else if (reducedData.author.length === 1) { + structData.authorLabel = 'Avtor' + } + } + + if (sentFromEntryId === 'dictsList') { + structData.prevHref = `/slovarji` + } else { + structData.prevHref = `/termin/${sentFromEntryId}` + } + + const finalData = { + ...reducedData, + ...structData + } + + res.render('pages/search/result-detail-dictionary', { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals, + sentFromEntryId, + dictId, + absolutePrevPath, + dictionaryData, + finalData, + numberOfAllPages, + comments, + commentCount + }) // todo +} + +dictionary.importFromFile = async (req, res) => { + try { + await parseImportFileBody(req, res) + // TODO return JSON error response rather then delegate to express. + // TODO Also return proper status codes. + // TODO File (or other form data) cound not be present. Add validation or fallback/errorhandling. + + const { dictionaryId } = req.params + const importFilePath = req.file.path + const { deleteExistingEntries, entryStatus, importFileFormat } = req.body + + await Dictionary.openImportFileJob( + dictionaryId, + deleteExistingEntries, + importFileFormat + ) + + if (deleteExistingEntries) { + await Entry.deleteAllFromIndex(dictionaryId) + await Entry.deleteAll(dictionaryId) + } + + await Dictionary.importFromFile( + req.user.id, + dictionaryId, + importFilePath, + entryStatus + ) + // TODO Rather then waiting for success/failure, return immediately and continue processing in the background. + // TODO Also add API endpoint for getting progress. + + await Dictionary.indexIntoSearchEngine(dictionaryId) + // TODO Error --> import job status: (indexing) error --> User manually triggers reindex. + + debug('IMPORT SUCCESSFUL') + + const importProcessId = 'DUMMY ID' // TODO You'll get it from DB. + res.status(202).send(importProcessId) + } catch (error) { + // TODO Consider writing a property on req and add an extra error handler for API errors. + debug('IMPORT FAILED') + debug(error) + res.status(400).send(error) + } finally { + try { + await unlink(req.file.path) + } catch (error) { + debug('ERROR REMOVING TEMP IMPORT FILE:') + debug(error) + } + } +} + +function importFileFilter(req, file, cb) { + if (file.mimetype !== 'text/xml') return cb(Error('Invalid file type')) + cb(null, true) +} + +/* +function commaSeperationReducer(dictionaryData) { + return dictionaryData.reduce((acc, x) => { + if (acc === ':://') { + return x + } else { + return `${acc}, ${x}` + } + }, ':://') +} */ + +module.exports = dictionary diff --git a/express/controllers/extraction-poc.js b/express/controllers/extraction-poc.js new file mode 100644 index 0000000..0674127 --- /dev/null +++ b/express/controllers/extraction-poc.js @@ -0,0 +1,150 @@ +const { mkdir } = require('fs/promises') +const { + getDocumentsPath, + getStopTermsPath +} = require('../models/helpers/extraction') +const { checkIfcanBegin } = require('./helpers/extraction') +const { MAX_EXTRACTIONS_PER_USER } = require('../config/settings') +const Extraction = require('../models/extraction') +const Dictionary = require('../models/dictionary') +const Domain = require('../models/domain') +const { intoDbArray } = require('../models/helpers') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') + +const extraction = {} + +extraction.list = async (req, res) => { + let extractions = await Extraction.fetchAllForUser(req.user.id) + extractions = await Promise.all( + extractions.map(async extraction => { + extraction.canBegin = await checkIfcanBegin(extraction) + if (extraction.status === 'finished') { + extraction.termCandidatesCount = + await Extraction.fetchTermCandidatesCount(extraction.id) + } + return extraction + }) + ) + res.render('extraction-poc/list', { extractions }) +} + +extraction.create = async (req, res) => { + const extractionCount = await Extraction.countAllForUser(req.user.id) + if (extractionCount >= MAX_EXTRACTIONS_PER_USER) { + // TODO Tukaj bo treba prikazati tudi obvestilo uporabniku skladno s trenutno metodologijo prikaza obvestil. + return res.redirect(303, 'back') + } + + const extractionName = `Luščenje ${extractionCount + 1}` + const { extractionType } = req.body + + let extractionId + if (extractionType === 'own') { + extractionId = await Extraction.createOwn(req.user.id, extractionName) + + const documentsPath = getDocumentsPath(extractionId) + const stopTermsPath = getStopTermsPath(extractionId) + await Promise.all([ + mkdir(documentsPath, { recursive: true }), + mkdir(stopTermsPath, { recursive: true }) + ]) + } else { + extractionId = await Extraction.createOss(req.user.id, extractionName) + + const stopTermsPath = getStopTermsPath(extractionId) + await mkdir(stopTermsPath, { recursive: true }) + } + + // Redirect to extraction edit page. + res.redirect(`poc/${extractionId}`) +} + +extraction.edit = async (req, res) => { + const extractionId = req.params.id + const extraction = await Extraction.fetch(extractionId) + + if (extraction.ossParams) { + const [allPrimaryDomains, stopTermsFiles] = await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Extraction.fetchAllStopTermsFilesStats(extractionId) + ]) + const { params } = extraction.ossParams + const domainUdk = params?.domainUdk?.[0] + if (domainUdk) + extraction.domainId = await Domain.fetchIdByUdkCode(domainUdk) + extraction.documentType = intoDbArray(params.documentType, 'always') + extraction.year = intoDbArray(params.year, 'always') + extraction.keywords = intoDbArray(params.keywords, 'always') + + res.render('extraction-poc/edit-oss', { + id: extractionId, + extraction, + allPrimaryDomains, + stopTermsFiles + }) + } else { + const [extractionDocuments, stopTermsFiles] = await Promise.all([ + Extraction.fetchAllDocumentsStats(extractionId), + Extraction.fetchAllStopTermsFilesStats(extractionId) + ]) + res.render('extraction-poc/edit-own', { + id: extractionId, + extraction, + extractionDocuments, + stopTermsFiles + }) + } +} + +extraction.updateOwn = async (req, res) => { + const extractionId = req.params.id + await Extraction.update(extractionId, req.body.name) + + // Reload page. + res.redirect(`./${extractionId}`) +} + +extraction.docsEdit = async (req, res) => { + const extractionId = req.params.id + const extractionDocuments = await Extraction.fetchAllDocumentsStats( + extractionId + ) + + res.render('extraction-poc/docs-edit', { + id: extractionId, + extractionDocuments + }) +} + +extraction.stopTermsEdit = async (req, res) => { + const extractionId = req.params.id + const stopTermsFiles = await Extraction.fetchAllStopTermsFilesStats( + extractionId + ) + + res.render('extraction-poc/stop-terms-edit', { + id: extractionId, + stopTermsFiles + }) +} + +extraction.listTermCandidates = async (req, res) => { + const extractionId = req.params.id + const termCandidatesJson = await Extraction.fetchTermCandidatesJson( + extractionId + ) + const termCandidates = JSON.parse(termCandidatesJson).terminoloski_kandidati + const hitsPerPage = +req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const numberOfAllPages = Math.ceil(termCandidates.length / hitsPerPage) + const firstPageOfTermCandidates = termCandidates.slice(0, hitsPerPage) + + res.render('extraction-poc/term-candidates', { + extractionId, + termCandidatesJson, + firstPageOfTermCandidates, + hitsPerPage, + numberOfAllPages + }) +} + +module.exports = extraction diff --git a/express/controllers/extraction.js b/express/controllers/extraction.js new file mode 100644 index 0000000..e8653a2 --- /dev/null +++ b/express/controllers/extraction.js @@ -0,0 +1,156 @@ +const { mkdir } = require('fs/promises') +const { + getDocumentsPath, + getStopTermsPath +} = require('../models/helpers/extraction') +const { checkIfcanBegin } = require('./helpers/extraction') +const { MAX_EXTRACTIONS_PER_USER } = require('../config/settings') +const Extraction = require('../models/extraction') +const Dictionary = require('../models/dictionary') +const Domain = require('../models/domain') +const { intoDbArray } = require('../models/helpers') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') + +const extraction = {} + +extraction.list = async (req, res) => { + let extractions = [] + if (req.user) { + extractions = await Extraction.fetchAllForUser(req.user.id) + extractions = await Promise.all( + extractions.map(async extraction => { + extraction.canBegin = await checkIfcanBegin(extraction) + if (extraction.status === 'finished') { + extraction.termCandidatesCount = + await Extraction.fetchTermCandidatesCount(extraction.id) + } + return extraction + }) + ) + } + + res.render('pages/extraction/list', { title: 'Luščenje seznam', extractions }) +} + +extraction.create = async (req, res) => { + const extractionCount = await Extraction.countAllForUser(req.user.id) + if (extractionCount >= MAX_EXTRACTIONS_PER_USER) { + // TODO Tukaj bo treba prikazati tudi obvestilo uporabniku skladno s trenutno metodologijo prikaza obvestil. + return res.redirect(303, 'back') + } + + const extractionName = `Luščenje ${extractionCount + 1}` + const { extractionType } = req.body + + let extractionId + if (extractionType === 'own') { + extractionId = await Extraction.createOwn(req.user.id, extractionName) + + const documentsPath = getDocumentsPath(extractionId) + const stopTermsPath = getStopTermsPath(extractionId) + await Promise.all([ + mkdir(documentsPath, { recursive: true }), + mkdir(stopTermsPath, { recursive: true }) + ]) + } else { + extractionId = await Extraction.createOss(req.user.id, extractionName) + + const stopTermsPath = getStopTermsPath(extractionId) + await mkdir(stopTermsPath, { recursive: true }) + } + + // Redirect to extraction edit page. + res.redirect(`luscenje/${extractionId}`) +} + +extraction.edit = async (req, res) => { + const extractionId = req.params.id + const extraction = await Extraction.fetch(extractionId) + + if (extraction.ossParams) { + const [allPrimaryDomains, stopTermsFiles] = await Promise.all([ + Dictionary.fetchAllPrimaryDomains(), + Extraction.fetchAllStopTermsFilesStats(extractionId) + ]) + const { params } = extraction.ossParams + const domainUdk = params?.domainUdk?.[0] + if (domainUdk) + extraction.domainId = await Domain.fetchIdByUdkCode(domainUdk) + extraction.documentType = intoDbArray(params.documentType, 'always') + extraction.year = intoDbArray(params.year, 'always') + extraction.keywords = intoDbArray(params.keywords, 'always') + + res.render('pages/extraction/edit-oss', { + title: 'KAS + dokumenti', + id: extractionId, + extraction, + allPrimaryDomains, + stopTermsFiles + }) + } else { + const [extractionDocuments, stopTermsFiles] = await Promise.all([ + Extraction.fetchAllDocumentsStats(extractionId), + Extraction.fetchAllStopTermsFilesStats(extractionId) + ]) + res.render('pages/extraction/edit-own', { + title: 'Besedila', + id: extractionId, + extraction, + extractionDocuments, + stopTermsFiles + }) + } +} + +extraction.updateOwn = async (req, res) => { + const extractionId = req.params.id + await Extraction.update(extractionId, req.body.name) + + // Reload page. + res.redirect(`./${extractionId}`) +} + +extraction.docsEdit = async (req, res) => { + const extractionId = req.params.id + const extractionDocuments = await Extraction.fetchAllDocumentsStats( + extractionId + ) + + res.render('pages/extraction/docs-edit', { + id: extractionId, + extractionDocuments + }) +} + +extraction.stopTermsEdit = async (req, res) => { + const extractionId = req.params.id + const stopTermsFiles = await Extraction.fetchAllStopTermsFilesStats( + extractionId + ) + + res.render('pages/extraction/stop-terms-edit', { + id: extractionId, + stopTermsFiles + }) +} + +extraction.listTermCandidates = async (req, res) => { + const extractionId = req.params.id + const termCandidatesJson = await Extraction.fetchTermCandidatesJson( + extractionId + ) + const termCandidates = JSON.parse(termCandidatesJson).terminoloski_kandidati + const hitsPerPage = +req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const numberOfAllPages = Math.ceil(termCandidates.length / hitsPerPage) + const firstPageOfTermCandidates = termCandidates.slice(0, hitsPerPage) + + res.render('pages/extraction/term-candidates', { + extractionId, + termCandidatesJson, + firstPageOfTermCandidates, + hitsPerPage, + numberOfAllPages + }) +} + +module.exports = extraction diff --git a/express/controllers/helpers/dictionary.js b/express/controllers/helpers/dictionary.js new file mode 100644 index 0000000..31bbd62 --- /dev/null +++ b/express/controllers/helpers/dictionary.js @@ -0,0 +1,211 @@ +const { getInstanceSetting } = require('../../models/helpers') +const Dictionary = require('../../models/dictionary') +const cache = require('../../models/cache') +const { promisify } = require('util') +const email = require('../../models/email') + +const MIN_ENTRIES_MAIL_NAMESPACE = 'below_min_entries_mail_sent' + +// Helper object for minEntries below. Defines operations on anti-spam bookmarks. +const minEntriesEmailBookmark = { + // Checks whether the anti-spam bookmark (still) exists. + async exists(dictionaryId) { + const bookMarkName = `${MIN_ENTRIES_MAIL_NAMESPACE}:${dictionaryId}` + return !!(await cache.exists(bookMarkName)) + }, + + // Sets the anti-spam bookmark for given dictionary. + async set(dictionaryId) { + const bookMarkName = `${MIN_ENTRIES_MAIL_NAMESPACE}:${dictionaryId}` + await cache.set(bookMarkName, true) + }, + + // Removes the anti-spam bookmark for given dictionary if conditions are met. + async update(dictionaryId) { + const doesBookmarkExist = await this.exists(dictionaryId) + if (!doesBookmarkExist) return + const minEntries = await getInstanceSetting('min_entries_per_dictionary') + const isBelowMinEntriesThreshold = await checkIfBelowMinEntriesThreshold( + dictionaryId, + minEntries + ) + + if (isBelowMinEntriesThreshold) return + + const bookMarkName = `${MIN_ENTRIES_MAIL_NAMESPACE}:${dictionaryId}` + await cache.unlink(bookMarkName) + } +} + +// Exports actions related to checking and acting on minimum entries per dictionary setting. +exports.minEntriesRequirementCheckAndAct = { + // Checks required criteria and sends notifications emails if required. + async onDelete(dictionaryId, appRef) { + const minEntries = await getInstanceSetting('min_entries_per_dictionary') + + // Only proceed if a valid and positive minimum entries per dictionary setting is set. + if (!(+minEntries > 0)) return + + const [isBelowMinEntriesThreshold, wasEmailAlreadySent] = await Promise.all( + [ + checkIfBelowMinEntriesThreshold(dictionaryId, minEntries), + minEntriesEmailBookmark.exists(dictionaryId) + ] + ) + + if (!isBelowMinEntriesThreshold || wasEmailAlreadySent) return + + // Prepare and send notification emails. + const [nameSl, adminEmails, dictionariesAdminEmails] = await Promise.all([ + Dictionary.fetchName(dictionaryId), + Dictionary.fetchAdminEmails(dictionaryId), + Dictionary.fetchDictionariesAdminEmails() + ]) + + const allEmailsSet = new Set([...adminEmails, ...dictionariesAdminEmails]) + const allEmails = [] + for (const email of allEmailsSet) allEmails.push(email) + + const type = 'delete' + const renderAsync = promisify(appRef.render.bind(appRef)) + const emailHtml = await renderAsync('email/dictionary-status-change', { + type, + nameSl + }) + + await email.send({ + to: allEmails, + subject: 'Obvestilo o številu gesel', + html: emailHtml + }) + + await minEntriesEmailBookmark.set(dictionaryId) + }, + + // Use this method after any entry updating operations to release potential anti-spam bookmarks. + onUpdate: minEntriesEmailBookmark.update.bind(minEntriesEmailBookmark) +} + +// Helper function to check if a given (published) dictionary has less entries than provided minEntries parameter. +async function checkIfBelowMinEntriesThreshold(dictionaryId, minEntries) { + const [publishedEntries, dictionaryStatus] = await Promise.all([ + Dictionary.countPublishedEntries(dictionaryId), + Dictionary.fetchStatus(dictionaryId) + ]) + + const isBelowMinEntriesThreshold = + +publishedEntries < +minEntries && dictionaryStatus === 'published' + + return isBelowMinEntriesThreshold +} + +// Determine new dictionary status based on dictionary_publish_approval setting. +exports.determineNewStatus = async isPublished => { + const publishApproval = await getInstanceSetting( + 'dictionary_publish_approval' + ) + + let newStatus + if (publishApproval === 'F') { + newStatus = isPublished ? 'published' : 'closed' + } else { + newStatus = isPublished ? 'reviewed' : 'closed' + } + + return newStatus +} + +// Exports actions related to checking and acting on dictionary status changes. +exports.statusChangeCheckAndAct = { + // Notify dictionaries admins by email on dictionary status changes. + async updateUsers( + dictionaryId, + isPublishedNew, + oldDictStatus, + nameSl, + appRef, + user + ) { + const isPublishedOld = oldDictStatus === 'published' + + // Published: on -> off. + if (!isPublishedNew && isPublishedOld) { + const dictionariesAdminEmails = + await Dictionary.fetchDictionariesAdminEmails() + const type = 'unpublish' + + await renderAndSendStatusChangeEmails( + appRef, + type, + user.email, + nameSl, + dictionariesAdminEmails + ) + + // Published: off -> on. + } else if (isPublishedNew && !isPublishedOld) { + const [isApprovalRequired, dictionariesAdminEmails] = await Promise.all([ + getInstanceSetting('dictionary_publish_approval'), + Dictionary.fetchDictionariesAdminEmails() + ]) + const type = + isApprovalRequired === 'T' ? 'publish-approval' : 'publish-no-approval' + + await renderAndSendStatusChangeEmails( + appRef, + type, + user.email, + nameSl, + dictionariesAdminEmails + ) + } + }, + + // Notify dictionary admins by email after dictionaries admins + // change dictionary status from reviewed to either closed or published. + async updateAdminDescription( + dictionaryId, + statusNew, + statusOld, + appRef, + user + ) { + if (statusOld === 'reviewed' && statusNew !== 'reviewed') { + const [nameSl, adminEmails] = await Promise.all([ + Dictionary.fetchName(dictionaryId), + Dictionary.fetchAdminEmails(dictionaryId) + ]) + const type = 'status' + + await renderAndSendStatusChangeEmails( + appRef, + type, + user.email, + nameSl, + adminEmails + ) + } + } +} + +// Helper function used by statusChangeCheckAndAct methods. +async function renderAndSendStatusChangeEmails( + appRef, + type, + changerEmail, + nameSl, + targetEmails +) { + const renderAsync = promisify(appRef.render.bind(appRef)) + const emailHtml = await renderAsync('email/dictionary-status-change', { + type, + changerEmail, + nameSl + }) + + await email.send({ + to: targetEmails, + subject: 'Sprememba stanja slovarja', + html: emailHtml + }) +} diff --git a/express/controllers/helpers/extraction.js b/express/controllers/helpers/extraction.js new file mode 100644 index 0000000..1e7c182 --- /dev/null +++ b/express/controllers/helpers/extraction.js @@ -0,0 +1,11 @@ +const Extraction = require('../../models/extraction') + +// Check if extraction process can be started. +exports.checkIfcanBegin = async extraction => { + if (extraction.status !== 'new') return false + + if (extraction.ossParams) return extraction.ossParams.status === 'confirmed' + + const documentsNames = await Extraction.fetchAllDocumentsNames(extraction.id) + return !!documentsNames.length +} diff --git a/express/controllers/helpers/search-filter-data-suggestion-importer.js b/express/controllers/helpers/search-filter-data-suggestion-importer.js new file mode 100644 index 0000000..1e4e3bc --- /dev/null +++ b/express/controllers/helpers/search-filter-data-suggestion-importer.js @@ -0,0 +1,34 @@ +const Dictionary = require('../../models/dictionary') +const Portal = require('../../models/portal') +const { getInstanceSetting } = require('../../models/helpers') + +const helper = {} + +helper.initialize = async () => { + const initializers = {} + + // TODO Once english language is implemented, gather selected language (sl/en) from request ~ (cookies?) + const language = 'name_sl' + + // TODO Consider parallelizing following queries. Single vs pooled clients? + initializers.allPrimaryDomains = await Dictionary.fetchAllPrimaryDomains() + initializers.sourceLanguages = await Dictionary.fetchAllLanguages(language) + initializers.targetLanguages = initializers.sourceLanguages.filter( + // drop slovene language + l => l.id !== 32 + ) + + initializers.allDictionaryNames = await Dictionary.fetchAll() + + initializers.portals = [] + initializers.portals.push({ + name: await getInstanceSetting('portal_name'), + code: await getInstanceSetting('portal_code') + }) + + initializers.portals.concat(await Portal.fetchAll()) + + return initializers +} + +module.exports = helper diff --git a/express/controllers/index.js b/express/controllers/index.js new file mode 100644 index 0000000..d50982d --- /dev/null +++ b/express/controllers/index.js @@ -0,0 +1,386 @@ +const Entry = require('../models/entry') +const { getInstanceSetting } = require('../models/helpers') +const Dictionary = require('../models/dictionary') +const Comment = require('../models/comment') +const { searchEntryIndex } = require('../models/search-engine') +const { intoDbArray } = require('../models/helpers') +const { + prepareEntries, + prepareAggregation, + prepareSeachFilterData +} = require('../models/helpers/search') +const generateQuery = require('../models/helpers/search/generate-query') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') +const SFDSuggestionImporter = require('./helpers/search-filter-data-suggestion-importer') +const User = require('../models/user') + +// TODO Luka (note to self): Measure performance, consider caching. +exports.index = async (req, res) => { + const { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals + } = await SFDSuggestionImporter.initialize() + + const englishLanguageEnabled = false // dummy variable for future edit + + const latestDicts = await Dictionary.fetchLatest3DictsByPublishDate( + englishLanguageEnabled + ) + + const portalName = await getInstanceSetting('portal_name') + const portalDescription = await getInstanceSetting('portal_description') + + const isRoot = true + + res.render('pages/index', { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals, + latestDicts, + portalName, + portalDescription, + isRoot + }) +} + +exports.search = async (req, res) => { + const searchString = req.query.q?.trim() + + if (!searchString) return res.redirect('/') + + const { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals + } = await SFDSuggestionImporter.initialize() + + const filters = { + sourceLanguages: intoDbArray(req.query.sl, 'always'), + targetLanguages: intoDbArray(req.query.tl, 'always'), + primaryDomains: intoDbArray(req.query.pd, 'always'), + dictionaries: intoDbArray(req.query.d, 'always'), + sources: intoDbArray(req.query.s, 'always') + } + + const hitsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const page = +req.query.p > 0 ? +req.query.p : 1 + + const [hitsQuery, aggregateQuery] = await generateQuery.main( + searchString, + filters, + hitsPerPage, + page, + true + ) + + const [hits, aggregationRaw] = await Promise.all([ + searchEntryIndex(hitsQuery), + searchEntryIndex(aggregateQuery) + ]) + + const numberOfAllHits = hits.body.hits.total.value + const numberOfAllPages = Math.ceil(numberOfAllHits / hitsPerPage) + + // TODO If there's no hits, this is probably the place where suggestions/related queries and processing would happen. + + let entriesByCategory = prepareEntries(hits) + + // Similar to search query without any extra filters, this is required for modal to diplay ALL res. + // const allAggregation = await indexAllResultsNoFiltering(req, res) + + const aggregation = await prepareAggregation(aggregationRaw) + const searchFilterData = prepareSeachFilterData(aggregation, filters) + + // TODO Luka (note to self): Consider reworking Miha's logic below. It's hacky and possibly error prone. + // TODO copied code below, maybe refactor to a helper function? + // check express/controllers/api/v1/search.js listMainEntries + entriesByCategory = Object.entries(entriesByCategory).reduce( + (acc, category, index) => { + acc[category[0]] = category[1].map(entry => { + if (entry.foreignEntries) { + entry.foreignEntries = entry.foreignEntries.map(fe => { + fe.terms = fe.terms ? fe.terms.filter(term => !!term) : [] + fe.synonyms = fe.synonyms + ? fe.synonyms.filter(synonym => !!synonym) + : [] + fe.nbspCount = fe.terms.length + fe.synonyms.length - 1 + return fe + }) + } + + return entry + }) + return acc + }, + {} + ) + + const count = Object.values(entriesByCategory).reduce((acc, cat, idx) => { + return acc + cat.length + }, 0) + + // filter to 5 resuts per search filter + Object.entries(searchFilterData).forEach(([key, value]) => { + searchFilterData[key] = value.filter((p, i) => { + return i < 5 + }) + }) + + // todo implement ALL disabled in pug view if required + const disabledSideMenuFilters = { + sourceLanguages: searchString === '*', + targetLanguages: false, + primaryDomains: false, + dictionaries: false, + sources: false + } + + if (count < 1) { + return res.render('pages/search/no-results', { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals, + searchString, + entriesByCategory, + searchFilterData, + disabledSideMenuFilters, + // allAggregation, + numberOfAllHits, + numberOfAllPages, + page + }) + } + + // TODO Add a page title? + res.render('pages/search/results', { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals, + searchString, + entriesByCategory, + searchFilterData, + disabledSideMenuFilters, + // allAggregation, + numberOfAllHits, + numberOfAllPages, + page + }) +} + +exports.entryDetails = async (req, res) => { + const termId = req.params.entryId + + /* const [entry, domainLabels] = await Promise.all([ + Entry.fetchFullWithOrderedForeignLanguages(termId), + Dictionary.fetchDomainLabelsFromEntryId(termId) + ]) */ + + const entry = await Entry.fetchFullWithOrderedForeignLanguages(termId) + + /* const entryData = { + entry + // allDomainLabelsJoined: domainLabels.map(e => e.name).join(', ') + } */ + + // unnecessary legacy assigment, refactor when time is available + const entryData = entry + + const { + allPrimaryDomains, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals + } = await SFDSuggestionImporter.initialize() + + const [dictStruct, dictionaryData, selectedDomainLabelsForEntry] = + await Promise.all([ + Dictionary.fetchDictionaryWithEditStructure(entry.dictionary_id), + Dictionary.fetchDictionaryBasicInfo(entry.dictionary_id), + Entry.fetchDomainLabels(termId) + ]) + + /// + + const filters = { ctxType: 'entry_dict_ext', ctxId: termId } + // TODO: integrate numberOfAllPages, commentCount with pug + + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const page = 1 // +req.query.p > 0 ? +req.query.p : 1 + const { + pages_total: numberOfAllPages, + comments, + comment_count: commentCount + } = await Comment.list(filters, req.user, resultsPerPage, page) + + /// + + // check if it is a local dictionary + if (!dictionaryData.portalname && !dictionaryData.portalcode) { + dictionaryData[0].portalname = await getInstanceSetting('portal_name') + dictionaryData[0].portalcode = await getInstanceSetting('portal_code') + } + + const reducedData = dictionaryData.reduce( + (acc, x) => { + if (acc.isbegin) { + x.languages = [x.languagesl] + x.subDomains = [x.domainsecondarysl] + return x + } + if (!acc.languages.includes(x.languagesl)) { + acc.languages.push(x.languagesl) + } + if (!acc.subDomains.includes(x.domainsecondarysl)) { + acc.subDomains.push(x.domainsecondarysl) + } + + return acc + }, + { isbegin: true } + ) + + const { structure } = dictStruct + + // Improved version of entropy, but some data duplications still exist + // struct data contains important data and re-maps for unification (maybe refactor later) + const structData = { + termId: termId, + prevWindowTitle: 'Iskanje', + prevHref: '/iskanje', + portalCode: dictionaryData[0].portalcode, + portalName: dictionaryData[0].portalname, + dictName: structure.nameSl, + dictHref: `/slovarji/${structure.id}/o-slovarju?sentFromEntryId=${termId}`, + fullAuthorName: reducedData.author ? reducedData.author.join(', ') : '', + areas: dictionaryData[0].domain_primary, + subareas: reducedData.subDomains ? reducedData.subDomains.join(', ') : '', + languages: reducedData.languages ? reducedData.languages.join(', ') : '' + } + + if (reducedData.author) { + if (reducedData.author.length > 2) { + structData.authorLabel = 'Avtorji' + } else if (reducedData.author.length === 2) { + structData.authorLabel = 'Avtorja' + } else if (reducedData.author.length === 1) { + structData.authorLabel = 'Avtor' + } + } + + const finalData = { + ...reducedData, + ...structData + } + + let selectedDomainLabelsForEntryString = '' + if (selectedDomainLabelsForEntry.length) { + selectedDomainLabelsForEntryString = mergeDomains( + selectedDomainLabelsForEntry, + (acc, n) => { + if (acc === '') return n.name + else return acc + ', ' + n.name + } + ) + } + + /* entryData.entry.foreign_entries.forEach((val, idx) => { + entry.foreignEntries[idx] = await + }) */ + + const langs = await Dictionary.fetchLanguages(entryData.dictionary_id) + entryData.foreign_entries.forEach((val, idx) => { + try { + entry.foreign_entries[idx].name_sl = langs[idx].nameSl + entry.foreign_entries[idx].name_en = langs[idx].nameEn + } catch (e) {} + }) + + res.render('pages/search/result-detail', { + allPrimaryDomains, + entryData, + sourceLanguages, + targetLanguages, + allDictionaryNames, + portals, + termId, + structure, + finalData, + selectedDomainLabelsForEntryString, + numberOfAllPages, + comments, + commentCount + }) +} + +exports.myProfile = async (req, res) => { + res.render('pages/profile/my-profile', { title: 'Moj račun' }) +} + +exports.changePassword = async (req, res) => { + res.render('pages/profile/change-password', { title: 'Spremeni geslo' }) +} + +exports.userSettings = async (req, res) => { + const hitsPerPageArr = await User.fetchAllowedHitsPerPage() + res.render('pages/profile/change-profile-settings', { + title: 'Nastavitve računa', + hitsPerPageArr, + hitsForUser: req.user?.hitsPerPage + }) +} + +function mergeDomains( + domainList, + aggregationFn = (acc, n) => { + if (acc === '') return n + else return acc + ', ' + n + } +) { + return Array.from(domainList).reduce(aggregationFn, '') +} + +function filterResults(entries) { + let mode = 0 + const termLst = [] + const ftermLst = [] + const otherLst = [] + entries.forEach(entry => { + switch (entry._title) { + case 'term': + mode = 0 + break + case 'foreignTerm': + mode = 1 + break + case 'other': + mode = 2 + } + + switch (mode) { + case 0: + termLst.push(entry) + break + case 1: + ftermLst.push(entry) + break + case 2: + otherLst.push(entry) + break + } + }) + + return [termLst, ftermLst, otherLst] +} diff --git a/express/controllers/portals.js b/express/controllers/portals.js new file mode 100644 index 0000000..4c15990 --- /dev/null +++ b/express/controllers/portals.js @@ -0,0 +1,140 @@ +const portal = {} +const Portal = require('../models/portal') +const Comment = require('../models/comment') +const { clearCachedInstanceSettings } = require('../models/helpers') +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') + +portal.instanceSettings = async (req, res) => { + const portal = await Portal.fetchInstanceSettings() + + res.render('pages/admin/portal', { + title: 'Nastavitve portala', + portal + }) +} + +portal.updateInstaceSettings = async (req, res) => { + const payload = req.body + await Portal.updateInstaceSettings(payload) + await clearCachedInstanceSettings() + res.redirect('/admin/nastavitve/portal') +} + +portal.instanceDictSettings = async (req, res) => { + const dictionary = await Portal.fetchInstanceDictSettings() + + res.render('pages/admin/settings-dictionaries', { + title: 'Nastavitve slovarjev', + dictionary + }) +} + +portal.updateInstanceDictSettings = async (req, res) => { + const payload = req.body + await Portal.updateInstaceDictSettings(payload) + await clearCachedInstanceSettings() + res.redirect('/admin/nastavitve/slovarji') +} + +portal.instanceConsultancySettings = async (req, res) => { + const consultancy = await Portal.fetchInstanceConsultancySettings() + res.render('pages/admin/portal-consultancy-settings', { + title: 'Nastavitve svetovalnice', + consultancy + }) +} + +portal.updateInstanceConusltacySettings = async (req, res) => { + const payload = req.body + await Portal.updateInstaceConsultancySettings(payload) + await clearCachedInstanceSettings() + res.redirect('/admin/nastavitve/svetovalnica') +} + +portal.new = async (req, res) => { + res.render('pages/admin/new-connection', { + title: 'Nova povezava' + }) +} + +portal.list = async (req, res) => { + const allLinkedPortals = await Portal.fetchAll() + + res.render('pages/admin/connections-list', { + title: 'Seznam povezav', + allLinkedPortals + }) +} + +portal.fetchPortal = async (req, res) => { + const portalId = req.params.portalId + const portal = await Portal.fetchPortal(portalId) + + res.render('pages/admin/portal-edit', { title: 'Uredi povezavo', portal }) +} + +portal.updatePortal = async (req, res) => { + const portalId = req.params.portalId + const payload = req.body + await Portal.update(portalId, payload) + res.redirect('/admin/povezave/seznam') +} + +portal.fetchSelectedLinkedDictionaries = async (req, res) => { + const linkedId = req.params.portalId + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = + await Portal.fetchSelectedLinkedDictionaries(linkedId, resultsPerPage, 1) + + res.render('pages/admin/portal-list-dict', { + title: 'Slovarji portala', + linkedId, + numberOfAllPages, + results + }) +} + +portal.updateSelectedDictionaries = async (req, res) => { + const linkedId = req.params.portalId + await Portal.updateSelectedDictionaries(linkedId, req.body) + res.redirect('back') +} + +portal.fetchAllLinkedDictionaries = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = + await Portal.fetchAllLinkedDictionaries(resultsPerPage, 1) + + res.render('pages/admin/portals-all-linked-dictionaries', { + title: 'Povezani', + numberOfAllPages, + results + }) +} + +portal.updateAllDictionaries = async (req, res) => { + await Portal.updateAllDictionaries(req.body) + res.redirect('back') +} + +portal.comments = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + const type = 'portal' + const filters = { ctxType: type } + const { comments, pages_total: numberOfAllPages } = await Comment.list( + filters, + req.user, + resultsPerPage, + 1 + ) + res.render('pages/admin/comments', { + title: 'Komentarji', + numberOfAllPages, + dictionary: { id: req.params.dictionaryId }, + comments + }) +} + +module.exports = portal diff --git a/express/controllers/users.js b/express/controllers/users.js new file mode 100644 index 0000000..3ad7f86 --- /dev/null +++ b/express/controllers/users.js @@ -0,0 +1,142 @@ +const { randomBytes } = require('crypto') +const { promisify } = require('util') +const passport = require('passport') +const User = require('../models/user') +const email = require('../models/email') +const { origin } = require('../config/keys') +const { rememberMeCookieSettings } = require('../config/settings') +const RandomBytesAsync = promisify(randomBytes) +const { DEFAULT_HITS_PER_PAGE } = require('../config/settings') + +const user = {} + +user.register = async (req, res) => { + // TODO Add validation. + const userId = await User.create(req.body) + const activationToken = (await RandomBytesAsync(32)).toString('hex') + await User.saveActivationToken(userId, activationToken) + const { email: userEmail, username } = req.body + let activationLink = new URL('/users/activate', origin) + activationLink.searchParams.set('token', activationToken) + activationLink = activationLink.href + const renderAsync = promisify(req.app.render.bind(req.app)) + const emailHtml = await renderAsync('email/user-activation', { + username, + activationLink + }) + await email.send({ + to: userEmail, + subject: 'Aktivacija računa', + html: emailHtml + }) + res.send('Registracija uspešna') +} + +user.activateAccount = async (req, res) => { + // TODO Add validation. What if user is already logged in? What if account is already active? ... + const { token } = req.query + const user = await User.fetchByActivationToken(token) + await User.activateAccount(user) + const loginAsync = promisify(req.login.bind(req)) + await loginAsync(user) + res.redirect('/') +} + +user.login = async (req, res, next) => { + passport.authenticate( + 'local', + { + badRequestMessage: + 'Nepravilno uporabniško ime, elektronski naslov ali geslo.' + }, + async (err, user, info) => { + if (err) return next(err) + + if (!user) { + const err = Error(info.message) + err.status = 403 + err.displayInProd = true + return next(err) + } + + const loginAsync = promisify(req.login.bind(req)) + await loginAsync(user) + + if (req.body.rememberMe) { + // TODO Consider what happens if the user already has a remember me token. + const rememberMeToken = await User.generateRememberMeToken() + await User.saveRememberMeToken(user, rememberMeToken) + res.cookie('remember_me', rememberMeToken, rememberMeCookieSettings) + } + + res.send('Prijava uspešna') + } + )(req, res, next) +} + +user.logout = async (req, res) => { + const rememberMeToken = req.signedCookies.remember_me + + if (rememberMeToken) { + res.clearCookie('remember_me') + await User.clearRememberMeToken(rememberMeToken) + } + + req.logout() + // Manually clear session.passport due to bug in current passport version. + delete req.session.passport.user + res.redirect('/') +} + +user.list = async (req, res) => { + const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE + + const { pages_total: numberOfAllPages, results } = await User.fetchAll( + resultsPerPage, + 1 + ) + res.render('pages/admin/user-list', { + title: 'Seznam slovarjeva', + numberOfAllPages, + results + }) +} + +user.listAllWithPortalRoles = async (req, res) => { + const users = await User.fetchAllWithPortalRoles() + res.render('pages/admin/user-portals', { title: 'Seznam slovarjev', users }) +} + +user.findByUsernameOrEmail = async (req, res) => { + const userNameEmail = req.query.userNameEmail + const searchedUser = await User.findByUsernameOrEmail(userNameEmail) + res.send(searchedUser) +} + +user.updateRoles = async (req, res) => { + await User.updatePortalRoles(req.body.rolesPerUser) + res.redirect('back') +} + +user.adminEdit = async (req, res) => { + const userId = req.params.userId + const [userData, userRoles] = await Promise.all([ + User.fetchUser(userId), + User.fetchUserRoles(userId) + ]) + res.render('pages/admin/user-edit', { + title: 'Urejanje uporabnikov', + userData, + userRoles + }) +} + +// TODO Aljaž: Luka, please adjust update function for updating user's password and email +// TODO Handle username unique constraint failure. +user.adminUpdate = async (req, res) => { + const { userId } = req.params + await User.updateUser(userId, req.body) + res.redirect('back') +} + +module.exports = user diff --git a/express/middleware/auth.js b/express/middleware/auth.js new file mode 100644 index 0000000..6e832c4 --- /dev/null +++ b/express/middleware/auth.js @@ -0,0 +1,113 @@ +const passport = require('passport') +const LocalStrategy = require('passport-local').Strategy +const RememberMeStrategy = require('passport-remember-me-extended').Strategy +const bcrypt = require('bcrypt') +const db = require('../models/db') +const User = require('../models/user') +const { + rememberMeCookieSettings, + REMEMBER_ME_DURATION_SQL +} = require('../config/settings') + +passport.serializeUser((user, done) => { + done(null, user.id) +}) + +passport.deserializeUser(async (id, done) => { + try { + // TODO Consider storing this data in cache. + // TODO In that case, make sure to invalidate it at every (relevant) data change. + + const user = await User.fetchDeserializedDataById(id) + + // TODO Consider what to do if no user was found? + done(null, user) + } catch (error) { + done(error) + } +}) + +passport.use( + new LocalStrategy( + { usernameField: 'usernameOrEmail' }, + async (usernameOrEmail, password, done) => { + try { + const { rows } = await db.query( + 'SELECT id, status, bcrypt_hash FROM "user" WHERE username = $1 OR email = $1', + [usernameOrEmail] + ) + const user = rows[0] + + if (!user) { + return done(null, false, { + message: 'Nepravilno uporabniško ime, elektronski naslov ali geslo.' + }) + } + + if (user.status !== 'active') { + return done(null, false, { + message: + 'Uporabniški račun še ni aktiviran. Kliknite aktivacijsko povezavo, katero smo vam poslali po elektronski pošti.' + }) + } + + const isCorrectPassword = await bcrypt.compare( + password, + user.bcrypt_hash + ) + if (!isCorrectPassword) { + return done(null, false, { + message: 'Nepravilno uporabniško ime, elektronski naslov ali geslo.' + }) + } + + delete user.bcrypt_hash + done(null, user) + } catch (error) { + done(error) + } + } + ) +) + +passport.use( + new RememberMeStrategy( + { cookie: rememberMeCookieSettings, signed: true }, + async (token, done) => { + try { + const text = ` + DELETE + FROM user_token_remember_me t + WHERE + t.token = $1 + AND AGE(NOW(), t.time_created) < $2::INTERVAL + RETURNING (SELECT u.id FROM "user" u where u.id = t.user_id) + ` + const values = [token, REMEMBER_ME_DURATION_SQL] + + let { + rows: [user] + } = await db.query(text, values) + + if (!user) return done(null, false) + + user = await User.fetchDeserializedDataById(user.id) + + done(null, user) + } catch (error) { + done(error) + } + }, + async (user, done) => { + try { + const token = await User.generateRememberMeToken() + await User.saveRememberMeToken(user, token) + done(null, token) + } catch (error) { + done(error) + } + } + ) +) + +module.exports = passport diff --git a/express/middleware/index.js b/express/middleware/index.js new file mode 100644 index 0000000..5a5d861 --- /dev/null +++ b/express/middleware/index.js @@ -0,0 +1,6 @@ +const { getInstanceSetting } = require('../models/helpers') + +exports.enhanceLocals = async (req, res, next) => { + res.locals.portalCode = await getInstanceSetting('portal_code') + next() +} diff --git a/express/middleware/session.js b/express/middleware/session.js new file mode 100644 index 0000000..c1e7988 --- /dev/null +++ b/express/middleware/session.js @@ -0,0 +1,54 @@ +const session = require('express-session') +const RedisStore = require('connect-redis')(session) +const { secret, cookiesSecure } = require('../config/keys') +const redisClient = require('../models/cache') + +const SESSION_DURATION = 1000 * 60 * 60 * 2 // 2 hours. +const SESSION_ID_COOKIE_NAME = 'sid' +// const RETRY_PERIOD = 3000 // 3 seconds. + +const options = { + cookie: { maxAge: SESSION_DURATION, sameSite: 'lax', secure: cookiesSecure }, + secret, + name: SESSION_ID_COOKIE_NAME, + rolling: true, + resave: false, + saveUninitialized: false, + store: new RedisStore({ client: redisClient }) +} + +module.exports = session(options) + +// Aditional checking logic below. +// Export it instead of the middleware above if it proves necessary. + +// const sessionMiddleware = session(options) + +// function verifiedSession(req, res, next) { +// let tries = 3 +// let timeoutId + +// function lookupSession(err) { +// clearTimeout(timeoutId) + +// if (err) return next(err) + +// if (req.session !== undefined) return next() + +// tries -= 1 + +// if (tries < 0) { +// return next(Error('Session store unresponsive')) +// } + +// sessionMiddleware(req, res, lookupSession) + +// if (req.session === undefined) { +// timeoutId = setTimeout(lookupSession, RETRY_PERIOD) +// } +// } + +// lookupSession() +// } + +// module.exports = verifiedSession diff --git a/express/middleware/settings.js b/express/middleware/settings.js new file mode 100644 index 0000000..992c4df --- /dev/null +++ b/express/middleware/settings.js @@ -0,0 +1,23 @@ +const settings = {} +const { getInstanceSetting } = require('../models/helpers') + +settings.prepareRequiredSettings = async (req, res, next) => { + const isExtractionEnabled = + (await getInstanceSetting('is_extraction_enabled')) === 'T' + const isDictionariesEnabled = + (await getInstanceSetting('is_dictionaries_enabled')) === 'T' + const isConsultancyEnabled = + (await getInstanceSetting('is_consultancy_enabled')) === 'T' + + // req.extractionEnabled = isExtractionEnabled + // req.dictionariesEnabled = isDictionariesEnabled + // req.consultancyEnabled = isConsultancyEnabled + + res.locals.extractionEnabled = isExtractionEnabled + res.locals.dictionariesEnabled = isDictionariesEnabled + res.locals.consultancyEnabled = isConsultancyEnabled + + next() +} + +module.exports = settings diff --git a/express/middleware/user.js b/express/middleware/user.js new file mode 100644 index 0000000..c71fc72 --- /dev/null +++ b/express/middleware/user.js @@ -0,0 +1,95 @@ +const user = {} + +user.enhance = (req, res, next) => { + // Make req.user available to view engine. + res.locals.user = req.user + + // Extend the req.user object with 3 rolechecking methods. + if (!req.user) return next() + req.user.hasRole = hasRole + req.user.hasDictionaryRole = hasDictionaryRole + req.user.hasAnyDictionaryRole = hasAnyDictionaryRole + req.user.isEditorOfConsultancyEntry = isEditorOfConsultancyEntry + + next() +} + +user.isDictionaryAdmin = (req, res, next) => { + const { dictionaryId } = req.params + const isAdmin = req.user.hasDictionaryRole(dictionaryId, 'administration') + + if (isAdmin) return next() + + if (req.isAjax) return res.status(400).end() + res.redirect(req.baseUrl) +} + +user.isDictionaryEditor = (req, res, next) => { + const { dictionaryId } = req.params + const isEditor = req.user.hasAnyDictionaryRole(dictionaryId) + + if (isEditor) return next() + + if (req.isAjax) return res.status(400).end() + res.redirect(req.baseUrl) +} + +/** + * Checks if the user has a specific role. + * + * @param {'portal admin'|'dictionaries admin'|'consultancy admin'|'consultant'|'editor'} roleName + * @returns {boolean} + */ +function hasRole(roleName) { + return this.userRoles.some(role => role.roleName === roleName) +} + +/** + * Checks if the user has a specific dictionary role. + * + * @param {number} dictionaryId + * @param {'administration'|'terminologyReview'|'languageReview'|'editing'} roleName + * @returns {boolean} + */ +function hasDictionaryRole(dictionaryId, roleName) { + return this.userRoles.some(role => { + const validDictionaryRoles = [ + 'administration', + 'editing', + 'terminologyReview', + 'languageReview' + ] + return ( + role.dictionaryId === +dictionaryId && + role.roleName === 'editor' && + validDictionaryRoles.includes(roleName) && + role[roleName] + ) + }) +} + +/** + * Checks if the user has any dictionary role for the specified dictionary. + * + * @param {number} dictionaryId + * @returns {boolean} + */ +function hasAnyDictionaryRole(dictionaryId) { + return this.userRoles.some(role => { + return role.dictionaryId === +dictionaryId && role.roleName === 'editor' + }) +} + +/** + * Checks if the user is an editor of the speficied consultancy entry. + * + * @param {number} consultancyEntryId + * @returns {boolean} + */ +function isEditorOfConsultancyEntry(consultancyEntryId) { + return this.assignedConsultancyEntries.some(entry => { + return entry.id === +consultancyEntryId + }) +} + +module.exports = user diff --git a/express/models/batch.js b/express/models/batch.js new file mode 100644 index 0000000..c54b567 --- /dev/null +++ b/express/models/batch.js @@ -0,0 +1,119 @@ +const debug = require('debug')('app:batch') +// const db = require('../models/db') + +function update(dbc, report, status, done) { + const reps = JSON.stringify(report) + debug('update', status, reps.length) + if (status === 'D' || status === 'F') { + dbc.query( + 'UPDATE batch SET report=$1, job_state=$2, ended=now(), changed=now() WHERE id=$3', + [reps, status, report.id], + err => { + done(err) + } + ) + } else { + dbc.query( + 'UPDATE batch SET report=$1, changed=now() WHERE id=$2', + [reps, report.id], + err => { + done(err) + } + ) + } +} + +module.exports = { + Report: function (jobName, threadId) { + this.id = 0 + this.name = jobName + this.thread = threadId + this.warnings = 0 + this.progress = { + total_percent: 0, + phase_name: '', + phase_percent: 0, + item_name: '' + } + this.trace = [] // here we push messages and errors + }, + + /** + * initializes batch tracker by adding a record to batch table + * @param job_name name of the job + * @param done (err, BatchId) + */ + init: function (dbc, report, done) { + debug('initializing', report) + dbc.query( + 'INSERT INTO batch (job_name, job_state, thread, report) VALUES($1,$2,$3,$4) RETURNING id', + [report.name, 'R', report.thread, JSON.stringify(report)], + (err, result) => { + if (err) return done(err) + debug(result) + report.id = result.rows[0].id + done() + } + ) + }, + + /** + * Close the batch by marking its status as completed and setting end_time. + * @param report object containing full batch report + * @param msg final message + * @param done + */ + finalize: function (dbc, report, msg, done) { + debug('finalizing', msg) + if (msg) report.trace.push(msg) + else report.trace.push('done') + update(dbc, report, 'D', done) + }, + + /** + * Report on phase. If phase name changes add new phase message to trace. + * @param report object containing full batch report + * @param phase name of phase + * @param percentJob percent (total for job) + * @param done + */ + reportPhase: function (dbc, report, phase, percentJob, done) { + debug('phase', phase, percentJob) + if (report.progress.phase_name !== phase) { + report.trace.push('starting phase ' + phase) + report.progress.phase_percent = 0 + report.progress.item_name = '' + } + report.progress.phase_name = phase + report.progress.total_percent = percentJob + update(dbc, report, '', done) + }, + + /** + * Report on item processed. This is sublevel of phase + * @param report object containing full batch report + * @param item name of item + * @param percentPhase percent of current phase done + * @param done + */ + reportItem: function (dbc, report, item, percentPhase, done) { + debug('item', item, percentPhase) + report.progress.item_name = item + report.progress.phase_percent = percentPhase + update(dbc, report, '', done) + }, + + /** + * Report error during process and close batch with status Failed and setting end_time. + * @param report object containing full batch report + * @param err the error. If it contains stack it will be included in trace + * @param done + */ + fail: function (dbc, report, err, done) { + debug('fail', err) + if (err.stack) report.trace.push(err.stack) + else if (err.message) report.trace.push(err.message) + else report.trace.push(JSON.stringify(err)) + update(dbc, report, 'F', done) + } +} diff --git a/express/models/cache.js b/express/models/cache.js new file mode 100644 index 0000000..f544391 --- /dev/null +++ b/express/models/cache.js @@ -0,0 +1,18 @@ +const Redis = require('ioredis') +const debug = require('debug')('termPortal:models/cache') + +const client = new Redis({ host: 'redis' }) + +client.on('error', debug) + +const isReadyPromise = new Promise(resolve => client.on('ready', resolve)) + +client.waitForConnection = async () => { + // eslint-disable-next-line no-console + console.log('Waiting for cache to be ready') + await isReadyPromise + // eslint-disable-next-line no-console + console.log('Cache is ready') +} + +module.exports = client diff --git a/express/models/comment.js b/express/models/comment.js new file mode 100644 index 0000000..366c845 --- /dev/null +++ b/express/models/comment.js @@ -0,0 +1,432 @@ +const db = require('./db') +const debug = require('debug')('termPortal:models/comment') +const User = require('../models/user') + +class Comment { + // Deserialize flat data into an organized comment object. + constructor({ + id, + message, + author_first_name: authorFirstName, + author_last_name: authorLastName, + time_created: timeCreated, + status, + quote_message: quoteMessage, + quote_author_first_name: quoteAuthorFirstName, + quote_author_last_name: quoteAuthorLastName, + quote_time_created: quoteTimeCreated + }) { + this.id = id + this.message = message + this.author = { firstName: authorFirstName, lastName: authorLastName } + this.timeCreated = timeCreated + this.status = status + + this.quote = quoteMessage + ? { + message: quoteMessage, + author: { + firstName: quoteAuthorFirstName, + lastName: quoteAuthorLastName + }, + timeCreated: quoteTimeCreated + } + : null + } + + // Fetch comments from DB. + static async list(filters, user, resultsPerPage, page) { + const { ctxType, ctxId } = filters + + if (!ctxType) throw Error('Missing context type') + + const values = [resultsPerPage, ctxType] + + let whereClause = 'WHERE c.context_type = $2' + + if (ctxId) { + whereClause += ' AND c.context_id = $3' + values.push(ctxId) + } + + const nonModeratedContexts = ['entry_dict_int', 'entry_consult_int'] + // In internal/non-moderated contexts, fetch all context specific comments and never show visibility toggles. + // In external/moderated contexts, for users with elevated context related rights, show all comments and show visibility toggles, + // for everyone else, show only visible comments and don't show visibility toggles. + let displayVisibilityToggles = false + if (!nonModeratedContexts.includes(ctxType)) { + let isCommentModerator = false + if (user) { + switch (ctxType) { + case 'portal': + if (user.hasRole('portal admin')) isCommentModerator = true + break + + case 'dictionary': + if ( + user.hasRole('portal admin') || + user.hasRole('dictionaries admin') + ) { + isCommentModerator = true + } + break + + case 'consultancy': + if ( + user.hasRole('portal admin') || + user.hasRole('consultancy admin') + ) { + isCommentModerator = true + } + break + + case 'entry_dict_ext': + if ( + user.hasRole('portal admin') || + user.hasRole('consultancy admin') || + user.hasDictionaryRole(ctxId, 'administration') + ) { + isCommentModerator = true + } + break + + default: + throw Error('Invalid context type') + } + } + + if (isCommentModerator) { + displayVisibilityToggles = true + } else { + whereClause += " AND c.status = 'visible'" + } + } + + let offsetValue + if (page === 'last') { + offsetValue = `(SELECT (CEIL(COUNT(*) / $1::float) - 1) * $1 FROM comment c ${whereClause})` + } else { + offsetValue = resultsPerPage * (page - 1) + } + + const text = ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM comment c + ${whereClause} + ), + 'comment_count', ( + SELECT COUNT(*) + FROM comment c + ${whereClause} + ), + 'comments', ARRAY( + SELECT jsonb_build_object( + 'id', c.id, + 'message', c.message, + 'timeCreated', c.time_created, + 'status', c.status, + 'author', ( + SELECT jsonb_build_object( + 'firstName', cu.first_name, + 'lastName', cu.last_name + ) + ), + 'showEye', ${displayVisibilityToggles}, + 'quote', ( + SELECT + CASE + WHEN c.quoted_comment_id IS NULL THEN NULL + ELSE jsonb_build_object( + 'message', q.message, + 'timeCreated', q.time_created, + 'author', ( + SELECT jsonb_build_object( + 'firstName', qu.first_name, + 'lastName', qu.last_name + ) + ) + ) + END + ) + ) + FROM comment c + LEFT JOIN "user" cu + ON cu.id = c.author_id + LEFT JOIN comment q + ON q.id = c.quoted_comment_id + LEFT JOIN "user" qu + ON qu.id = q.author_id + ${whereClause} + ORDER BY c.time_created + LIMIT $1 + OFFSET ${offsetValue} + ) + ) results` + const { rows } = await db.query(text, values) + + const { results } = rows[0] + return results + } + + // Insert a new comment into DB. + static async create(comment, userId) { + const text = + 'INSERT INTO comment (message, author_id, context_type, context_id, quoted_comment_id) VALUES ($1, $2, $3, $4, $5)' + const values = [ + comment.message, + userId, + comment.ctxType, + comment.ctxId, + comment.quoteId + ] + + await db.query(text, values) + } + + static async updateStatus(status, id) { + const values = [id, status] + const text = ` + UPDATE comment + SET status = $1 + WHERE id = $2` + await db.query(text, values) + } + + // Insert a new demo comment into DB. + static async createDemo(comment) { + const text = + "INSERT INTO comment (message, author_id, context_type, quoted_comment_id) VALUES ($1, $2, 'portal', $3) RETURNING id" + const values = [comment.message, pickRandomMockUserId(), comment.quoteId] + const { rows } = await db.query(text, values) + const idOfInsertedComment = rows[0].id + const text2 = `${selectAllCommentsQueryString} WHERE c.id = ${idOfInsertedComment}` + const { rows: rows2 } = await db.query(text2) + + const insertedComment = rows2[0] + + const deserializedComment = new this(insertedComment) + + return deserializedComment + } + + // Seed DB with random comments. + static async seed(commentCount) { + const seedTasks = [] + + for (let i = 0; i < commentCount; i++) { + seedTasks.push(this.createDemo({ message: pickRandomMockMessage() })) + } + + const seededComments = await Promise.all(seedTasks) + debug(`Successfully seeded ${commentCount} comments`) + debug('Comments:') + seededComments.forEach(comment => debug(comment)) + } + + // Clear all comments from DB. + static async clear() { + await db.query('TRUNCATE comment') + } +} + +// Base SQL query string to fetch all comments. +// Can be extended with a WHEN filter clause. +const selectAllCommentsQueryString = `SELECT +c.id, +c.message, +cu.first_name author_first_name, +cu.last_name author_last_name, +c.time_created, +c.status, +q.message quote_message, +qu.first_name quote_author_first_name, +qu.last_name quote_author_last_name, +q.time_created quote_time_created +FROM comment c +LEFT JOIN "user" cu +ON cu.id = c.author_id +LEFT JOIN comment q +ON q.id = c.quoted_comment_id +LEFT JOIN "user" qu +ON qu.id = q.author_id` + +// A list of messages of varying length for DB seeding. +const mockMessageVariations = [ + 'Lorem ipsum dolor sit amet.', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem obcaecati ut reprehenderit explicabo, adipisci atque! Repudiandae eos facilis veniam modi.', + 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab dicta error architecto id soluta laborum pariatur saepe doloribus voluptatem voluptas totam placeat, inventore rem! Tempore illum deleniti esse nemo. Amet.', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tristique at sem eu ultricies. Curabitur cursus efficitur ipsum, et iaculis ipsum egestas vel egestas vestibulum nec odio posuere, mollis diam et, bibendum velit. Proin non velit nec dui luctus dolor.', + 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Eveniet deleniti ad quasi, ea, recusandae esse autem expedita tempora molestiae ipsa labore magnam dolorem nostrum, corrupti sint obcaecati. Voluptatum molestiae, qui laudantium voluptatibus eius, ratione voluptate, eaque quae alias dicta pariatur?' +] + +// A list of users for DB seeding and random asigning to new +// comments until authentication and session mechanism are in place. +const mockUsers = [ + { firstName: 'Primož', lastName: 'Roglič' }, + { firstName: 'Tadej', lastName: 'Pogačar' }, + { firstName: 'Krištof', lastName: 'Kolumb' }, + { firstName: 'Rudolf', lastName: 'Maister' }, + { firstName: 'Ricky', lastName: 'Rickardo' }, + { firstName: 'Freddy', lastName: 'Mercury' }, + { firstName: 'Roger', lastName: 'Moore' }, + { firstName: 'Michael', lastName: 'Jackson' }, + { firstName: 'John', lastName: 'Elton' }, + { firstName: 'Harry', lastName: 'Potter' } +] + +function pickRandomMockMessage() { + return mockMessageVariations[ + Math.floor(Math.random() * mockMessageVariations.length) + ] +} + +function pickRandomMockUserId() { + return Math.ceil(Math.random() * mockUsers.length) +} + +async function seedMockUsersInDb() { + const { rows } = await db.query('SELECT COUNT(*) user_count FROM "user"') + const userCount = rows[0].user_count + if (+userCount) return 'Users already exist' + + await Promise.all( + mockUsers.map(async user => { + const text = + 'INSERT INTO "user"(username, first_name, last_name, email, bcrypt_hash) VALUES ($1, $2, $3, $4, \'dummyBcryptHash\') RETURNING *' + const values = [ + `${user.firstName}_${user.lastName}`, + user.firstName, + user.lastName, + `${user.firstName}.${user.lastName}@rsdo.com` + ] + const { rows } = await db.query(text, values) + const createdUser = rows[0] + debug(`Created user: ${JSON.stringify(createdUser)}`) + }) + ) + return 'Successfully seeded all users' +} + +async function seedPortalAdmin() { + const MOCK_ADMIN_BASE = 'admin' + + const { + rows: [mockAdmin] + } = await db.query('SELECT id FROM "user" WHERE username = $1', [ + MOCK_ADMIN_BASE + ]) + + if (mockAdmin) { + return `Portal admin already exists (username: ${MOCK_ADMIN_BASE}, password: ${MOCK_ADMIN_BASE})` + } + + const adminUser = { + username: MOCK_ADMIN_BASE, + firstName: MOCK_ADMIN_BASE, + lastName: MOCK_ADMIN_BASE, + password: MOCK_ADMIN_BASE, + email: `${MOCK_ADMIN_BASE}@rsdo.com` + } + const userId = await User.create(adminUser) + const assignAdminRole = db.query( + `INSERT INTO user_role (user_id, role_name) + VALUES + ($1, 'portal admin'), + ($1, 'dictionaries admin'), + ($1, 'consultancy admin'), + ($1, 'consultant')`, + [userId] + ) + const activateAdminUser = db.query( + `UPDATE "user" SET status = 'active', time_activated = time_registered WHERE username = $1`, + [adminUser.username] + ) + await Promise.all([assignAdminRole, activateAdminUser]) + return `Successfully seeded portal admin (username: ${MOCK_ADMIN_BASE}, password: ${MOCK_ADMIN_BASE})` +} + +async function seedConsultants() { + const { + rows: [mockConsultancyAdmin] + } = await db.query('SELECT id FROM "user" WHERE username = $1', ['cadmin']) + + if (mockConsultancyAdmin) { + return "Consultants already exist: 'cadmin', 'consultant1', 'consultant2', 'consultant3'" + } + + const cadminUser = { + username: 'cadmin', + firstName: 'cadmin', + lastName: 'cadmin', + password: 'cadmin', + email: 'cadmin@rsdo.com' + } + const userId = await User.create(cadminUser) + const assignConsultancyAdminRole = db.query( + `INSERT INTO user_role (user_id, role_name) + VALUES + ($1, 'consultancy admin')`, + [userId] + ) + const activateConsultancyAdminUser = db.query( + `UPDATE "user" SET status = 'active', time_activated = time_registered WHERE username = $1`, + [cadminUser.username] + ) + await Promise.all([assignConsultancyAdminRole, activateConsultancyAdminUser]) + + for (let i = 1; i <= 3; i++) { + const consultant = { + username: `consultant${i}`, + firstName: `consultant${i}`, + lastName: `consultant${i}`, + password: `consultant${i}`, + email: `consultant${i}@rsdo.com` + } + const userId = await User.create(consultant) + const assignConsultantRole = db.query( + `INSERT INTO user_role (user_id, role_name) + VALUES + ($1, 'consultant')`, + [userId] + ) + const activateConsultant = db.query( + `UPDATE "user" SET status = 'active', time_activated = time_registered WHERE username = $1`, + [consultant.username] + ) + await Promise.all([assignConsultantRole, activateConsultant]) + } + + return `Successfully seeded consultants 'cadmin', 'consultant1', 'consultant2', 'consultant3'` +} + +Comment.seedDummyData = () => { + // Seed DB with mock users on empty DB. + // seedMockUsersInDb() + // .then(debug) + // .catch(err => { + // debug('Users not seeded.') + // debug(err) + // }) + + // Seed DB with mock portal admin user on empty DB. + // TODO Replace with a more robust solution for production. + seedPortalAdmin() + .then(debug) + .catch(err => { + debug('Portal admin not seeded.') + debug(err) + }) + + // Seed DB with mock consultancy admin and consultant users on empty DB. + // seedConsultants() + // .then(debug) + // .catch(err => { + // debug('Consultants not seeded.') + // debug(err) + // }) +} + +module.exports = Comment diff --git a/express/models/consultancy-entry.js b/express/models/consultancy-entry.js new file mode 100644 index 0000000..9dae4e2 --- /dev/null +++ b/express/models/consultancy-entry.js @@ -0,0 +1,754 @@ +const db = require('./db') +const { + searchEngineClient, + deleteConsultancyEntriesFromIndex, + CONSULTANCY_ENTRY_INDEX +} = require('./search-engine') +const { removeHtmlTags } = require('./helpers') + +class ConsultancyEntry { + constructor({ + id, + id_external: idExternal, + time_created: timeCreated, + status, + author_id: authorId, + institution, + description, + domain_primary_id_initial: domainPrimaryIdInitial, + existing_solutions: existingSolutions, + examples_of_use: examplesOfUse, + time_published: timePublished, + title, + question, + answer, + path, + answer_authors: answerAuthors, + domain_primary_id: domainPrimaryId, + first_name: firstName, + last_name: lastName, + is_moderator: isModerator, + formatted_time_created: formattedTimeCreated, + formatted_time_published: formattedTimePublished + }) { + this.id = id + this.idExternal = idExternal + this.timeCreated = timeCreated + this.status = status + this.authorId = authorId + this.institution = institution + this.description = description + this.domainPrimaryIdInitial = domainPrimaryIdInitial + this.existingSolutions = existingSolutions + this.examplesOfUse = examplesOfUse + this.timePublished = timePublished + this.title = title + this.question = question + this.answer = answer + this.path = path + this.answerAuthors = answerAuthors + this.domainPrimaryId = domainPrimaryId + this.firstName = firstName + this.lastName = lastName + this.isModerator = isModerator + this.formattedTimeCreated = formattedTimeCreated + this.formattedTimePublished = formattedTimePublished + } + + // Fetch all consultancy entries from DB. + static async fetchAll() { + // TODO Luka: Miha, define specific fields instead of using *. + const { rows: fetchedConsEntries } = await db.query(` + SELECT * + FROM consultancy_entry + ORDER BY time_created DESC`) + const deserializedConsEntries = fetchedConsEntries.map( + consEntry => new this(consEntry) + ) + return deserializedConsEntries + } + + // Fetch consultancy entry by ID + // to_char(time_created,'HH24:MI:SS DD/MM/YYYY') + static async fetchByIdWithFormattedTime(id) { + const { rows: fetchedConsEntry } = await db.query( + ` + SELECT + + id, + id_external, + to_char(time_created,'DD. MM. YYYY') time_created, + status, + author_id, + institution, + description, + domain_primary_id_initial, + existing_solutions, + examples_of_use, + to_char(time_published,'DD. MM. YYYY') time_published, + title, + question, + answer, + path, + answer_authors, + domain_primary_id + + FROM consultancy_entry + WHERE id=$1`, + [id] + ) + + return new this(fetchedConsEntry[0]) + } + + static async fetchById(id) { + const { rows: fetchedConsEntry } = await db.query( + ` + SELECT + + id, + id_external, + to_char(time_created, 'DD. MM. YYYY') time_created, + status, + author_id, + institution, + description, + domain_primary_id_initial, + existing_solutions, + examples_of_use, + to_char(time_published,'DD. MM. YYYY') time_published, + title, + question, + answer, + path, + answer_authors, + domain_primary_id + + FROM consultancy_entry + WHERE id=$1`, + [id] + ) + + return new this(fetchedConsEntry[0]) + } + + // Fetch dictionaries admin emails. + static async fetchConsultancyAdminEmails() { + const query = { + text: ` + SELECT email FROM "user" WHERE id + IN(SELECT user_id FROM user_role + WHERE role_name = 'consultancy admin')`, + rowMode: 'array' + } + + const { rows: users } = await db.query(query) + const emails = users.flat() + return emails + } + + static async fetchModeratorEmail(entryId) { + const query = { + text: ` + SELECT email FROM "user" WHERE id + IN (SELECT user_id FROM consultancy_entry_consultant cec + WHERE cec.entry_id=$1 AND cec.is_moderator=true)`, + rowMode: 'array' + } + + const { rows: users } = await db.query(query, [entryId]) + const emails = users.flat() + return emails + } + + // Fetch all consultancy entries filtered by status from DB. + static async fetchAllByStatus(status) { + // TODO Luka: Miha, define specific fields instead of using *. + const sqlQuery = ` + SELECT *, to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created + FROM consultancy_entry + WHERE status=$1 + ORDER BY time_created DESC` + + const values = [status] + const { rows: fetchedConsEntries } = await db.query(sqlQuery, values) + + const deserializedConsEntries = fetchedConsEntries.map( + consEntry => new this(consEntry) + ) + return deserializedConsEntries + } + + // Fetch all consultancy entries filtered by status from DB. + static async fetchAllByStatusCount(status) { + // TODO Luka: Miha, define specific fields instead of using *. + const sqlQuery = ` + SELECT COUNT(id) + FROM consultancy_entry + WHERE status=$1` + + const values = [status] + const { rows } = await db.query(sqlQuery, values) + + return rows[0].count + } + + static async fetchWithStatusByIdCount(status, id) { + const sqlQuery = ` + SELECT COUNT(DISTINCT(ce.id)) + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1 and cec.user_id=$2` + const values = [status, id] + const { rows } = await db.query(sqlQuery, values) + + return rows[0].count + } + + static async fetchWithStatusById(status, id) { + const sqlQuery = ` + SELECT ce.id, + to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created, + author_id, + institution, + description, + domain_primary_id_initial, + to_char(time_published, 'FMDD. FMMM. YYYY') time_published, + title, + question, + answer, + path, + answer_authors, + domain_primary_id, + first_name, + last_name, + cec.is_moderator + + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1 and cec.user_id=$2 + ORDER BY time_created DESC` + + /* filter them in pug by displaying moderator, and showing authors + of non moderator */ + /* AND cec.is_moderator='true';` */ + + const values = [status, id] + const { rows: fetchedConsEntries } = await db.query(sqlQuery, values) + + const deserializedConsEntries = fetchedConsEntries.map( + consEntry => new this(consEntry) + ) + return deserializedConsEntries + } + + static async fetchInProgressById(id) { + return await this.fetchWithStatusById('in progress', id) + } + + static async fetchPublishedById(id) { + return await this.fetchWithStatusById('published', id) + } + + // Fetch entry count. + static async fetchAllByStatusWithAuthorDataCount(status) { + const sqlQuery = ` + SELECT COUNT(DISTINCT(ce.id)) + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1` + + /* filter them in pug by displaying moderator, and showing authors + of non moderator */ + /* AND cec.is_moderator='true';` */ + + const values = [status] + const { rows } = await db.query(sqlQuery, values) + await db.query(sqlQuery, values) + return rows[0].count + } + + // Fetch all consultancy entries filtered by status from DB. + static async fetchAllByStatusWithAuthorData(status) { + const sqlQuery = ` + SELECT ce.id, + to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created, + author_id, + institution, + description, + domain_primary_id_initial, + to_char(time_published, 'FMDD. FMMM. YYYY') time_published, + title, + question, + answer, + path, + answer_authors, + domain_primary_id, + first_name, + last_name, + cec.is_moderator + + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1 + ORDER BY time_created DESC` + + /* filter them in pug by displaying moderator, and showing authors + of non moderator */ + /* AND cec.is_moderator='true';` */ + + const values = [status] + const { rows: fetchedConsEntries } = await db.query(sqlQuery, values) + + const deserializedConsEntries = fetchedConsEntries.map( + consEntry => new this(consEntry) + ) + return deserializedConsEntries + } + + // Fetch all new consultancy entries from DB. + static async fetchAllNew() { + const newEntries = await this.fetchAllByStatus('new') + return newEntries + } + + static async fetchAllRejected() { + const newEntries = await this.fetchAllByStatusWithAuthorData('rejected') + return newEntries + } + + static async fetchAllInProgress() { + const newEntries = await this.fetchAllByStatusWithAuthorData('in progress') + return newEntries + } + + static async fetchAllPrepared() { + const newEntries = await this.fetchAllByStatusWithAuthorData('review') + return newEntries + } + + static async fetchAllPublished() { + const newEntries = await this.fetchAllByStatusWithAuthorData('published') + return newEntries + } + + static async fetch5MostRecentPublished() { + const sqlQuery = ` + SELECT ce.id, + to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created, + author_id, + institution, + description, + domain_primary_id_initial, + to_char(time_published, 'FMDD. FMMM. YYYY') time_published, + title, + question, + answer, + path, + answer_authors, + domain_primary_id, + first_name, + last_name, + cec.is_moderator + + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1 + ORDER BY time_published DESC + LIMIT 5` + + /* filter them in pug by displaying moderator, and showing authors + of non moderator */ + /* AND cec.is_moderator='true';` */ + + const values = ['published'] + const { rows: fetchedConsEntries } = await db.query(sqlQuery, values) + + const deserializedConsEntries = fetchedConsEntries.map( + consEntry => new this(consEntry) + ) + return deserializedConsEntries + } + + static async fetchPublishedCount() { + const sqlQuery = ` + SELECT COUNT(DISTINCT(ce.id)) + + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.status=$1` + + /* filter them in pug by displaying moderator, and showing authors + of non moderator */ + /* AND cec.is_moderator='true';` */ + + const values = ['published'] + const { rows } = await db.query(sqlQuery, values) + + return rows[0].count + } + + /* + static async fetchAuthorsFirstAndLastName(entryId, userId) { + const sqlQuery = ` + SELECT u.first_name u.last_name + FROM "user" u INNER JOIN "consultancy_entry_consultant" cec ON u.id = cec.user_id + WHERE cec.entry_id=$1 and cec.user_id=$2` + + const values = [entryId, userId] + const { rows: fetchedConsEntries } = await db.query(sqlQuery, values) + + return fetchedConsEntries + } + */ + + /* Get shared authors in progress, + answer_authors only get published when the question is published */ + static async getSharedAuthorsArrayBeforePublish(entryId) { + const sqlQuery = `SELECT cec.entry_id, cec.user_id, + u.first_name, u.last_name, u.username + FROM "consultancy_entry_consultant" cec INNER JOIN + "user" u ON u.id = cec.user_id + WHERE cec.entry_id=$1 AND cec.is_moderator='false';` + + const values = [entryId] + + const { rows } = await db.query(sqlQuery, values) + return rows + } + + static async getModerator(entryId) { + const sqlQuery = ` + SELECT u.id, u.first_name, u.last_name + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.id=$1 AND cec.is_moderator=true;` + + const values = [entryId] + + const { rows } = await db.query(sqlQuery, values) + return rows[0] + } + + static async getEditors(entryId) { + const sqlQuery = ` + SELECT u.id, u.first_name, u.last_name + FROM "consultancy_entry" ce + INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id + INNER JOIN "user" u ON u.id = cec.user_id + WHERE ce.id=$1` + + const values = [entryId] + + const { rows } = await db.query(sqlQuery, values) + return rows + } + + static async getSharedAuthorsArray(entryId) { + const sqlQuery = `SELECT answer_authors FROM "consultancy_entry" + WHERE id=$1;` + + const values = [entryId] + + const { rows } = await db.query(sqlQuery, values) + return rows[0] + } + + static async updateSharedAuthorsArray(entryId, authors) { + const sqlQuery = `UPDATE "consultancy_entry" SET answer_authors=$2 + WHERE id=$1;` + + const values = [entryId, authors] + + await db.query(sqlQuery, values) + } + + static async createQuestion(consultancyEntry) { + const sqlQuery = `INSERT INTO consultancy_entry ( + status, + author_id, + institution, + description, + domain_primary_id_initial, + existing_solutions, + examples_of_use + ) + VALUES ( + $1, + $2, + $3, + $4, + $5, + $6, + $7 + ) + RETURNING id;` + + const values = [ + consultancyEntry.status, + consultancyEntry.authorId, + consultancyEntry.institution, + consultancyEntry.description, + consultancyEntry.domainPrimaryIdInitial || null, + consultancyEntry.existingSolutions, + consultancyEntry.examplesOfUse + ] + + const { + rows: [{ id }] + } = await db.query(sqlQuery, values) + return id + } + + static async updateQuestion(consultancyEntry) { + await db.transaction(async dbClient => { + const sqlQuery = `UPDATE consultancy_entry SET + id_external=$2, + status=$3, + author_id=$4, + institution=$5, + description=$6, + domain_primary_id_initial=$7, + existing_solutions=$8, + examples_of_use=$9, + title=$10, + question=$11, + answer=$12, + path=$13, + answer_authors=$14, + domain_primary_id=$15 + WHERE id=$1;` + + const values = [ + consultancyEntry.id, + consultancyEntry.idExternal, + consultancyEntry.status, + consultancyEntry.authorId, + consultancyEntry.institution, + consultancyEntry.description, + consultancyEntry.domainPrimaryIdInitial, + consultancyEntry.existingSolutions, + consultancyEntry.examplesOfUse, + consultancyEntry.title, + consultancyEntry.question, + consultancyEntry.answer, + consultancyEntry.path, + consultancyEntry.answerAuthors, + consultancyEntry.domainPrimaryId + ] + + await dbClient.query(sqlQuery, values) + + await dbClient.query( + `UPDATE "consultancy_entry" SET status=$2 + WHERE id=$1;`, + [consultancyEntry.id, 'in progress'] + ) + }) + } + + static async deleteQuestion(id) { + const sqlQuery = `DELETE FROM consultancy_entry + WHERE id=$1;` + + const values = [id] + + await db.query(sqlQuery, values) + } + + /** refactor in case you need both moderator and non moderator + * insertions as a common function + */ + static async insertNonModerator(entryId, userId) { + const sqlQuery = `INSERT INTO "consultancy_entry_consultant" (entry_id, user_id, is_moderator) VALUES + ($1, $2, 'false'); + ` + + const values = [entryId, userId] + + const { rows } = await db.query(sqlQuery, values) + return rows + } + + static async assignWorkInProgress(entryId, userId) { + await db.transaction(async dbClient => { + let sqlQuery = `SELECT entry_id FROM consultancy_entry_consultant + WHERE entry_id=$1 AND is_moderator='true'` + + let values = [entryId] + + const { rows } = await dbClient.query(sqlQuery, values) + if (rows.length) { + await dbClient.query( + `DELETE FROM consultancy_entry_consultant + WHERE entry_id=$1 AND is_moderator='true'`, + values + ) + } + sqlQuery = [ + `UPDATE "consultancy_entry" SET status='in progress' + WHERE id=$1;`, + `INSERT INTO "consultancy_entry_consultant" (entry_id, user_id, is_moderator) VALUES + ($1, $2, 'true'); + ` + ] + + values = [[entryId], [entryId, userId]] + + for (let i = 0; i < sqlQuery.length; i++) { + await dbClient.query(sqlQuery[i], values[i]) + } + }) + } + + static async updateConsultancyEntryStatus(entryId, status) { + const sqlQuery = `UPDATE "consultancy_entry" SET status=$2 + WHERE id=$1;` + + const values = [entryId, status] + + await db.query(sqlQuery, values) + } + + static async rejectEntry(entryId) { + await this.updateConsultancyEntryStatus(entryId, 'rejected') + } + + static async sendToReview(entryId) { + await this.updateConsultancyEntryStatus(entryId, 'review') + } + + static async publish(entryId, answerAuthors) { + await db.transaction(async dbClient => { + await dbClient.query( + `UPDATE "consultancy_entry" SET status=$2 + WHERE id=$1;`, + [entryId, 'published'] + ) + + if (answerAuthors) { + answerAuthors = answerAuthors.split(',').filter(author => author !== '') + await dbClient.query( + `UPDATE "consultancy_entry" + SET answer_authors=$2 + WHERE id=$1;`, + [entryId, answerAuthors] + ) + } + + await dbClient.query( + `UPDATE "consultancy_entry" + SET time_published=CURRENT_TIMESTAMP + WHERE id=$1;`, + [entryId] + ) + }) + } + + static async removeConsultantForEntry(entryId, userId) { + // TODO check for any other tables where entry id is foreign key + await db.query( + `DELETE FROM consultancy_entry_consultant + WHERE entry_id=$1 AND user_id=$2`, + [entryId, userId] + ) + } + + static async removeEntry(id) { + // TODO check for any other tables where entry id is foreign key + await db.transaction(async dbClient => { + await dbClient.query( + `DELETE FROM consultancy_entry_consultant + WHERE entry_id=$1`, + [id] + ) + + await dbClient.query( + `DELETE FROM consultancy_entry + WHERE id=$1`, + [id] + ) + }) + } + + // (Re)index specific consultancy entry into consultancy search index. + static async indexIntoSearchEngine(entryId, shouldWait) { + const values = [entryId] + const text = ` + SELECT + jsonb_strip_nulls( + jsonb_build_object( + 'id', ce.id, + 'timeCreated', ce.time_created, + 'status', ce.status, + 'description', ce.description, + 'title', ce.title, + 'question', ce.question, + 'answer', ce.answer, + 'answerAuthors', ce.answer_authors, + 'primaryDomain', jsonb_strip_nulls( + jsonb_build_object( + 'id', dp.id, + 'nameSl', dp.name_sl, + 'nameEn', dp.name_en + ) + ), + 'assignedConsultants', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'id', u.id, + 'firstName', u.first_name, + 'lastName', u.last_name, + 'isModerator', cec.is_moderator + ) + ) + FROM consultancy_entry_consultant cec + LEFT JOIN "user" u on u.id = cec.user_id + WHERE cec.entry_id = ce.id + ORDER BY is_moderator DESC + ) + ) + ) entry + FROM consultancy_entry ce + LEFT JOIN domain_primary dp on dp.id = ce.domain_primary_id + WHERE ce.id = $1` + + let { + rows: [{ entry }] + } = await db.query(text, values) + + if (!entry.answerAuthors?.length) delete entry.answerAuthors + if (!Object.keys(entry.primaryDomain).length) delete entry.primaryDomain + if (!entry.assignedConsultants.length) delete entry.assignedConsultants + + entry = removeHtmlTags(JSON.stringify(entry)) + + await searchEngineClient.index({ + id: entryId, + index: CONSULTANCY_ENTRY_INDEX, + body: entry, + refresh: shouldWait ? 'wait_for' : false + }) + } + + // Remove all consultancy entries from index and index them all again. + static async reindexAll() { + await deleteConsultancyEntriesFromIndex() + + const { rows } = await db.query('SELECT id FROM consultancy_entry') + + for (const row of rows) { + const { id: entryId } = row + await this.indexIntoSearchEngine(entryId) + } + } +} + +module.exports = ConsultancyEntry diff --git a/express/models/db.js b/express/models/db.js new file mode 100644 index 0000000..3a77740 --- /dev/null +++ b/express/models/db.js @@ -0,0 +1,65 @@ +const { Pool, Client } = require('pg') +const debug = require('debug')('termPortal:models/db') + +const pool = new Pool() + +pool.on('error', (err, client) => { + debug('Error on DB pool idle client:') + debug({ err, client }) +}) + +exports.query = (text, params) => pool.query(text, params) + +exports.getClient = () => pool.connect() + +// Returns a new client from outside the pool. +exports.getExtraClient = () => { + const client = new Client() + client.connect() + return client +} + +exports.transaction = async queriesFn => { + const client = await pool.connect() + try { + await client.query('BEGIN') + await queriesFn(client) + await client.query('COMMIT') + } catch (error) { + await client.query('ROLLBACK') + throw error + } finally { + client.release() + } +} + +exports.genParamStr = paramArr => { + const paramPlaceholderString = paramArr.reduce((str, param, index) => { + if (index) str += ', ' + str += `$${index + 1}` + + return str + }, '') + + return paramPlaceholderString +} + +exports.waitForConnection = () => { + return new Promise(resolve => { + async function testConnection() { + try { + // eslint-disable-next-line no-console + console.log('Verifying connection to DB server') + await pool.query('SELECT 1') + // eslint-disable-next-line no-console + console.log('Connection to DB server verified') + resolve() + } catch { + // eslint-disable-next-line no-console + console.error('Could not connect to DB server') + setTimeout(testConnection, 1000) + } + } + testConnection() + }) +} diff --git a/express/models/demo-paginacija.js b/express/models/demo-paginacija.js new file mode 100644 index 0000000..3db8a72 --- /dev/null +++ b/express/models/demo-paginacija.js @@ -0,0 +1,49 @@ +const db = require('./db') + +const DemoPaginacija = {} + +// Metoda za generacijo demo podatkov. +DemoPaginacija.initDemoData = async () => { + await db.query(` + CREATE TABLE IF NOT EXISTS demo_paginacija (zanimivo TEXT, nezanimivo1 TEXT, nezanimivo2 TEXT); + + DO $$ + BEGIN + IF (SELECT COUNT(*) FROM demo_paginacija) = 0 THEN + FOR stevec IN 1..9993 LOOP + INSERT INTO demo_paginacija VALUES ('vrednost' || stevec, 'brezveze', 'tega res ne rabimo'); + END LOOP; + END IF; + END $$`) +} + +// Metoda za poizvedbo demo podatkov za določeno stran. +DemoPaginacija.fetch = async (resultsPerPage, page) => { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM demo_paginacija + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'zanimivo', zanimivo, + 'nezanimivo1', nezanimivo1, + 'nezanimivo2', nezanimivo2 + ) + FROM demo_paginacija + LIMIT $1 + OFFSET $2 + ) + ) result + `, + [resultsPerPage, resultsPerPage * (page - 1)] + ) + + return result +} + +module.exports = DemoPaginacija diff --git a/express/models/dictionary.js b/express/models/dictionary.js new file mode 100644 index 0000000..df38606 --- /dev/null +++ b/express/models/dictionary.js @@ -0,0 +1,1373 @@ +const Cursor = require('pg-cursor') +const db = require('./db') +const { intoDbArray, getInstanceSetting } = require('./helpers') +const { deserialize, bulkIndex } = require('./helpers/dictionary') +const { readFileIntoDb } = require('./helpers/dictionary/import-file') +// const debug = require('debug')('termPortal:models/dictionary') + +class Dictionary { + // Convert DB names into JS names. + // TODO Add (language sensitive) dictionary status text conversion. + constructor({ + id, + name_sl: nameSl, + time_modified: timeModified, + status, + count_entries: countEntries, + count_comments: countComments + }) { + this.id = id + this.nameSl = nameSl + this.timeModified = timeModified + this.status = status + this.countEntries = countEntries + this.countComments = countComments + } + + // Fetch all dictionaries from DB. + static async fetchAll() { + // TODO Implement SQL stored procedures or functions. + const { rows: fetchedDictionaries } = await db.query(` + SELECT + id, + name_sl, + time_modified, + status, + count_entries, + count_comments + FROM dictionary + ORDER BY time_modified DESC`) + const deserializedDictionaries = fetchedDictionaries.map( + dictionary => new this(dictionary) + ) + return deserializedDictionaries + } + + /* + // Fetch all dictionaries from DB by it's ID. + static async fetchAllByUser(id) { + // TODO Implement SQL stored procedures or functions. + const text = ` + SELECT + id, + name_sl, + time_modified, + status, + count_entries, + count_comments + FROM dictionary + WHERE id=$1 + ` + const values = [id] + const { rows: fetchedDictionaries } = await db.query(text, values) + const deserializedDictionary = new this(fetchedDictionaries[0]) + return deserializedDictionary + } + */ + + // Fetch all dictionaries from DB for which the user has at least one dictionary role. + static async fetchAllByUser(userId) { + // TODO Implement SQL stored procedures or functions. + const text = ` + SELECT + id, + name_sl, + time_modified, + status, + count_entries, + count_comments + FROM dictionary + WHERE id IN ( + SELECT dictionary_id + FROM user_role + WHERE user_id = $1 AND role_name = 'editor' + ) + ORDER BY time_modified DESC + ` + const values = [userId] + const { rows: fetchedDictionaries } = await db.query(text, values) + const deserializedDictionaries = fetchedDictionaries.map( + dictionary => new this(dictionary) + ) + return deserializedDictionaries + } + + // Fetch all primary domains from DB. + static async fetchAllPrimaryDomains() { + // TODO Implement SQL stored procedures or functions. + const { rows: fetchedDomains } = await db.query(` + SELECT id, name_sl, name_en + FROM domain_primary + ORDER BY id`) + const deserializedDomains = fetchedDomains.map(domain => + deserialize.primaryDomain(domain) + ) + return deserializedDomains + } + + // Fetch primary domain for a specific dictionary from DB. + static async fetchPrimaryDomain(dictionaryId) { + // TODO Implement SQL stored procedures or functions. + const { rows: fetchedDomains } = await db.query( + ` + SELECT dp.id, dp.name_sl, dp.name_en + FROM domain_primary dp + INNER JOIN dictionary dict ON dict.domain_primary_id = dp.id + WHERE dict.id = $1`, + [dictionaryId] + ) + const deserializedDomain = deserialize.primaryDomain(fetchedDomains[0]) + + return deserializedDomain + } + + // Fetch all approved secondary domains from DB. + static async fetchAllApprovedSecondaryDomains() { + // TODO Implement SQL stored procedures or functions. + const { rows: fetchedDomains } = await db.query(` + SELECT + id, + name_sl, + name_en + FROM domain_secondary + WHERE approved`) + const deserializedDomains = fetchedDomains.map(domain => + deserialize.approvedSecondaryDomain(domain) + ) + return deserializedDomains + } + + // Fetch all languages from DB. + static async fetchAllLanguages(lang) { + // TODO Implement SQL stored procedures or functions. + const { rows: fetchedLanguages } = await db.query(` + SELECT + id, + ${lang} + FROM language + ORDER BY ${lang}`) + const deserializedLanguages = fetchedLanguages.map(language => + deserialize.language(language) + ) + return deserializedLanguages + } + + // Create new dictionary in DB and assign the creator as its admin. + static async create(dictionary, userId) { + const values = [ + dictionary.nameSl || null, + dictionary.nameSlShort || null, + dictionary.nameEn || null, + intoDbArray(dictionary.author), + dictionary.issn || null, + dictionary.domainPrimary || null, + !!dictionary.hasDomainLabels, + !!dictionary.hasLabel, + !!dictionary.hasDefinition, + !!dictionary.hasSynonyms, + !!dictionary.hasLinks, + !!dictionary.hasOther, + !!dictionary.hasForeignLanguages, + !!dictionary.hasForeignDefinitions, + !!dictionary.hasForeignSynonyms, + !!dictionary.hasImages, + !!dictionary.hasAudio, + !!dictionary.hasVideos, + intoDbArray(dictionary.domainSecondary, 'always'), + intoDbArray(dictionary.domainSecondaryNewNameSl, 'always'), + intoDbArray(dictionary.domainSecondaryNewNameEn, 'always'), + intoDbArray(dictionary.language, 'always'), + userId + ] + const text = `SELECT dictionary_new (${db.genParamStr(values)})` + + await db.query(text, values) + } + + // Fetch single dictionary data for editing description from DB. + static async fetchEditDescription(dictionaryId) { + const text = ` + SELECT + id, + name_sl, + name_en, + name_sl_short, + author, + domain_primary_id, + description, + issn + FROM + dictionary + WHERE + id = $1` + const values = [dictionaryId] + + const { rows } = await db.query(text, values) + const fetchedDictionary = rows[0] + + const deserializedDictionary = + deserialize.editDescription(fetchedDictionary) + + return deserializedDictionary + } + + // Fetch secondary domains associated with a single dictionary from DB. + static async fetchSecondaryDomains(dictionaryId) { + const text = ` + SELECT + ds.id, + ds.name_sl, + ds.name_en + FROM dictionary d + INNER JOIN dictionary_domain_secondary dd ON d.id = dd.dictionary_id + INNER JOIN domain_secondary ds ON dd.domain_secondary_id = ds.id + WHERE d.id = $1` + const values = [dictionaryId] + + const { rows: fetchedSecondaryDomains } = await db.query(text, values) + + const deserializedSecondaryDomains = fetchedSecondaryDomains.map(domain => + deserialize.secondaryDomain(domain) + ) + + return deserializedSecondaryDomains + } + + // Update single dictionary description in DB. + static async updateDescription(dictionaryId, dictionary) { + const values = [ + dictionaryId, + dictionary.nameSl || null, + dictionary.nameSlShort || null, + dictionary.nameEn || null, + dictionary.issn || null, + dictionary.domainPrimary || null, + intoDbArray(dictionary.author), + dictionary.description || null + ] + + const text = ` + UPDATE + dictionary + SET + name_sl = $2, + name_sl_short = $3, + name_en = $4, + issn = $5, + domain_primary_id = $6, + author = $7, + description = $8 + WHERE + id = $1` + + await db.query(text, values) + } + + // Delete secondary domain associations with a single dictionary from DB. + static async deleteSecondaryDomains(dictionaryId, dictionary) { + const value = [dictionaryId] + + const text = ` + DELETE FROM + dictionary_domain_secondary + WHERE + dictionary_id = $1` + await db.query(text, value) + } + + // Insert new secondary domain associations with a single dictionary into DB. + static async updateSecondaryDomains(dictionaryId, dictionary) { + const updatedSecondaryDomains = intoDbArray( + dictionary.domainSecondary, + 'always' + ) + const values = [dictionaryId, updatedSecondaryDomains] + + const text = ` + INSERT INTO dictionary_domain_secondary (dictionary_id, domain_secondary_id) + VALUES ($1, UNNEST($2::smallint[]))` + await db.query(text, values) + } + + // Fetch single dictionary data for editing users from DB. + static async fetchEditUsers(dictionaryId) { + const text = ` + SELECT + id, + name_sl, + entries_have_terminology_review_flag, + entries_have_language_review_flag, + status + FROM + dictionary + WHERE + id = $1` + const value = [dictionaryId] + + const { rows } = await db.query(text, value) + const fetchedDictionary = rows[0] + + const deserializedDictionary = deserialize.editUsers(fetchedDictionary) + + return deserializedDictionary + } + + // Update single dictionary users and their roles in DB. + static async updateUsers(dictionaryId, dictionary, newDictStatus) { + const values = [ + dictionaryId, + !!dictionary.hasTerminologyReview, + !!dictionary.hasLanguageReview, + newDictStatus + ] + + const text = ` + UPDATE + dictionary + SET + entries_have_terminology_review_flag = $2, + entries_have_language_review_flag = $3, + status = $4 + WHERE + id = $1` + + await db.query(text, values) + } + + // Fetch single dictionary's admin emails. + static async fetchAdminEmails(dictionaryId) { + const query = { + text: ` + SELECT email FROM "user" WHERE id + IN(SELECT user_id FROM user_role WHERE dictionary_id = $1 + AND administration = true)`, + values: [dictionaryId], + rowMode: 'array' + } + + const { rows: users } = await db.query(query) + const emails = users.flat() + return emails + } + + // Fetch dictionaries admin emails. + static async fetchDictionariesAdminEmails() { + const query = { + text: ` + SELECT email FROM "user" WHERE id + IN(SELECT user_id FROM user_role + WHERE role_name = 'dictionaries admin')`, + rowMode: 'array' + } + + const { rows: users } = await db.query(query) + const emails = users.flat() + return emails + } + + // Fetch single dictionary data for editing structure from DB. + static async fetchEditStructure(dictionaryId) { + const text = ` + SELECT + id, + name_sl, + entries_have_domain_labels, + entries_have_label, + entries_have_definition, + entries_have_synonyms, + entries_have_links, + entries_have_other, + entries_have_foreign_languages, + entries_have_foreign_definitions, + entries_have_foreign_synonyms, + entries_have_images, + entries_have_audio, + entries_have_videos + FROM + dictionary + WHERE id = $1` + + const value = [dictionaryId] + + const { rows } = await db.query(text, value) + const fetchedDictionary = rows[0] + + const deserializedDictionary = deserialize.editStructure(fetchedDictionary) + + return deserializedDictionary + } + + // Fetch single dictionary data for viewing details about it + static async fetchDictionaryBasicInfo(dictionaryId) { + const isInEnglish = false + const lang = isInEnglish ? 'd.name_en' : 'd.name_sl' + const text = ` + SELECT + d.id, + ${lang} dictionarysl, + d.count_entries, + to_char(d.time_modified,'YYYY-MM-DD') time_modified, + d.issn, + d.author, + dp.name_sl domain_primary, + description, + l.name_sl languageSl, + ds.name_sl domainSecondarySl, + lp.name portalname, + lp.code portalcode + FROM + dictionary d + INNER JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN language l ON dl.language_id = l.id + LEFT JOIN dictionary_domain_secondary dds on dds.dictionary_id = d.id + LEFT JOIN domain_secondary ds ON dds.domain_secondary_id = ds.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id + WHERE d.id = $1` + // AND ds.approved + + const value = [dictionaryId] + + const { rows } = await db.query(text, value) + + return rows + } + + // Fetch dictionaries data for viewing details about it + static async fetchBasicInfoForAllDictionaries(isInEnglish) { + const lang = isInEnglish ? 'd.name_en' : 'd.name_sl' + const text = ` + SELECT + distinct(d.id), + ${lang} dictionarysl, + d.count_entries, + to_char(d.time_modified,'YYYY-MM-DD') time_modified, + d.issn, + d.author, + dp.name_sl domain_primary, + description, + lp.name portalname, + lp.code portalcode + FROM + dictionary d + FULL JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id + ORDER BY ${lang} ASC + ` + + const { rows } = await db.query(text) + + return rows + } + + // Fetch dictionary data for viewing details about it + static async fetchBasicInfoPerPageFiltered( + searchQuery, + domainQuery, + resultsPerPage, + page + ) { + let queryAppend = '' + if (domainQuery.length > 0) { + try { + queryAppend = domainQuery.reduce((acc, e, i) => { + if (i === 0) { + let retstring = `( dp.id=${parseInt(e)}` + + if (domainQuery.length - 1 === 0) { + // if contains only one item -> "AND (dp.id=XXX)" + retstring = `${retstring} )` + } + + // "AND [[( dp.id=XXX]]" + return acc + retstring + } + if (i === domainQuery.length - 1) { + return acc + ` OR dp.id=${parseInt(e)})` + } + + // "AND ( dp.id=XXX [[OR dp.id=YYY]]" + return acc + ` OR dp.id=${parseInt(e)}` + }, 'AND ') + } catch (e) { + queryAppend = '' + } + } + + const isInEnglish = false + const lang = isInEnglish ? 'name_en' : 'name_sl' + const text = ` + SELECT + distinct (d.id), + d.${lang} dictionarysl, + d.count_entries, + to_char(d.time_modified,'YYYY-MM-DD') time_modified, + d.issn, + d.author, + dp.name_sl domain_primary, + description, + lp.name portalname, + lp.code portalcode + FROM + dictionary d + FULL JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id + WHERE d.name_sl LIKE '%' || $1 || '%' ${queryAppend} + LIMIT $2 + OFFSET $3` + + const { rows } = await db.query(text, [ + searchQuery, + resultsPerPage, + resultsPerPage * (page - 1) + ]) + + return rows + } + + // Fetch dictionary data for viewing details about it + static async fetchBasicInfoPerPageFilteredWithOrdering( + searchQuery, + domainQuery, + resultsPerPage, + page, + orderType, + orderIndex + ) { + let queryAppend = '' + if (domainQuery.length > 0) { + try { + queryAppend = domainQuery.reduce((acc, e, i) => { + if (i === 0) { + let retstring = `( dp.id=${parseInt(e)}` + + if (domainQuery.length - 1 === 0) { + // if contains only one item -> "AND (dp.id=XXX)" + retstring = `${retstring} )` + } + + // "AND [[( dp.id=XXX]]" + return acc + retstring + } + if (i === domainQuery.length - 1) { + return acc + ` OR dp.id=${parseInt(e)})` + } + + // "AND ( dp.id=XXX [[OR dp.id=YYY]]" + return acc + ` OR dp.id=${parseInt(e)}` + }, 'AND ') + } catch (e) { + queryAppend = '' + } + } + + const isInEnglish = false + const lang = isInEnglish ? 'name_en' : 'name_sl' + + const orderBy = `${orderType}.${lang} ${orderIndex ? 'DESC' : 'ASC'}` + + // TODO domain primary language toggle! + const text = ` + SELECT + distinct (d.id), + d.${lang} dictionarysl, + d.count_entries, + to_char(d.time_modified,'YYYY-MM-DD') time_modified, + d.issn, + d.author, + dp.name_sl domain_primary, + description, + lp.name portalname, + lp.code portalcode + FROM + dictionary d + FULL JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id + WHERE d.name_sl LIKE '%' || $1 || '%' ${queryAppend} + ORDER BY ${orderBy} + LIMIT $2 + OFFSET $3` + + const { rows } = await db.query(text, [ + searchQuery, + resultsPerPage, + resultsPerPage * (page - 1) + ]) + + return rows + } + + // Fetch dictionary data for viewing details about it + static async fetchFilteredCount(searchQuery, domainQuery) { + let queryAppend = '' + if (domainQuery.length > 0) { + try { + queryAppend = domainQuery.reduce((acc, e, i) => { + if (i === 0) { + let retstring = `( dp.id=${parseInt(e)}` + + if (domainQuery.length - 1 === 0) { + // if contains only one item -> "AND (dp.id=XXX)" + retstring = `${retstring} )` + } + + // "AND [[( dp.id=XXX]]" + return acc + retstring + } + if (i === domainQuery.length - 1) { + return acc + ` OR dp.id=${parseInt(e)})` + } + + // "AND ( dp.id=XXX [[OR dp.id=YYY]]" + return acc + ` OR dp.id=${parseInt(e)}` + }, 'AND ') + } catch (e) { + queryAppend = '' + } + } + + // TODO domain primary language toggle! + const text = ` + SELECT + COUNT (distinct (d.id)) AS count + FROM + dictionary d + FULL JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id + WHERE d.name_sl LIKE '%' || $1 || '%' ${queryAppend}` + + const { rows } = await db.query(text, [searchQuery]) + + return rows[0] + } + + static async fetchAllDictionariesCount() { + const text = ` + SELECT + count(d.id) + FROM + dictionary d + INNER JOIN dictionary_language dl ON dl.dictionary_id = d.id + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + LEFT JOIN linked_dictionary ld ON ld.target_dictionary_id = d.id + LEFT JOIN linked_portal lp ON ld.linked_portal_id = lp.id` + + const { rows } = await db.query(text) + + return rows[0] + } + + // Fetch single dictionary data for editing structure from DB. + static async fetchDictionaryWithEditStructure(dictionaryId) { + const text = ` + SELECT + id, + name_sl, + name_sl_short, + name_en, + author, + issn, + entries_have_domain_labels, + entries_have_label, + entries_have_definition, + entries_have_synonyms, + entries_have_links, + entries_have_other, + entries_have_foreign_languages, + entries_have_foreign_definitions, + entries_have_foreign_synonyms, + entries_have_images, + entries_have_audio, + entries_have_videos + FROM + dictionary + WHERE id = $1` + + const value = [dictionaryId] + + const { rows } = await db.query(text, value) + const fetchedDictionary = rows[0] + + const dictionary = new this(fetchedDictionary) + const deserializedEditstructure = + deserialize.editStructure(fetchedDictionary) + + return { dictionary, structure: deserializedEditstructure } + } + + // Fetch languages associated with a single dictionary from DB. + static async fetchLanguages(dictionaryId) { + const text = ` + SELECT + l.id, + l.code, + l.name_sl, + l.name_en + FROM dictionary d + INNER JOIN dictionary_language dl ON d.id = dl.dictionary_id + INNER JOIN language l ON dl.language_id = l.id + WHERE d.id = $1 + ORDER BY dl.selection_order` + const value = [dictionaryId] + + const { rows: fetchedLanguages } = await db.query(text, value) + + const deserializedLanguages = fetchedLanguages.map(language => + deserialize.language(language) + ) + return deserializedLanguages + } + + // Fetch latest 3 dictionaries by publish date + static async fetchLatest3DictsByPublishDate(isInEnglish) { + const lang = isInEnglish ? 'd.name_en' : 'd.name_sl' + const text = ` + SELECT + d.id, + ${lang} dictionarysl, + dp.name_sl domain_primary + FROM dictionary d + INNER JOIN domain_primary dp ON d.domain_primary_id = dp.id + where d.time_published is not NULL + ORDER BY d.time_published desc + limit 3` + + const { rows } = await db.query(text) + return rows + } + + // Update single dictionary structure in DB. + static async updateStructure(dictionaryId, dictionary) { + const values = [ + dictionaryId, + !!dictionary.hasDomainLabels, + !!dictionary.hasLabel, + !!dictionary.hasDefinition, + !!dictionary.hasSynonyms, + !!dictionary.hasLinks, + !!dictionary.hasOther, + !!dictionary.hasForeignLanguages, + !!dictionary.hasForeignDefinitions, + !!dictionary.hasForeignSynonyms, + !!dictionary.hasImages, + !!dictionary.hasAudio, + !!dictionary.hasVideos + ] + + const text = ` + UPDATE + dictionary + SET + entries_have_domain_labels = $2, + entries_have_label = $3, + entries_have_definition = $4, + entries_have_synonyms = $5, + entries_have_links = $6, + entries_have_other = $7, + entries_have_foreign_languages = $8, + entries_have_foreign_definitions = $9, + entries_have_foreign_synonyms = $10, + entries_have_images = $11, + entries_have_audio = $12, + entries_have_videos = $13 + WHERE + id = $1` + + await db.query(text, values) + } + + // Delete language associations with a single dictionary from DB. + static async deleteLanguages(dictionaryId) { + const value = [dictionaryId] + + const text = ` + DELETE FROM + dictionary_language + WHERE + dictionary_id = $1` + await db.query(text, value) + } + + // Insert new language associations with a single dictionary into DB. + static async updateLanguages(dictionaryId, dictionary) { + const updatedLanguages = intoDbArray(dictionary.language, 'always') + const selectionOrder = updatedLanguages.map((language, index) => index + 1) + const values = [dictionaryId, updatedLanguages, selectionOrder] + + const text = ` + INSERT INTO dictionary_language (dictionary_id, language_id, selection_order) + VALUES ($1, UNNEST($2::smallint[]), UNNEST($3::smallint[]))` + await db.query(text, values) + } + + static async fetchAllAdminDictionaries(resultsPerPage, page) { + // TODO Implement SQL stored procedures or functions. + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM dictionary + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', id, + 'name', name_sl, + 'timeCreated', time_created, + 'timeModified', time_modified, + 'status', status + ) + FROM dictionary + WHERE count_comments IS NOT NULL + LIMIT $1 + OFFSET $2 + ) + ) result`, + [resultsPerPage, resultsPerPage * (page - 1)] + ) + + return result + } + + static async countPublishedEntries(dictionaryId) { + const text = ` + SELECT COUNT(*) + FROM entry + WHERE is_published = true + AND dictionary_id = $1` + const value = [dictionaryId] + + const { + rows: [{ count }] + } = await db.query(text, value) + + return count + } + + static async fetchStatus(dictionaryId) { + const text = ` + SELECT status + FROM dictionary + WHERE id = $1` + const value = [dictionaryId] + + const { + rows: [{ status }] + } = await db.query(text, value) + + return status + } + + static async updateStatus(dictionaryId, dictionary) { + const text = ` + UPDATE dictionary + SET status = $2 + WHERE id = $1` + const value = [dictionaryId, dictionary.status] + + await db.query(text, value) + } + + static async updateTimePublished(dictionaryId) { + const text = ` + UPDATE dictionary + SET time_published = NOW() + WHERE id = $1` + const value = [dictionaryId] + + await db.query(text, value) + } + + // Update single dictionary metadata in DB after modifying entires. + static async updateMetadataAfterModifyingEntries( + dictionaryId, + dbClient = db // Use the provided client else grab one from the pool. + ) { + const values = [dictionaryId] + + const text = ` + UPDATE + dictionary + SET + time_content_modified = NOW(), + count_entries = ( + SELECT COUNT(*) + FROM entry + WHERE dictionary_id = $1 + ) + WHERE id = $1` + + await dbClient.query(text, values) + } + + // Update single dictionary metadata in DB after modifying its entry. + static async updateMetadataAfterModifyingEntry( + entryId, + dbClient = db // Use the provided client else grab one from the pool. + ) { + const values = [entryId] + + const text = ` + UPDATE + dictionary + SET + time_content_modified = NOW(), + count_entries = ( + SELECT COUNT(*) + FROM entry + WHERE dictionary_id = ( + SELECT dictionary_id FROM entry + WHERE id = $1 + ) + ) + WHERE id = ( + SELECT dictionary_id FROM entry + WHERE id = $1 + )` + + await dbClient.query(text, values) + } + + // Create new import file job in DB. + static async openImportFileJob( + dictionaryId, + deleteExistingEntries, + importFileFormat + ) { + const values = [dictionaryId, !!deleteExistingEntries, importFileFormat] + const text = ` + INSERT INTO import_file_job ( + dictionary_id, + delete_existing_entries, + file_format + ) + VALUES ($1, $2, $3)` + + await db.query(text, values) + } + + // Import entries from file into DB. + static async importFromFile( + userId, + dictionaryId, + importFilePath, + entryStatus + ) { + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + await readFileIntoDb( + userId, + dictionaryId, + importFilePath, + entryStatus, + dbClient + ) + await this.updateMetadataAfterModifyingEntries(dictionaryId, dbClient) + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } + } + + // Index entries of specific dictionary from DB into search engine. + static async indexIntoSearchEngine(dictionaryId) { + // TODO Luka: I expect "source" needing a rework once linked portals and dictionaries start working. + const source = { + code: await getInstanceSetting('portal_code'), + name: await getInstanceSetting('portal_name') + } + const dbClient = await db.getClient() + try { + const queryValues = [dictionaryId] + + const dictionaryQueryText = ` + SELECT + jsonb_strip_nulls( + jsonb_build_object( + 'id', d.id, + 'nameSl', d.name_sl, + 'nameSlShort', d.name_sl_short, + 'nameEn', d.name_en, + 'status', d.status + ) + ) "dictionary", + jsonb_build_object( + 'id', dp.id, + 'nameSl', dp.name_sl, + 'nameEn', dp.name_en + ) primary_domain + FROM dictionary d + LEFT JOIN domain_primary dp ON dp.id = d.domain_primary_id + WHERE d.id = $1` + + const { + rows: [{ dictionary, primary_domain: primaryDomain }] + } = await dbClient.query(dictionaryQueryText, queryValues) + + const entryQueryText = ` + SELECT + id, + is_valid, + is_published, + is_terminology_reviewed, + is_language_reviewed, + status, + term, + homonym_sort, + label, + definition, + synonym synonyms, + other, + time_most_recent_comment, + ARRAY( + SELECT name + FROM entry_domain_label edl + LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id + WHERE entry_id = e.id + ) domain_labels, + ARRAY( + SELECT link + FROM entry_link + WHERE entry_id = e.id + ) links, + ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'lang', jsonb_build_object( + 'id', l.id, + 'code', l.code, + 'nameSl', l.name_sl, + 'nameEn', l.name_en + ), + 'terms', ef.term, + 'definition', ef.definition, + 'synonyms', ef.synonym + ) + ) + FROM entry_foreign ef + LEFT JOIN LANGUAGE l ON l.id = ef.language_id + WHERE entry_id = e.id + ) foreign_entries + FROM entry e + WHERE + e.dictionary_id = $1` + + const cursor = dbClient.query(new Cursor(entryQueryText, queryValues)) + + let entries = [] + do { + // Keep getting and indexing entries in batches of 100. + entries = await cursor.read(100) + + await bulkIndex(entries, primaryDomain, dictionary, source) + } while (entries.length === 100) + } finally { + dbClient.release() + } + } + + // Fetch single dictionary's name from DB. + static async fetchName(dictionaryId) { + const { rows } = await db.query( + 'SELECT name_sl FROM dictionary WHERE id = $1', + [dictionaryId] + ) + const dictionaryName = rows[0].name_sl + return dictionaryName + } + + // Fetch all domain labels for single dictionary from DB. + static async fetchDomainLabels(dictionaryId) { + const { rows: fetchedDomainLabels } = await db.query( + 'SELECT id, name, is_visible FROM domain_label WHERE dictionary_id = $1', + [dictionaryId] + ) + + const deserializedDomainLabels = fetchedDomainLabels.map(domainLabel => + deserialize.editDomainLabels(domainLabel) + ) + + return deserializedDomainLabels + } + + // Fetch all domain labels for selected entry from DB. + static async fetchDomainLabelsFromEntryId(entryId) { + const { rows: fetchedDomainLabels } = await db.query( + ` + SELECT id, name, is_visible + FROM domain_label + WHERE dictionary_id = + (SELECT dictionary_id FROM entry WHERE id = $1)`, + [entryId] + ) + + const deserializedDomainLabels = fetchedDomainLabels.map(domainLabel => + deserialize.editDomainLabels(domainLabel) + ) + + return deserializedDomainLabels + } + + // Fetch all domain labels for pagination for single dictionary from DB. + static async fetchPaginationDomainLabels(dictionaryId, resultsPerPage, page) { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $2::float) + FROM domain_label + WHERE dictionary_id = $1 + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', id, + 'name', name, + 'isVisible', is_visible + ) + FROM domain_label + WHERE dictionary_id = $1 + ORDER BY name + LIMIT $2 + OFFSET $3 + ) + ) result`, + [dictionaryId, resultsPerPage, resultsPerPage * (page - 1)] + ) + + return result + } + + // Fetch all secondary domains from DB. + static async fetchAllSecondaryDomains(resultsPerPage, page) { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM domain_secondary + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', id, + 'isApproved', approved, + 'nameSl', name_sl, + 'nameEn', name_en + ) + FROM domain_secondary + ORDER BY name_sl + LIMIT $1 + OFFSET $2 + ) + ) result`, + [resultsPerPage, resultsPerPage * (page - 1)] + ) + + return result + } + + static async updateDomainLabel(dictionaryId, data) { + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const deletableDomainLabels = data.filter( + domainLabel => domainLabel.type === 'removeArea' + ) + + const deleteEntryDomainLabel = deletableDomainLabels.map( + async element => { + const values = [element.id] + const text = ` + DELETE FROM entry_domain_label + WHERE domain_label_id = $1` + + await dbClient.query(text, values) + } + ) + + await Promise.all(deleteEntryDomainLabel) + + const deleteDomainLabel = deletableDomainLabels.map(async element => { + const values = [element.id] + const text = ` + DELETE FROM domain_label + WHERE id = $1` + + await dbClient.query(text, values) + }) + + await Promise.all(deleteDomainLabel) + + const addableDomainLabels = data.filter( + domainLabel => domainLabel.type === 'addArea' + ) + const addDomainLabels = addableDomainLabels.map(async element => { + const values = [element.name, dictionaryId] + const text = ` + INSERT INTO domain_label (name, dictionary_id) + VALUES ($1, $2)` + + await dbClient.query(text, values) + }) + + const addJobs = Promise.all(addDomainLabels) + + const updatableDomainLabels = data.filter( + domainLabel => domainLabel.type === 'changeArea' + ) + const updateDomainLabels = updatableDomainLabels.map(async element => { + const values = [ + element.name, + element.isVisible, + element.id, + dictionaryId + ] + const text = ` + UPDATE domain_label + SET name = $1, is_visible = $2 + WHERE id = $3 AND dictionary_id = $4` + + await dbClient.query(text, values) + }) + + const updateJobs = Promise.all(updateDomainLabels) + + await Promise.all([addJobs, updateJobs]) + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } + } + + static async renovateSecondaryDomains(data) { + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const deletableSecondaryDomains = data.filter( + domainSecondary => domainSecondary.type === 'removeArea' + ) + const deleteDictionarySecondaryDomains = deletableSecondaryDomains.map( + async element => { + const values = [element.id] + const text = ` + DELETE FROM dictionary_domain_secondary + WHERE domain_secondary_id = $1` + + await dbClient.query(text, values) + } + ) + + await Promise.all(deleteDictionarySecondaryDomains) + + const deleteSecondaryDomain = deletableSecondaryDomains.map( + async element => { + const values = [element.id] + const text = ` + DELETE FROM domain_secondary + WHERE id = $1` + + await dbClient.query(text, values) + } + ) + + await Promise.all(deleteSecondaryDomain) + + const addableSecondaryDomains = data.filter( + domainSecondary => domainSecondary.type === 'addArea' + ) + const addSeconaryDomains = addableSecondaryDomains.map(async element => { + const values = [element.nameSl, element.nameEn] + const text = ` + INSERT INTO domain_secondary (name_sl, name_en) + VALUES ($1, $2)` + + await dbClient.query(text, values) + }) + + const addJobs = Promise.all(addSeconaryDomains) + + const updatableSecondaryDomains = data.filter( + domainSecondary => domainSecondary.type === 'changeArea' + ) + const updateSecondaryDomain = updatableSecondaryDomains.map( + async element => { + const values = [ + element.nameSl, + element.nameEn, + element.isApproved, + element.id + ] + const text = ` + UPDATE domain_secondary + SET name_sl = $1, name_en = $2, approved = $3 + WHERE id = $4` + + await dbClient.query(text, values) + } + ) + + const updateJobs = Promise.all(updateSecondaryDomain) + + await Promise.all([addJobs, updateJobs]) + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } + } + + static async fetchAllImports(dictionaryId) { + const text = ` + SELECT + time_started, + status, + delete_existing_entries, + file_format, + count_valid_entries + FROM import_file_job + WHERE dictionary_id = $1` + + const value = [dictionaryId] + const { rows: fetchedImports } = await db.query(text, value) + + const deserializedImports = fetchedImports.map(oneImport => + deserialize.imports(oneImport) + ) + return deserializedImports + } + + static async delete(dictionaryId) { + const text = 'DELETE FROM dictionary WHERE id = $1' + const value = [dictionaryId] + await db.query(text, value) + } +} + +module.exports = Dictionary diff --git a/express/models/domain.js b/express/models/domain.js new file mode 100644 index 0000000..a7e49f9 --- /dev/null +++ b/express/models/domain.js @@ -0,0 +1,79 @@ +// TODO Possible duplicate methods in Dictionary model. +// TODO Ambiguous model name. There are also secondary domains, domain labels, ... + +const db = require('./db') + +class Domain { + constructor({ + id, + name_sl: nameSl, + name_en: nameEn, + udk_code: udkCode, + cerif_name: cerifName, + cerif_code: cerifCode, + eurovoc_name: eurovocName, + eurovoc_code: eurovocNode + }) { + this.id = id + this.nameSl = nameSl + this.nameEn = nameEn + this.udkCode = udkCode + this.cerifName = cerifName + this.cerifCode = cerifCode + this.eurovocName = eurovocName + this.eurovocNode = eurovocNode + } + + // Fetch all consultancy entries from DB. + static async fetchAll() { + // TODO Luka: Miha, define specific fields instead of using *. + const { rows: fetchedConsEntries } = await db.query(` + SELECT * + FROM domain_primary`) + const domains = fetchedConsEntries.map(domain => new this(domain)) + return domains + } + + // Fetch domain by ID. + static async fetchById(id) { + // TODO Luka: Miha, define specific fields instead of using *. + const { rows: domainEntity } = await db.query( + ` + SELECT * + FROM domain_primary + WHERE id=$1`, + [id] + ) + + const domain = new this(domainEntity[0]) + return domain + } + + // Fetch domain by name. + static async fetchByName(name) { + // TODO Luka: Miha, define specific fields instead of using *. + const { rows: domainEntity } = await db.query( + ` + SELECT * + FROM domain_primary + WHERE name_sl=$1`, + [name] + ) + + const domain = new this(domainEntity[0]) + return domain + } + + // Fetch primary domain id by udk code. + static async fetchIdByUdkCode(udkCode) { + const { + rows: [{ id }] + } = await db.query('SELECT id FROM domain_primary WHERE udk_code = $1', [ + udkCode + ]) + + return id + } +} + +module.exports = Domain diff --git a/express/models/email.js b/express/models/email.js new file mode 100644 index 0000000..3a70baa --- /dev/null +++ b/express/models/email.js @@ -0,0 +1,40 @@ +const nodemailer = require('nodemailer') +const htmlToText = require('nodemailer-html-to-text').htmlToText() +const { + smtpHost, + smtpPort, + smtpTlsRejectUnauthorized, + smtpFrom +} = require('../config/keys') + +const options = { + host: smtpHost, + port: smtpPort, + tls: { rejectUnauthorized: smtpTlsRejectUnauthorized } +} +const defaults = { from: smtpFrom } + +const transporter = nodemailer.createTransport(options, defaults) +transporter.use('compile', htmlToText) + +exports.send = data => transporter.sendMail(data) + +exports.waitForConnection = () => { + return new Promise(resolve => { + async function testConnection() { + try { + // eslint-disable-next-line no-console + console.log('Verifying connection to SMTP server') + await transporter.verify() + // eslint-disable-next-line no-console + console.log('Connection to SMTP server verified') + resolve() + } catch { + // eslint-disable-next-line no-console + console.error('Could not connect to SMTP server') + setTimeout(testConnection, 1000) + } + } + testConnection() + }) +} diff --git a/express/models/entry.js b/express/models/entry.js new file mode 100644 index 0000000..45d977d --- /dev/null +++ b/express/models/entry.js @@ -0,0 +1,650 @@ +const db = require('./db') +const { searchEngineClient, ENTRY_INDEX } = require('./search-engine') +const { intoDbArray, getInstanceSetting, removeHtmlTags } = require('./helpers') +const { prepareEntryForIndexing } = require('./helpers/dictionary') + +const Entry = {} + +// Create a new dictionary entry in DB. +Entry.create = async (userId, dictionaryId, entry) => { + const pickedLinks = intoDbArray(entry.links, 'always') + const pickedType = intoDbArray(entry.type, 'always') + const links = pickedLinks.map((link, index) => ({ + link, + type: pickedType[index] + })) + const foreign = intoDbArray(entry.foreign, 'always') + const foreignLanguageContent = foreign.reduce((agg, row) => { + if (row.term || row.definition || row.synonym) { + agg.push({ + language: row.code, + terms: intoDbArray(row.term, 'undefined'), + definition: row.definition || null, + synonyms: intoDbArray(row.synonym, 'undefined') + }) + } + return agg + }, []) + + const isValid = + !!entry.term && + (!!entry.definition || foreignLanguageContent.some(el => el.terms)) + + const values = [ + dictionaryId, + isValid, + entry.status, + entry.term || null, + userId, + entry.homonymSort || null, + entry.wordforms || null, + entry.accent || null, + entry.pronunciation, + intoDbArray(entry.domainLabels, 'always'), + entry.label || null, + entry.definition || null, + intoDbArray(entry.synonyms), + links, + entry.other || null, + foreignLanguageContent, + intoDbArray(entry.image), + intoDbArray(entry.audio), + intoDbArray(entry.video) + ] + const text = `SELECT entry_new (${db.genParamStr(values)})` + + const { + rows: [{ entry_new: entryId }] + } = await db.query(text, values) + + return entryId +} + +// // Fetch all entry terms of a single dictionary from DB. +// Entry.fetchAll = async dictionaryId => { +// const text = ` +// SELECT +// e.id, +// e.is_valid as valid, +// e.is_published as published, +// e.term as term, +// MAX(ef.term) as fterm, +// CASE +// WHEN NOW() - e.time_most_recent_comment < INTERVAL '1 week' THEN 'T' +// WHEN NOW() - e.time_most_recent_comment < INTERVAL '1 month' THEN 'M' +// WHEN NOW() - e.time_most_recent_comment < INTERVAL '1 year' THEN 'L' +// ELSE '' +// END comment_age +// FROM entry e +// LEFT JOIN entry_foreign ef ON e.id = ef.entry_id +// WHERE dictionary_id = $1 +// GROUP BY id, is_valid, is_published, e.term, comment_age +// ORDER BY e.term` +// const value = [dictionaryId] + +// const { rows: fetchedTerms } = await db.query(text, value) +// return fetchedTerms +// } + +// Metoda za poizvedbo demo podatkov za določeno stran. +// Entry.fetchPaginated = async (resultsPerPage, page) => { +// const { +// rows: [{ result }] +// } = await db.query( +// ` +// SELECT jsonb_build_object( +// 'pages_total', ( +// SELECT CEIL(COUNT(*) / $1::float) +// FROM demo_paginacija +// ), +// 'results', ARRAY( +// SELECT jsonb_build_object( +// dictionary_id, +// term, +// is_published, +// is_terminology_reviewed, +// is_language_reviewed, +// status, +// label, +// definition, +// synonym, +// other, +// image, +// audio, +// video +// ) +// FROM entry +// LIMIT $1 +// OFFSET $2 +// ) +// ) result +// `, +// [resultsPerPage, resultsPerPage * (page - 1)] +// ) + +// return result +// } + +// Fetch all data, related to single entry from DB. +Entry.fetchFull = async entryId => { + const text = ` + SELECT + jsonb_strip_nulls( + jsonb_build_object( + 'dictionary_id', e.dictionary_id, + 'is_valid', e.is_valid, + 'is_published', e.is_published, + 'is_terminology_reviewed', e.is_terminology_reviewed, + 'is_language_reviewed', e.is_language_reviewed, + 'status', e.status, + 'term', e.term, + 'version', e.version, + 'version_author', ( + SELECT username + FROM "user" u + LEFT JOIN entry e ON e.version_author = u.id + WHERE e.id = $1 + ), + 'homonym_sort', e.homonym_sort, + 'label', e.label, + 'definition', e.definition, + 'synonyms', e.synonym, + 'other', e.other, + 'image', e.image, + 'audio', e.audio, + 'video', e.video, + 'time_modified', e.time_modified, + 'domain_labels', ARRAY( + SELECT name + FROM entry_domain_label edl + LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id + WHERE entry_id = e.id + ), + 'links', ARRAY( + SELECT jsonb_build_object( + 'type', type, + 'link', link + ) + FROM entry_link + WHERE entry_id = e.id + ), + 'foreign_entries', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'language_id', language_id, + 'term', term, + 'definition', definition, + 'synonym', synonym + ) + ) + FROM entry_foreign + WHERE entry_id = e.id + ), + 'versions', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'version', version, + 'version_time', version_time + ) + ) + FROM entry_version_history + WHERE entry_id = e.id + ) + ) + ) entry + FROM entry e + WHERE e.id = $1` + const value = [entryId] + const { + rows: [{ entry }] + } = await db.query(text, value) + + return entry +} + +// Fetch all data, related to single entry from DB with ordered foreign languages. +Entry.fetchFullWithOrderedForeignLanguages = async entryId => { + const text = ` + SELECT + jsonb_strip_nulls( + jsonb_build_object( + 'dictionary_id', e.dictionary_id, + 'is_valid', e.is_valid, + 'is_published', e.is_published, + 'is_terminology_reviewed', e.is_terminology_reviewed, + 'is_language_reviewed', e.is_language_reviewed, + 'status', e.status, + 'term', e.term, + 'synonym', e.synonym, + 'version', e.version, + 'version_author', ( + SELECT username + FROM "user" u + LEFT JOIN entry e ON e.version_author = u.id + WHERE e.id = $1 + ), + 'homonym_sort', e.homonym_sort, + 'label', e.label, + 'definition', e.definition, + 'synonyms', e.synonym, + 'other', e.other, + 'image', e.image, + 'audio', e.audio, + 'video', e.video, + 'time_modified', e.time_modified, + 'domain_labels', ARRAY( + SELECT name + FROM entry_domain_label edl + LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id + WHERE entry_id = e.id + ), + 'links', ARRAY( + SELECT jsonb_build_object( + 'type', type, + 'link', link + ) + FROM entry_link + WHERE entry_id = e.id + ), + 'foreign_entries', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'language_id', ef.language_id, + 'term', ef.term, + 'definition', ef.definition, + 'synonym', ef.synonym + ) + ) + FROM entry e + LEFT JOIN entry_foreign ef on ef.entry_id = e.id + LEFT JOIN dictionary_language dl on dl.dictionary_id = e.dictionary_id AND ef.language_id = dl.language_id + LEFT JOIN language l on l.id = ef.language_id + WHERE entry_id = $1 + ORDER BY dl.selection_order + ), + 'versions', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'version', version, + 'version_time', version_time + ) + ) + FROM entry_version_history + WHERE entry_id = e.id + ) + ) + ) entry + FROM entry e + WHERE e.id = $1` + const value = [entryId] + const { + rows: [{ entry }] + } = await db.query(text, value) + + return entry +} + +// Fetch single entry data from DB. +Entry.fetch = async entryId => { + const text = ` + SELECT + dictionary_id, + term, + is_published, + is_terminology_reviewed, + is_language_reviewed, + homonym_sort, + status, + label, + definition, + synonym, + other, + image, + audio, + video + FROM entry + WHERE id = $1` + const value = [entryId] + const { rows: fetchedEntryData } = await db.query(text, value) + return fetchedEntryData[0] +} + +// Fetch domain labels associated with a single entry from DB. +Entry.fetchDomainLabels = async entryId => { + const text = ` + SELECT + dl.id, + dl.dictionary_id, + dl.name + FROM entry e + INNER JOIN entry_domain_label edl ON e.id = edl.entry_id + INNER JOIN domain_label dl ON edl.domain_label_id = dl.id + WHERE e.id = $1` + const value = [entryId] + const { rows: fetchedDomainLabels } = await db.query(text, value) + return fetchedDomainLabels +} + +// Fetch foreign content associated with a single entry from DB. +Entry.fetchForeign = async entryId => { + const text = ` + SELECT term, language_id, definition, synonym + FROM entry_foreign + WHERE entry_id=$1` + const value = [entryId] + const { rows: fetchedEntries } = await db.query(text, value) + return fetchedEntries +} + +// Redundant. Use getInstanceSetting function instead. +// Entry.fetchEditingPhase = async () => { +// const text = ` +// SELECT +// name, value +// FROM +// instance_settings +// WHERE +// name = 'can_publish_entries_in_edit' +// ` +// const { rows: fetchedPhase } = await db.query(text) +// const aggregatedSettings = aggregateSettings(fetchedPhase) +// const deserializedSettings = deserialize.dictSettings(aggregatedSettings) +// return deserializedSettings +// } + +// Delete foreign content of a single entry from DB. +Entry.deleteForeign = async entryId => { + const text = 'DELETE FROM entry_foreign WHERE entry_id = $1' + const value = [entryId] + await db.query(text, value) +} + +// Delete domain label associations with a single entry from DB. +Entry.deleteDomainLabels = async entryId => { + const text = 'DELETE FROM entry_domain_label WHERE entry_id = $1' + const value = [entryId] + await db.query(text, value) +} + +// Delete links of a single entry from DB. +Entry.deleteLinks = async entryId => { + const text = 'DELETE FROM entry_link WHERE entry_id = $1' + const value = [entryId] + await db.query(text, value) +} + +// Delete single entry from DB. +Entry.delete = async entryId => { + const text = 'DELETE FROM entry WHERE id = $1 RETURNING dictionary_id' + const value = [entryId] + const { + rows: [{ dictionary_id: dictionaryId }] + } = await db.query(text, value) + return dictionaryId +} + +// Delete foreign content for selected dictionary from DB. +Entry.deleteAllForeign = async dictionaryId => { + const text = ` + DELETE FROM entry_foreign + WHERE entry_id + IN (SELECT id + FROM entry + WHERE dictionary_id = $1)` + const value = [dictionaryId] + await db.query(text, value) +} + +// Delete all domain label associations for selected dictionary from DB. +Entry.deleteAllDomainLabels = async dictionaryId => { + const text = ` + DELETE FROM entry_domain_label + WHERE entry_id + IN (SELECT id + FROM entry + WHERE dictionary_id = $1)` + const value = [dictionaryId] + await db.query(text, value) +} + +// Delete all links for selected dictionary. +Entry.deleteAllLinks = async dictionaryId => { + const text = ` + DELETE FROM entry_link + WHERE entry_id + IN (SELECT id + FROM entry + WHERE dictionary_id = $1)` + const value = [dictionaryId] + await db.query(text, value) +} + +// (Re)index specific entry into entry search index. +Entry.indexIntoSearchEngine = async (entryId, shouldWait) => { + const values = [entryId] + const text = ` + SELECT + jsonb_strip_nulls( + jsonb_build_object( + 'id', e.id, + 'is_valid', e.is_valid, + 'is_published', e.is_published, + 'is_terminology_reviewed', e.is_terminology_reviewed, + 'is_language_reviewed', e.is_language_reviewed, + 'status', e.status, + 'term', e.term, + 'homonym_sort', e.homonym_sort, + 'label', e.label, + 'definition', e.definition, + 'synonyms', e.synonym, + 'other', e.other, + 'time_most_recent_comment', e.time_most_recent_comment, + 'domain_labels', ARRAY( + SELECT name + FROM entry_domain_label edl + LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id + WHERE entry_id = e.id + ), + 'links', ARRAY( + SELECT link + FROM entry_link + WHERE entry_id = e.id + ), + 'foreign_entries', ARRAY( + SELECT jsonb_strip_nulls( + jsonb_build_object( + 'lang', jsonb_build_object( + 'id', l.id, + 'code', l.code, + 'nameSl', l.name_sl, + 'nameEn', l.name_en + ), + 'terms', ef.term, + 'definition', ef.definition, + 'synonyms', ef.synonym + ) + ) + FROM entry_foreign ef + LEFT JOIN LANGUAGE l ON l.id = ef.language_id + WHERE entry_id = e.id + ) + ) + ) entry, + jsonb_strip_nulls( + jsonb_build_object( + 'id', d.id, + 'nameSl', d.name_sl, + 'nameSlShort', d.name_sl_short, + 'nameEn', d.name_en, + 'status', d.status + ) + ) "dictionary", + jsonb_build_object( + 'id', dp.id, + 'nameSl', dp.name_sl, + 'nameEn', dp.name_en + ) primary_domain + FROM entry e + JOIN dictionary d ON d.id = e.dictionary_id + JOIN domain_primary dp ON dp.id = d.domain_primary_id + WHERE e.id = $1` + + const { + rows: [dataToIndex] + } = await db.query(text, values) + + const { dictionary, primary_domain: primaryDomain } = dataToIndex + let { entry } = dataToIndex + // TODO Luka: I expect "source" needing a rework once linked portals and dictionaries start working. + const source = { + code: await getInstanceSetting('portal_code'), + name: await getInstanceSetting('portal_name') + } + + entry = prepareEntryForIndexing(entry) + entry.primaryDomain = primaryDomain + entry.dictionary = dictionary + entry.source = source + entry = removeHtmlTags(JSON.stringify(entry)) + + await searchEngineClient.index({ + id: entryId, + index: ENTRY_INDEX, + body: entry, + refresh: shouldWait ? 'wait_for' : false + }) +} + +// Delete all entries for selected dictionary from search index. +Entry.deleteAllFromIndex = async dictionaryId => { + await searchEngineClient.deleteByQuery({ + index: ENTRY_INDEX, + body: { query: { match: { 'dictionary.id': dictionaryId } } } + }) +} + +// Delete all entries for selected dictionary from DB. +Entry.deleteAll = async dictionaryId => { + const text = 'DELETE FROM entry WHERE dictionary_id = $1' + const value = [dictionaryId] + await db.query(text, value) +} + +// Publish all entries for selected dictionary from DB that match the criteria. +Entry.publishAllQualified = async dictionaryId => { + const text = ` + UPDATE entry + SET is_published = TRUE + WHERE + dictionary_id = $1 + AND is_valid = TRUE + AND status = ANY( + CASE (SELECT value FROM instance_settings WHERE name = 'can_publish_entries_in_edit') + WHEN 'T' THEN ARRAY ['complete', 'in_edit']::entry_status[] + ELSE ARRAY ['complete']::entry_status[] + END + ) + ` + const value = [dictionaryId] + + await db.query(text, value) +} + +// Update single entry in DB. +Entry.update = async (userId, entry) => { + // Copied from Entry.create and modified. + const pickedLinks = intoDbArray(entry.links, 'always') + const pickedType = intoDbArray(entry.type, 'always') + const links = pickedLinks.map((link, index) => ({ + link, + type: pickedType[index] + })) + const foreign = intoDbArray(entry.foreign, 'always') + const foreignLanguageContent = foreign.reduce((agg, row) => { + if (row.term || row.definition || row.synonym) { + agg.push({ + language: row.code, + terms: intoDbArray(row.term, 'undefined'), + definition: row.definition || null, + synonyms: intoDbArray(row.synonym, 'undefined') + }) + } + return agg + }, []) + const isValid = + !!entry.term && + (!!entry.definition || foreignLanguageContent.some(el => el.terms)) + + const values = [ + entry.entryId, + isValid, + !!entry.isPublished, + !!entry.isTerminologyReviewed, + !!entry.isLanguageReviewed, + entry.status, + entry.term || null, + userId, + entry.homonymSort || null, + intoDbArray(entry.domainLabels, 'always'), + entry.label || null, + entry.definition || null, + intoDbArray(entry.synonyms), + links, + entry.other || null, + foreignLanguageContent, + intoDbArray(entry.image), + intoDbArray(entry.audio), + intoDbArray(entry.video) + ] + const text = `SELECT entry_update (${db.genParamStr(values)})` + + const { + rows: [{ entry_update: dictionaryId }] + } = await db.query(text, values) + + return dictionaryId +} + +// // Fetch all versions (with timestamps) of a single entry from DB. +// Entry.fetchVersions = async entryId => { +// const { rows: historyVersions } = await db.query( +// 'SELECT version, version_time FROM entry_version_history WHERE entry_id = $1', +// [entryId] +// ) + +// return historyVersions +// } + +// Fetch a single version snapshot of a single entry from DB. +Entry.fetchVersionSnapshot = async (entryId, version) => { + const { + rows: [{ version_snapshot: historySnapshot }] + } = await db.query( + 'SELECT version_snapshot FROM entry_version_history WHERE entry_id = $1 and version = $2', + [entryId, version] + ) + + return historySnapshot +} + +/* Fetch by language and entry Id. Note that this version includes the language name */ +Entry.fetchForeignEntryById = async entryId => { + const text = ` + SELECT + entry_id, + language_id, + code, + name_sl, + name_en, + term, + definition, + synonym + FROM entry_foreign ef + INNER JOIN language lang ON ef.language_id = lang.id + WHERE ef.entry_id = $1` + const value = [entryId] + const { rows: fetchedDomainLabels } = await db.query(text, value) + return fetchedDomainLabels +} + +module.exports = Entry diff --git a/express/models/extraction.js b/express/models/extraction.js new file mode 100644 index 0000000..98258da --- /dev/null +++ b/express/models/extraction.js @@ -0,0 +1,501 @@ +const FormData = require('form-data') +const { createReadStream } = require('fs') +const { writeFile, readFile } = require('fs/promises') +const axios = require('axios') +const db = require('./db') +const { + deserialize, + getDocumentsPath, + getStopTermsPath, + getConllusPath, + getTermCandidatesPath, + getFileNamesInFolder, + getFileStatsInFolder +} = require('./helpers/extraction') + +const Extraction = {} + +// Fetch all extractions for a specific user. +Extraction.fetchAllForUser = async userId => { + const { rows: fetchedExtractions } = await db.query( + 'SELECT id, name, status, corpus_id, oss_params, time_started, time_finished FROM extraction WHERE user_id = $1 ORDER BY id', + [userId] + ) + + return fetchedExtractions.map(fetchedExtraction => + deserialize.extraction(fetchedExtraction) + ) +} + +// Count all extractions for a specific user. +Extraction.countAllForUser = async userId => { + const { + rows: [{ count: extractionCount }] + } = await db.query('SELECT COUNT(*) FROM extraction WHERE user_id = $1', [ + userId + ]) + + return +extractionCount +} + +// Create a new (own) extraction entry in DB. +Extraction.createOwn = async (userId, extractionName) => { + const { + rows: [{ id }] + } = await db.query( + 'INSERT INTO extraction (user_id, name) VALUES ($1, $2) RETURNING id', + [userId, extractionName] + ) + + return id +} + +// Create a new (oss) extraction entry in DB. +Extraction.createOss = async (userId, extractionName) => { + const { + rows: [{ id }] + } = await db.query( + 'INSERT INTO extraction (user_id, name, oss_params) VALUES ($1, $2, $3) RETURNING id', + [userId, extractionName, { params: {}, status: 'new' }] + ) + + return id +} + +// Fetch a specific extraction entry from DB. +Extraction.fetch = async id => { + const { + rows: [fetchedExtraction] + } = await db.query( + 'SELECT id, name, status, corpus_id, oss_params, time_started, time_finished FROM extraction WHERE id = $1', + [id] + ) + + return deserialize.extraction(fetchedExtraction) +} + +// Fetch author email of a specific extraction entry from DB. +Extraction.fetchAuthorEmail = async id => { + const { + rows: [{ email }] + } = await db.query( + `SELECT u.email + FROM extraction e + LEFT JOIN "user" u ON u.id = e.user_id + WHERE e.id = $1`, + [id] + ) + + return email +} + +// Update extraction entry in DB. +Extraction.update = async (id, name) => { + await db.query('UPDATE extraction SET name = $2 WHERE id = $1', [id, name]) +} + +// Delete a specific extraction entry from DB. +Extraction.delete = async id => { + const { + rows: [{ corpus_id: corpusId }] + } = await db.query( + 'DELETE FROM extraction WHERE id = $1 RETURNING corpus_id', + [id] + ) + + return corpusId +} + +// Fetch all documents' names for a specific extraction. +Extraction.fetchAllDocumentsNames = async extractionId => { + const documentsPath = getDocumentsPath(extractionId) + const documentsNames = await getFileNamesInFolder(documentsPath) + + return documentsNames +} + +// Fetch all documents' metadata for a specific extraction. +Extraction.fetchAllDocumentsStats = async extractionId => { + const documentsPath = getDocumentsPath(extractionId) + const documentsStats = await getFileStatsInFolder(documentsPath) + + return documentsStats +} + +// Fetch all stop terms files' names for a specific extraction. +Extraction.fetchAllStopTermsFilesNames = async extractionId => { + const stopTermsFilesPath = getStopTermsPath(extractionId) + const stopTermsFilesNames = await getFileNamesInFolder(stopTermsFilesPath) + + return stopTermsFilesNames +} + +// Fetch all stop terms files' metadata for a specific extraction. +Extraction.fetchAllStopTermsFilesStats = async extractionId => { + const stopTermsFilesPath = getStopTermsPath(extractionId) + const stopTermsFilesStats = await getFileStatsInFolder(stopTermsFilesPath) + + return stopTermsFilesStats +} + +// Update OSS parameters for a specific extraction in DB. +Extraction.updateOssParams = async (extractionId, newOssParams) => { + await db.query('UPDATE extraction SET oss_params = $1 WHERE id = $2', [ + newOssParams, + extractionId + ]) +} + +// Fetch term candidates JSON for a specific extraction. +Extraction.fetchTermCandidatesJson = async extractionId => { + const termCandidatesPath = getTermCandidatesPath(extractionId) + const fileContent = await readFile(termCandidatesPath, 'utf8') + return fileContent +} + +// Fetch the number of term candidates for a specific extraction. +Extraction.fetchTermCandidatesCount = async function (extractionId) { + const termCandidatesJson = await this.fetchTermCandidatesJson(extractionId) + const termCandidates = JSON.parse(termCandidatesJson).terminoloski_kandidati + return termCandidates.length +} + +// Mark extraction from own documents as began. +Extraction.beginOwn = async (extractionId, documentsNames) => { + let timeStarted + await db.transaction(async dbClient => { + ;[ + { + rows: [{ time_started: timeStarted }] + } + ] = await Promise.all([ + dbClient.query( + "UPDATE extraction SET status = 'in progress', time_started = NOW() WHERE id = $1 RETURNING time_started", + [extractionId] + ), + dbClient.query( + 'INSERT INTO extraction_job (extraction_id, job_type, filename) VALUES ($1, $2, UNNEST($3::VARCHAR[]))', + [extractionId, 'doc to conllu', documentsNames] + ), + dbClient.query( + 'INSERT INTO extraction_job (extraction_id, job_type, filename) VALUES ($1, $2, $3)', + [extractionId, 'conllus to term candidates', ''] + ), + dbClient.query( + 'INSERT INTO extraction_job (extraction_id, job_type, filename) VALUES ($1, $2, $3)', + [extractionId, 'concordancer', ''] + ) + ]) + }) + + return timeStarted +} + +// Mark extraction from OSS as began. +Extraction.beginOss = async extractionId => { + let timeStarted + await db.transaction(async dbClient => { + const insertExtractionJob = dbClient.query( + 'INSERT INTO extraction_job (extraction_id, job_type, filename) VALUES ($1, $2, $3)', + [extractionId, 'oss term candidates', ''] + ) + const updateExtraction = dbClient.query( + "UPDATE extraction SET status = 'in progress', time_started = NOW() WHERE id = $1 RETURNING time_started", + [extractionId] + ) + + ;[ + { + rows: [{ time_started: timeStarted }] + } + ] = await Promise.all([updateExtraction, insertExtractionJob]) + }) + + return timeStarted +} + +// Fetch all finished extractions for a specific user. +Extraction.fetchFinishedForUser = async userId => { + const { rows: fetchedExtractions } = await db.query( + 'SELECT id, name FROM extraction WHERE user_id = $1 AND status = $2 ORDER BY id', + [userId, 'finished'] + ) + + return fetchedExtractions.map(fetchedExtraction => + deserialize.extraction(fetchedExtraction) + ) +} + +// Supervise a specific extraction from own documents and bring it out of 'in progress' status. +// This is a temporary solution as explained in its execution context. +// It's also completely unmodular and a complete mess. Refactor at appropriate time. +Extraction.processOwn = async function (extractionId, extractionName) { + // Get documents folder path and all documets' names witin. + const documentsPath = getDocumentsPath(extractionId) + const documentNames = await this.fetchAllDocumentsNames(extractionId) + const conllusPath = getConllusPath(extractionId) + const conllusPaths = [] + // Using remote API, transform each document into conllu format. + for (const documentName of documentNames) { + const filePath = `${documentsPath}/${documentName}` + const form = new FormData() + form.append('file', createReadStream(filePath), documentName) + try { + const { data: data1 } = await axios.post( + 'http://rsdo.lhrs.feri.um.si:8080/datotekaVConlluAsync', + form, + { + headers: { + ...form.getHeaders() + } + } + ) + const remotejobId = +data1.check_job_url.split('/').at(-1) + await db.query( + "UPDATE extraction_job SET status = 'in progress', remote_job_id = $1 WHERE extraction_id = $2 AND job_type = $3 AND filename = $4", + [remotejobId, extractionId, 'doc to conllu', documentName] + ) + + // Kristjan said: I don't have to wait for one job to finish to begin the next. I could launch all at once, which is the whole purpose of async processing. + // Consider reworking it in such manner. + // Poll job until finished. + while (true) { + await sleep(5) + const { data: data2 } = await axios.get( + `http://rsdo.lhrs.feri.um.si:8080/job/${remotejobId}` + ) + if (data2.finished_on) { + if (data2.job_status !== 'finished processing (OK)') throw Error() + // TODO Read the response as a stream and try to parse it's contents into a file (write stream)('stream-json' package?). + const fileSavePath = `${conllusPath}/${documentName}.conllu` + await writeFile(fileSavePath, data2.job_result) + await db.query( + "UPDATE extraction_job SET status = 'finished', time_finished = NOW() WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, 'doc to conllu', documentName] + ) + conllusPaths.push(fileSavePath) + break + } + } + } catch { + await failTheJob(extractionId, 'doc to conllu', documentName) + } + } + + // Conllu transformation for all documents finished. Start extracting term candidates. + // TODO This is a naive implementation which builds the whole payload in memory. Make it streamy. + const conllusArr = [] + for (const conlluPath of conllusPaths) { + const fileContent = await readFile(conlluPath, 'utf8') + conllusArr.push(fileContent) + } + + const stopTermsPath = getStopTermsPath(extractionId) + const stopTermsFilesNames = await this.fetchAllStopTermsFilesNames( + extractionId + ) + const stopTermsSet = new Set() + const stopTermsSeperator = /\r?\n/ + for (const stopTermsFileName of stopTermsFilesNames) { + const fileContent = await readFile( + `${stopTermsPath}/${stopTermsFileName}`, + 'utf8' + ) + const stopTerms = fileContent.split(stopTermsSeperator) + stopTerms.forEach(stopTerm => stopTermsSet.add(stopTerm.trim())) + } + stopTermsSet.delete('') + const termCandidatesPath = getTermCandidatesPath(extractionId) + + try { + const { data: data3 } = await axios.post( + 'http://rsdo.lhrs.feri.um.si:8080/izlusciAsync', + { + conllus: conllusArr, + prepovedaneBesede: Array.from(stopTermsSet) + } + ) + const remotejobId = +data3.check_job_url.split('/').at(-1) + await db.query( + "UPDATE extraction_job SET status = 'in progress', remote_job_id = $1 WHERE extraction_id = $2 AND job_type = $3 AND filename = $4", + [remotejobId, extractionId, 'conllus to term candidates', ''] + ) + + // Poll job until finished. + while (true) { + await sleep(5) + const { data: data4 } = await axios.get( + `http://rsdo.lhrs.feri.um.si:8080/job/${remotejobId}` + ) + if (data4.finished_on) { + if (data4.job_status !== 'finished processing (OK)') throw Error() + // TODO Read the response as a stream and try to parse it's contents into a file (write stream)('stream-json' package?). + await writeFile(termCandidatesPath, JSON.stringify(data4.job_result)) + // TODO Once returned JSON is properly formed, use the bottom line instead. + // await writeFile(termCandidatesPath, data4.job_result.terminoloski_kandidati) + await db.query( + "UPDATE extraction_job SET status = 'finished', time_finished = NOW() WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, 'conllus to term candidates', ''] + ) + break + } + } + } catch { + await failTheJob(extractionId, 'conllus to term candidates', '') + await failExtraction(extractionId) + return + } + + // Now we have conllus and term_candidates.json. + // Start concondancer corpus processing. + try { + await db.query( + "UPDATE extraction_job SET status = 'in progress' WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, 'concordancer', ''] + ) + console.log('CREATING CORPUS') + const { + data: { + entityInfo: { id: corpusId } + } + } = await axios.post('http://concordancer:5000/dashboard/corpus', { + title: extractionName + }) + console.log('CORPUS CREATED') + console.log('SLEEP FOR 10 SECS') + await sleep(10) + for (const conlluPath of conllusPaths) { + const textPathParts = conlluPath.split('/') + textPathParts[0] = '/data' + const textPath = textPathParts.join('/') + console.log('ADDING TEXT') + await axios.post( + `http://concordancer:5000/dashboard/corpus/${corpusId}/text`, + { sourceFile: textPath } + ) + console.log('TEXT ADDED') + console.log('SLEEP FOR 10 SECS') + await sleep(10) + } + + const termListPathParts = termCandidatesPath.split('/') + termListPathParts[0] = '/data' + const termListPath = termListPathParts.join('/') + console.log('ADDING TERMS') + await axios.post( + `http://concordancer:5000/dashboard/corpus/${corpusId}/termList`, + { sourceFile: termListPath } + ) + console.log('TERMS ADDED') + await db.query( + "UPDATE extraction_job SET status = 'finished', time_finished = NOW() WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, 'concordancer', ''] + ) + + await db.query( + "UPDATE extraction SET status = 'finished', time_finished = NOW(), corpus_id = $1 WHERE id = $2", + [corpusId, extractionId] + ) + console.log('EXTRACTION SUCCESSFUL') + } catch (e) { + console.log('EXTRACTION ERROR') + console.log(e) + await failTheJob(extractionId, 'concordancer', '') + await failExtraction(extractionId) + } +} + +// Supervise a specific extraction from OSS and bring it out of 'in progress' status. +// This is a temporary solution as explained in its execution context. +// It's also completely unmodular and a complete mess. Refactor at appropriate time. +Extraction.processOss = async function (extractionId, ossParams) { + // TODO Consider if it would make sense to make stop term file reading streaming. + // TODO Probably not, at least not while the the OSS enpoint is GET, due to limited length of URLs. + // TODO Also consider refactoring certain parts, + // TODO as some are identical or similar to Own variants or used earlier in the same pipeline. + const stopTermsPath = getStopTermsPath(extractionId) + const stopTermsFilesNames = await this.fetchAllStopTermsFilesNames( + extractionId + ) + const stopTermsSet = new Set() + const stopTermsSeperator = /\r?\n/ + for (const stopTermsFileName of stopTermsFilesNames) { + const fileContent = await readFile( + `${stopTermsPath}/${stopTermsFileName}`, + 'utf8' + ) + const stopTerms = fileContent.split(stopTermsSeperator) + stopTerms.forEach(stopTerm => stopTermsSet.add(stopTerm.trim())) + } + stopTermsSet.delete('') + const stopTerms = Array.from(stopTermsSet) + + const searchParams = new URLSearchParams({ + ...(ossParams.year && { leta: ossParams.year }), + ...(ossParams.documentType && { vrste: ossParams.documentType }), + ...(ossParams.keywords && { kljucneBesede: ossParams.keywords }), + ...(ossParams.domainUdk && { udk: ossParams.domainUdk }), + ...(stopTerms.length && { prepovedaneBesede: stopTerms }) + }) + + const extractApiUrl = `http://rsdo.lhrs.feri.um.si:8080/oss/izlusciPoIskanjuAsync?${searchParams}` + try { + const { data: data1 } = await axios.get(extractApiUrl) + const remotejobId = +data1.check_job_url.split('/').at(-1) + await db.query( + "UPDATE extraction_job SET status = 'in progress', remote_job_id = $1 WHERE extraction_id = $2 AND job_type = $3 AND filename = $4", + [remotejobId, extractionId, 'oss term candidates', ''] + ) + + // Poll job until finished. + while (true) { + await sleep(5) + const { data: data2 } = await axios.get( + `http://rsdo.lhrs.feri.um.si:8080/job/${remotejobId}` + ) + if (data2.finished_on) { + if (data2.job_status !== 'finished processing (OK)') throw Error() + // TODO Read the response as a stream and try to parse it's contents into a file (write stream)('stream-json' package?). + const termCandidatesPath = getTermCandidatesPath(extractionId) + await writeFile(termCandidatesPath, JSON.stringify(data2.job_result)) + // TODO Once returned JSON is properly formed, use the bottom line instead. + // await writeFile(termCandidatesPath, data4.job_result.terminoloski_kandidati) + await db.query( + "UPDATE extraction_job SET status = 'finished', time_finished = NOW() WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, 'oss term candidates', ''] + ) + break + } + } + + // Now we have term_candidates.json. + // Mark extraction as finished. + await db.query( + "UPDATE extraction SET status = 'finished', time_finished = NOW() WHERE id = $1", + [extractionId] + ) + } catch { + await failTheJob(extractionId, 'oss term candidates', '') + await failExtraction(extractionId) + } +} + +async function failTheJob(extractionId, jobType, documentName) { + await db.query( + "UPDATE extraction_job SET status = 'failed', time_finished = NOW() WHERE extraction_id = $1 AND job_type = $2 AND filename = $3", + [extractionId, jobType, documentName] + ) +} + +async function failExtraction(extractionId) { + await db.query( + "UPDATE extraction SET status = 'failed', time_finished = NOW() WHERE id = $1", + [extractionId] + ) +} + +function sleep(seconds) { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)) +} + +module.exports = Extraction diff --git a/express/models/helpers/dictionary/import-file.js b/express/models/helpers/dictionary/import-file.js new file mode 100644 index 0000000..f9bf533 --- /dev/null +++ b/express/models/helpers/dictionary/import-file.js @@ -0,0 +1,282 @@ +const fs = require('fs') +const xmlFlow = require('xml-flow') +const xss = require('xss') +const debug = require('debug')('termPortal:models/helpers/dictionary') +const db = require('../../db') +const { intoDbArray } = require('..') + +const JOBS_MAX = 50 +const JOBS_MIN = 15 + +// Import given file into given dictionary. +exports.readFileIntoDb = ( + userId, + dictionaryId, + importFilePath, + entryStatus, + dbClient +) => { + return new Promise((resolve, reject) => { + const progress = { + jobCount: 0, + totalCount: 0, + validCount: 0, + isWholeFileRead: false, + importError: null + } + entryStatus = entryStatus === 'complete' ? 'complete' : 'in_edit' + const importFileReader = fs.createReadStream(importFilePath) + const xmlStream = xmlFlow(importFileReader, { + strict: true, + trim: false, + preserveMarkup: xmlFlow.ALWAYS, + simplifyNodes: false, + useArrays: xmlFlow.ALWAYS + }) + const handleError = handleImportError(xmlStream, progress, reject) + const handleEntry = handleEntryXml( + userId, + dictionaryId, + entryStatus, + progress, + dbClient, + resolve, + handleError + ) + + xmlStream + .on('error', () => {}) + .once('error', handleError) + .on('end', () => (progress.isWholeFileRead = true)) + .on('tag:entry', handleEntry) + }) +} + +function handleImportError(xmlStream, progress, reject) { + return function handleError(error) { + if (progress.importError) return + + progress.importError = error + xmlStream.removeAllListeners('tag:entry') + reject(error) + } +} + +function handleEntryXml( + userId, + dictionaryId, + entryStatus, + progress, + dbClient, + resolve, + handleError +) { + return async function handleEntry(entry) { + if (progress.importError) return + + try { + if (++progress.jobCount > JOBS_MAX) this.pause() + + const term = toMixedBasic( + entry.$markup.find(el => el.$name === 'term')?.$markup + ) + const hwGrp = entry.$markup.find(el => el.$name === 'hwGrp') + const wordforms = hwGrp?.$attrs.wfs + const accent = hwGrp?.$attrs.acc + const pronunciation = hwGrp?.$attrs.pron + const domainLabels = entry.$markup + .find(el => el.$name === 'domainLabels') + ?.$markup.filter(childEl => childEl.$name === 'domainLabel') + .map(domainLabel => toText(domainLabel.$markup)) + const label = toMixedExtended( + entry.$markup.find(el => el.$name === 'label')?.$markup + ) + const definition = toMixedExtended( + entry.$markup.find(el => el.$name === 'def')?.$markup + ) + const synonyms = entry.$markup + .find(el => el.$name === 'syns') + ?.$markup.filter(childEl => childEl.$name === 'syn') + .map(synonym => toMixedBasic(synonym.$markup)) + const links = entry.$markup + .find(el => el.$name === 'links') + ?.$markup.filter(childEl => childEl.$name === 'link') + .map(link => ({ + link: toMixedBasic(link.$markup), + type: link.$attrs.type + })) + const other = toMixedOther( + entry.$markup.find(el => el.$name === 'other')?.$markup + ) + let hasForeignTerms = false + const foreignLanguageContent = entry.$markup + .find(el => el.$name === 'fLangs') + ?.$markup.filter(childEl => childEl.$name === 'fLang') + .map(fLang => ({ + language: fLang.$attrs.lang, + terms: fLang.$markup + .find(el => el.$name === 'fTerms') + ?.$markup.filter(childEl => childEl.$name === 'fTerm') + .map(term => { + const content = toMixedBasic(term.$markup) + if (content.length) hasForeignTerms = true + return content + }), + definition: + toMixedExtended( + fLang.$markup.find(el => el.$name === 'fDef')?.$markup + ) || null, + synonyms: fLang.$markup + .find(el => el.$name === 'fSyns') + ?.$markup.filter(childEl => childEl.$name === 'fSyn') + .map(synonym => toMixedBasic(synonym.$markup)) + })) + const multimedia = entry.$markup.find(el => el.$name === 'mm')?.$markup + const images = [] + const audio = [] + const videos = [] + multimedia?.forEach(mm => { + switch (mm.$name) { + case 'image': + images.push(toText(mm.$markup)) + break + case 'audio': + audio.push(toText(mm.$markup)) + break + case 'video': + videos.push(toText(mm.$markup)) + } + }) + + const isValid = !!term && (!!definition || hasForeignTerms) + + if (!entry.$markup.length) return + + const values = [ + dictionaryId, + isValid, + entryStatus, + term || null, + userId, + null, + wordforms, + accent, + pronunciation, + intoDbArray(domainLabels, 'always'), + label || null, + definition || null, + intoDbArray(synonyms), + intoDbArray(links, 'always'), + other || null, + intoDbArray(foreignLanguageContent, 'always'), + images.length ? images : null, + audio.length ? audio : null, + videos.length ? videos : null + ] + const text = `SELECT entry_new (${db.genParamStr(values)})` + + await dbClient.query(text, values) + + progress.totalCount++ + if (isValid) progress.validCount++ + } catch (error) { + handleError(error) + } finally { + progress.jobCount-- + + if (progress.jobCount < JOBS_MIN) this.resume() + + if ( + !progress.jobCount && + progress.isWholeFileRead && + !progress.importError + ) { + debug(`TOTAL ENTRIES: ${progress.totalCount}`) + debug(`VALID ENTRIES: ${progress.validCount}`) + resolve() + } + } + } +} + +const markupFilter = { + noMixed: new xss.FilterXSS({ + whiteList: {}, + stripIgnoreTag: true, + stripIgnoreTagBody: ['script', 'style'] + }), + + mixedBasic: new xss.FilterXSS({ + whiteList: { + sup: [], + sub: [] + }, + stripIgnoreTag: true, + stripIgnoreTagBody: ['script', 'style'] + }), + + mixedExtended: new xss.FilterXSS({ + whiteList: { + sup: [], + sub: [], + b: [], + i: [], + a: ['href'] + }, + stripIgnoreTag: true, + stripIgnoreTagBody: ['script', 'style'], + onTag: customTagHandler + }), + + mixedOther: new xss.FilterXSS({ + whiteList: { + sup: [], + sub: [], + b: [], + i: [], + a: ['href'], + br: [] + }, + stripIgnoreTag: true, + stripIgnoreTagBody: ['script', 'style'], + onTag: customTagHandler + }) +} + +function customTagHandler(tag, html, { isWhite, isClosing }) { + // Special treatment only for whitelisted opening anchor tags. + if (tag !== 'a' || !isWhite || isClosing) return + + const matchUrl = html.match(/href="?(?https?:\/\/.*?)"?[\s>]/) + const url = matchUrl ? xss.escapeAttrValue(matchUrl.groups.url) : undefined + + return `` +} + +function toText(markupObj) { + return markupFilter.noMixed + .process(xmlFlow.toXml(markupObj)) + .replace(/\s+/g, ' ') + .trim() +} + +function toMixedBasic(markupObj) { + return markupFilter.mixedBasic + .process(xmlFlow.toXml(markupObj)) + .replace(/\s+/g, ' ') + .trim() +} + +function toMixedExtended(markupObj) { + return markupFilter.mixedExtended + .process(xmlFlow.toXml(markupObj)) + .replace(/\s+/g, ' ') + .trim() +} + +function toMixedOther(markupObj) { + return markupFilter.mixedOther + .process(xmlFlow.toXml(markupObj)) + .replace(/\s+/g, ' ') + .trim() +} diff --git a/express/models/helpers/dictionary/index.js b/express/models/helpers/dictionary/index.js new file mode 100644 index 0000000..26d8a77 --- /dev/null +++ b/express/models/helpers/dictionary/index.js @@ -0,0 +1,196 @@ +const { removeHtmlTags } = require('../../helpers') +const { searchEngineClient, ENTRY_INDEX } = require('../../search-engine') + +exports.deserialize = { + primaryDomain(domain) { + const deserializedDomain = { + id: domain.id, + nameSl: domain.name_sl, + nameEn: domain.name_en + } + + return deserializedDomain + }, + + secondaryDomain(domain) { + const deserializedDomain = { + id: domain.id, + isApproved: domain.approved, + nameSl: domain.name_sl, + nameEn: domain.name_en + } + + return deserializedDomain + }, + + approvedSecondaryDomain(domain) { + const deserializedDomain = { + id: domain.id, + nameSl: domain.name_sl, + nameEn: domain.name_en + } + + return deserializedDomain + }, + + language(language) { + const deserializedLanguage = { + id: language.id, + code: language.code, + nameSl: language.name_sl, + nameEn: language.name_en + } + + return deserializedLanguage + }, + + editDescription(dictionary) { + const deserializedDictionary = { + id: dictionary.id, + nameSl: dictionary.name_sl, + nameEn: dictionary.name_en, + nameSlShort: dictionary.name_sl_short, + author: dictionary.author, + domainPrimary: dictionary.domain_primary_id, + description: dictionary.description, + issn: dictionary.issn + } + + return deserializedDictionary + }, + + editUsers(dictionary) { + const deserializedDictionary = { + id: dictionary.id, + nameSl: dictionary.name_sl, + terminologyReviewFlag: dictionary.entries_have_terminology_review_flag, + languageReviewFlag: dictionary.entries_have_language_review_flag, + status: dictionary.status + } + + return deserializedDictionary + }, + + editStructure(dictionary) { + const deserializedDictionary = { + id: dictionary.id, + nameSl: dictionary.name_sl, + hasDomainLabels: dictionary.entries_have_domain_labels, + hasLabel: dictionary.entries_have_label, + hasDefinition: dictionary.entries_have_definition, + hasSynonyms: dictionary.entries_have_synonyms, + hasLinks: dictionary.entries_have_links, + hasOther: dictionary.entries_have_other, + hasForeignLanguages: dictionary.entries_have_foreign_languages, + hasForeignDefinitions: dictionary.entries_have_foreign_definitions, + hasForeignSynonyms: dictionary.entries_have_foreign_synonyms, + hasImages: dictionary.entries_have_images, + hasAudio: dictionary.entries_have_audio, + hasVideo: dictionary.entries_have_videos + } + + return deserializedDictionary + }, + + editDomainLabels(domainLabel) { + const deserializedDomainLabel = { + id: domainLabel.id, + name: domainLabel.name, + isVisible: domainLabel.is_visible + } + + return deserializedDomainLabel + }, + + imports(oneImport) { + const deserializedImports = { + timeStarted: oneImport.time_started, + status: oneImport.status, + deleteExisting: oneImport.delete_existing_entries, + fileFormat: oneImport.file_format, + countValidEntries: oneImport.count_valid_entries + } + + return deserializedImports + } +} + +exports.bulkIndex = async (entries, primaryDomain, dictionary, source) => { + const entriesCount = entries.length + if (!entries.length) return + + // Construct request body. + const bulkBody = new Array(entriesCount * 2) + for (let i = 0; i < entriesCount; i++) { + let entry = prepareEntryForIndexing(entries[i]) + bulkBody[i * 2] = { index: { _index: ENTRY_INDEX, _id: entry.id } } + + entry.primaryDomain = primaryDomain + entry.dictionary = dictionary + entry.source = source + entry = removeHtmlTags(JSON.stringify(entry)) + bulkBody[i * 2 + 1] = entry + } + + // Send the request. + const bulkResponse = await searchEngineClient.bulk({ body: bulkBody }) + + // Log possible errors. + if (bulkResponse.errors) { + const erroredDocuments = [] + bulkResponse.items.forEach((action, i) => { + const operation = Object.keys(action)[0] + if (action[operation].error) { + erroredDocuments.push({ + // If the status is 429 it means that you can retry the document, + // otherwise it's very likely a mapping error, and you should + // fix the document before to try it again. + status: action[operation].status, + error: action[operation].error, + operation: action[operation].body[i * 2], + document: action[operation].body[i * 2 + 1] + }) + } + }) + console.log('Errors indexing documents:') // eslint-disable-line no-console + console.log(erroredDocuments) // eslint-disable-line no-console + } +} + +function prepareEntryForIndexing(entry) { + // Snake case property names into camel case. + entry.isValid = entry.is_valid + delete entry.is_valid + + entry.isPublished = entry.is_published + delete entry.is_published + + entry.isTerminologyReviewed = entry.is_terminology_reviewed + delete entry.is_terminology_reviewed + + entry.isLanguageReviewed = entry.is_language_reviewed + delete entry.is_language_reviewed + + entry.homonymSort = entry.homonym_sort + delete entry.homonym_sort + + entry.timeMostRecentComment = entry.time_most_recent_comment + delete entry.time_most_recent_comment + + entry.domainLabels = entry.domain_labels + delete entry.domain_labels + + entry.foreignEntries = entry.foreign_entries + delete entry.foreign_entries + + // Remove (top-level) properies with null or empty array values. + entry = Object.fromEntries( + Object.entries(entry).filter( + ([_, v]) => v !== null && (!Array.isArray(v) || v.length) + ) + ) + + return entry +} + +exports.prepareEntryForIndexing = prepareEntryForIndexing diff --git a/express/models/helpers/extraction.js b/express/models/helpers/extraction.js new file mode 100644 index 0000000..75c7ca6 --- /dev/null +++ b/express/models/helpers/extraction.js @@ -0,0 +1,62 @@ +const { readdir, stat } = require('fs/promises') +const { partial } = require('filesize') +const { DATA_FILES_PATH } = require('../../config/settings') + +const formatFileSize = partial({ separator: ',' }) + +exports.deserialize = { + extraction(extraction) { + const deserializedExtraction = { + id: extraction.id, + name: extraction.name, + status: extraction.status, + corpusId: extraction.corpus_id, + timeStarted: extraction.time_started, + timeFinished: extraction.time_finished, + ossParams: extraction.oss_params + } + + return deserializedExtraction + } +} + +exports.getExtractionFilesPath = getExtractionFilesPath + +exports.getDocumentsPath = extractionId => { + return `${getExtractionFilesPath(extractionId)}/documents` +} + +exports.getStopTermsPath = extractionId => { + return `${getExtractionFilesPath(extractionId)}/stop_terms` +} + +exports.getConllusPath = extractionId => { + return `${getExtractionFilesPath(extractionId)}/conllu` +} + +exports.getTermCandidatesPath = extractionId => { + return `${getExtractionFilesPath(extractionId)}/term_candidates.json` +} + +exports.getFileNamesInFolder = async folderPath => { + const filenames = await readdir(folderPath) + return filenames +} + +exports.getFileStatsInFolder = async folderPath => { + const filenames = await readdir(folderPath) + const fileStats = await Promise.all( + filenames.map(async filename => { + const filePath = `${folderPath}/${filename}` + const { mtimeMs: timeModified, size } = await stat(filePath) + const sizeHumanReadable = formatFileSize(size) + const fileStats = { filename, size: sizeHumanReadable, timeModified } + return fileStats + }) + ) + return fileStats +} + +function getExtractionFilesPath(extractionId) { + return `${DATA_FILES_PATH}/extraction/${extractionId}` +} diff --git a/express/models/helpers/index.js b/express/models/helpers/index.js new file mode 100644 index 0000000..70610c3 --- /dev/null +++ b/express/models/helpers/index.js @@ -0,0 +1,73 @@ +const xss = require('xss') +const cache = require('../cache') +const Portal = require('../portal') + +const INSTANCE_SETTING_NAMESPACE = 'instance-setting' +const INSTANCE_SETTING_CACHE_EXPIRE_TIME = 60 * 60 // 1 hour. +const SLOVENIAN_LANGUAGE_ID_CACHE_EXPIRE_TIME = 60 * 60 // 1 hour. + +exports.intoDbArray = (inputData, mode) => { + if (Array.isArray(inputData)) { + return inputData + } else if (inputData === undefined || inputData === '') { + if (mode === 'always') return [] + if (mode === 'undefined') return undefined + else return null + // return mode === 'always' ? [] : null + } + return [inputData] +} + +exports.removeHtmlTags = text => { + return tagFilter.process(text) +} + +// Returns setting value by its name from table instance_settings. +exports.getInstanceSetting = async settingName => { + const settingCacheName = `${INSTANCE_SETTING_NAMESPACE}:${settingName}` + let settingValue = await cache.get(settingCacheName) + + if (!settingValue) { + settingValue = await Portal.getInstanceSettingValue(settingName) + await cache.set( + settingCacheName, + settingValue, + 'EX', + INSTANCE_SETTING_CACHE_EXPIRE_TIME + ) + } + + return settingValue +} + +// Deletes cached instance settings. +exports.clearCachedInstanceSettings = async () => { + const settingNames = await Portal.fetchAllInstanceSettingNames() + const settingCacheNames = settingNames.map( + settingName => `${INSTANCE_SETTING_NAMESPACE}:${settingName}` + ) + await cache.unlink(...settingCacheNames) +} + +// Returns slovenian language id and keeps it cached. +exports.getSlovenianLanguageId = async () => { + const settingCacheName = 'slovenian-language-id' + let id = await cache.get(settingCacheName) + + if (!id) { + id = (await Portal.getSlovenianLanguageId()).toString() + await cache.set( + settingCacheName, + id, + 'EX', + SLOVENIAN_LANGUAGE_ID_CACHE_EXPIRE_TIME + ) + } + + return id +} + +const tagFilter = new xss.FilterXSS({ + whiteList: {}, + stripIgnoreTag: true +}) diff --git a/express/models/helpers/portal/index.js b/express/models/helpers/portal/index.js new file mode 100644 index 0000000..8af4333 --- /dev/null +++ b/express/models/helpers/portal/index.js @@ -0,0 +1,67 @@ +exports.aggregateSettings = settings => { + const deserializedSettings = settings.reduce((agg, setting) => { + agg[setting.name] = setting.value + return agg + }, {}) + return deserializedSettings +} + +exports.deserialize = { + settings(settings) { + const deserializedSettings = { + name: settings.portal_name, + description: settings.portal_description, + code: settings.portal_code, + isExtractionEnabled: settings.is_extraction_enabled, + isDictionariesEnabled: settings.is_dictionaries_enabled, + isConsultancyEnabled: settings.is_consultancy_enabled + } + + return deserializedSettings + }, + dictSettings(settings) { + const deserializedSettings = { + minEntriesPerDictionary: settings.min_entries_per_dictionary, + dictionaryPublishApproval: settings.dictionary_publish_approval, + // keepNumOfExportsPerDict: settings.keep_num_of_exports_per_dictionary, + // dictionaryAutoSaveFrequency: settings.dictionary_auto_save_frequency, + numOfHistoryEntriesPerEntry: settings.num_of_history_entires_per_entry, + canPublishEntriesInEdit: settings.can_publish_entries_in_edit + } + + return deserializedSettings + }, + consultSettings(settings) { + const deserializedSettings = { + consultancyType: settings.consultancy_type, + zrcEmail: settings.zrc_email, + zrcURL: settings.zrc_url + } + + return deserializedSettings + }, + connections(connection) { + const deserializedConnections = { + id: connection.id, + name: connection.name, + indexURL: connection.url_index, + code: connection.code, + isEnabled: connection.is_enabled, + synced: connection.time_last_synced, + isLinked: connection.is_linked, + URLupdate: connection.url_update + } + + return deserializedConnections + }, + dictionaries(dictionary) { + const deserializeDictionaries = { + id: dictionary.id, + name: dictionary.name, + code: dictionary.code, + isEnabled: dictionary.is_enabled + } + + return deserializeDictionaries + } +} diff --git a/express/models/helpers/search/generate-query/consultancy/all.js b/express/models/helpers/search/generate-query/consultancy/all.js new file mode 100644 index 0000000..3d87ae8 --- /dev/null +++ b/express/models/helpers/search/generate-query/consultancy/all.js @@ -0,0 +1,40 @@ +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = function (filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + filter: [] + } + }, + sort: ['_score', 'timeCreated'] + } + + if (filters.status) { + queryDsl.query.bool.filter.push({ + term: { + status: filters.status + } + }) + } + + if (filters.assignedConsultant) { + queryDsl.query.bool.filter.push({ + term: { + 'assignedConsultants.id': filters.assignedConsultant + } + }) + } + + if (filters.primaryDomain) { + queryDsl.query.bool.filter.push({ + term: { + 'primaryDomain.id': filters.primaryDomain + } + }) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/consultancy/phrase.js b/express/models/helpers/search/generate-query/consultancy/phrase.js new file mode 100644 index 0000000..8a291c0 --- /dev/null +++ b/express/models/helpers/search/generate-query/consultancy/phrase.js @@ -0,0 +1,76 @@ +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = function (searchString, filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: { + match_phrase: { + title: searchString + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + match_phrase: { + question: searchString + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + match_phrase: { + answer: searchString + } + }, + boost: 1 + } + } + ] + } + }, + filter: [] + } + }, + sort: ['_score', 'timeCreated'] + } + + if (filters.status) { + queryDsl.query.bool.filter.push({ + term: { + status: filters.status + } + }) + } + + if (filters.assignedConsultant) { + queryDsl.query.bool.filter.push({ + term: { + 'assignedConsultants.id': filters.assignedConsultant + } + }) + } + + if (filters.primaryDomain) { + queryDsl.query.bool.filter.push({ + term: { + 'primaryDomain.id': filters.primaryDomain + } + }) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/consultancy/wildcard.js b/express/models/helpers/search/generate-query/consultancy/wildcard.js new file mode 100644 index 0000000..138565c --- /dev/null +++ b/express/models/helpers/search/generate-query/consultancy/wildcard.js @@ -0,0 +1,70 @@ +const { queryForField } = require('../..') + +const whitespace = /\s+/ + +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = function (searchString, filters, hitsPerPage, page) { + const searchTokens = searchString.split(whitespace) + + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: queryForField('title', searchTokens), + boost: 3 + } + }, + { + constant_score: { + filter: queryForField('question', searchTokens), + boost: 2 + } + }, + { + constant_score: { + filter: queryForField('answer', searchTokens), + boost: 1 + } + } + ] + } + }, + filter: [] + } + }, + sort: ['_score', 'timeCreated'] + } + + if (filters.status) { + queryDsl.query.bool.filter.push({ + term: { + status: filters.status + } + }) + } + + if (filters.assignedConsultant) { + queryDsl.query.bool.filter.push({ + term: { + 'assignedConsultants.id': filters.assignedConsultant + } + }) + } + + if (filters.primaryDomain) { + queryDsl.query.bool.filter.push({ + term: { + 'primaryDomain.id': filters.primaryDomain + } + }) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/consultancy/words.js b/express/models/helpers/search/generate-query/consultancy/words.js new file mode 100644 index 0000000..4f27ecf --- /dev/null +++ b/express/models/helpers/search/generate-query/consultancy/words.js @@ -0,0 +1,85 @@ +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = function (searchString, filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: { + match: { + title: { + query: searchString, + operator: 'and' + } + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + match: { + question: { + query: searchString, + operator: 'and' + } + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + match: { + answer: { + query: searchString, + operator: 'and' + } + } + }, + boost: 1 + } + } + ] + } + }, + filter: [] + } + }, + sort: ['_score', 'timeCreated'] + } + + if (filters.status) { + queryDsl.query.bool.filter.push({ + term: { + status: filters.status + } + }) + } + + if (filters.assignedConsultant) { + queryDsl.query.bool.filter.push({ + term: { + 'assignedConsultants.id': filters.assignedConsultant + } + }) + } + + if (filters.primaryDomain) { + queryDsl.query.bool.filter.push({ + term: { + 'primaryDomain.id': filters.primaryDomain + } + }) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/editor/all.js b/express/models/helpers/search/generate-query/editor/all.js new file mode 100644 index 0000000..2af3598 --- /dev/null +++ b/express/models/helpers/search/generate-query/editor/all.js @@ -0,0 +1,129 @@ +const { EDITOR_MAX_HITS } = require('../../../../../config/settings') + +module.exports = function (dictionaryId, filters, searchFieldFilters) { + const queryDsl = { + _source: ['id', 'isValid', 'isPublished', 'term'], + fields: ['foreignEntries.terms'], + script_fields: { + commentActivityIndicator: { + script: { + source: ` + if (!doc.containsKey('timeMostRecentComment') || doc['timeMostRecentComment'].empty) return ""; + + ZonedDateTime mostRecentCommentTime = doc['timeMostRecentComment'].value; + + long nowMilli = params['now']; + Instant nowInstant = Instant.ofEpochMilli(nowMilli); + ZonedDateTime now = ZonedDateTime.ofInstant(nowInstant, ZoneId.of('Z')); + + long ageInDays = ChronoUnit.DAYS.between(mostRecentCommentTime, now); + + if (ageInDays < 7) { + return "T" + } else if (ageInDays < 30) { + return "M" + } else if (ageInDays < 365) { + return "L" + } else { + return "" + } + `, + params: { + now: Date.now() + } + } + } + }, + size: EDITOR_MAX_HITS, + query: { + bool: { + filter: [ + { + term: { + 'dictionary.id': dictionaryId + } + } + ] + } + }, + sort: ['term.sort', 'homonymSort'] + } + + if (searchFieldFilters) queryDsl.query.bool.filter.push(searchFieldFilters) + + if (filters) { + if (filters.isValid !== undefined) { + queryDsl.query.bool.filter.push({ + term: { + isValid: filters.isValid + } + }) + } + + if (filters.isPublished !== undefined) { + queryDsl.query.bool.filter.push({ + term: { + isPublished: filters.isPublished + } + }) + } + + if (filters.hasComments !== undefined) { + if (filters.hasComments === true) { + queryDsl.query.bool.filter.push({ + exists: { + field: 'timeMostRecentComment' + } + }) + } else { + queryDsl.query.bool.filter.push({ + bool: { + must_not: { + exists: { + field: 'timeMostRecentComment' + } + } + } + }) + } + } + + if (filters.isComplete !== undefined) { + if (filters.isComplete === true) { + queryDsl.query.bool.filter.push({ + term: { + status: 'complete' + } + }) + } else { + queryDsl.query.bool.filter.push({ + bool: { + must_not: { + term: { + status: 'complete' + } + } + } + }) + } + } + + if (filters.isTerminologyReviewed !== undefined) { + queryDsl.query.bool.filter.push({ + term: { + isTerminologyReviewed: filters.isTerminologyReviewed + } + }) + } + + if (filters.isLanguageReviewed !== undefined) { + queryDsl.query.bool.filter.push({ + term: { + isLanguageReviewed: filters.isLanguageReviewed + } + }) + } + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/editor/exists.js b/express/models/helpers/search/generate-query/editor/exists.js new file mode 100644 index 0000000..a66765d --- /dev/null +++ b/express/models/helpers/search/generate-query/editor/exists.js @@ -0,0 +1,103 @@ +const { fieldMap } = require('../..') +const generateQuery = require('./all') + +module.exports = function (dictionaryId, searchField, filters) { + const searchFieldFilters = generateSearchFieldFilters(searchField) + + const queryDsl = generateQuery(dictionaryId, filters, searchFieldFilters) + + return queryDsl +} + +function generateSearchFieldFilters(searchField) { + const mappedName = fieldMap[searchField] + + if (mappedName) { + if (mappedName.startsWith('foreignEntries')) { + return { + nested: { + path: 'foreignEntries', + query: { + exists: { + field: mappedName + } + } + } + } + } + + return { + exists: { + field: mappedName + } + } + } + + return { + dis_max: { + queries: [ + { + exists: { + field: 'term' + } + }, + { + exists: { + field: 'synonyms' + } + }, + { + exists: { + field: 'label' + } + }, + { + exists: { + field: 'definition' + } + }, + { + exists: { + field: 'other' + } + }, + { + exists: { + field: 'domainLabels' + } + }, + { + exists: { + field: 'links' + } + }, + { + nested: { + path: 'foreignEntries', + query: { + dis_max: { + queries: [ + { + exists: { + field: 'foreignEntries.terms' + } + }, + { + exists: { + field: 'foreignEntries.synonyms' + } + }, + { + exists: { + field: 'foreignEntries.definition' + } + } + ] + } + } + } + } + ] + } + } +} diff --git a/express/models/helpers/search/generate-query/editor/phrase.js b/express/models/helpers/search/generate-query/editor/phrase.js new file mode 100644 index 0000000..bf85148 --- /dev/null +++ b/express/models/helpers/search/generate-query/editor/phrase.js @@ -0,0 +1,76 @@ +const { fieldMap } = require('../..') +const generateQuery = require('./all') + +module.exports = function (dictionaryId, searchField, searchString, filters) { + const searchFieldFilters = generateSearchFieldFilters( + searchField, + searchString + ) + + const queryDsl = generateQuery(dictionaryId, filters, searchFieldFilters) + + return queryDsl +} + +function generateSearchFieldFilters(searchField, searchString) { + const mappedName = fieldMap[searchField] + + if (mappedName) { + if (mappedName.startsWith('foreignEntries')) { + return { + nested: { + path: 'foreignEntries', + query: { + match_phrase: { + [mappedName]: searchString + } + } + } + } + } + + return { + match_phrase: { + [mappedName]: searchString + } + } + } + + return { + dis_max: { + queries: [ + { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }, + { + nested: { + path: 'foreignEntries', + query: { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + } + } + } + ] + } + } +} diff --git a/express/models/helpers/search/generate-query/editor/wildcard.js b/express/models/helpers/search/generate-query/editor/wildcard.js new file mode 100644 index 0000000..182b19e --- /dev/null +++ b/express/models/helpers/search/generate-query/editor/wildcard.js @@ -0,0 +1,62 @@ +const { fieldMap, queryForField } = require('../..') +const generateQuery = require('./all') + +const whitespace = /\s+/ + +module.exports = function (dictionaryId, searchField, searchString, filters) { + const searchFieldFilters = generateSearchFieldFilters( + searchField, + searchString + ) + + const queryDsl = generateQuery(dictionaryId, filters, searchFieldFilters) + + return queryDsl +} + +function generateSearchFieldFilters(searchField, searchString) { + const searchTokens = searchString.split(whitespace) + + const mappedName = fieldMap[searchField] + + if (mappedName) { + if (mappedName.startsWith('foreignEntries')) { + return { + nested: { + path: 'foreignEntries', + query: queryForField(mappedName, searchTokens) + } + } + } + + return queryForField(mappedName, searchTokens) + } + + return { + dis_max: { + queries: [ + queryForField('term', searchTokens), + queryForField('synonyms', searchTokens), + queryForField('label', searchTokens), + queryForField('definition', searchTokens), + queryForField('other', searchTokens), + queryForField('domainLabels', searchTokens), + queryForField('links', searchTokens), + { + nested: { + path: 'foreignEntries', + query: { + dis_max: { + queries: [ + queryForField('foreignEntries.terms', searchTokens), + queryForField('foreignEntries.synonyms', searchTokens), + queryForField('foreignEntries.definition', searchTokens) + ] + } + } + } + } + ] + } + } +} diff --git a/express/models/helpers/search/generate-query/editor/words.js b/express/models/helpers/search/generate-query/editor/words.js new file mode 100644 index 0000000..2d0dbc9 --- /dev/null +++ b/express/models/helpers/search/generate-query/editor/words.js @@ -0,0 +1,82 @@ +const { fieldMap } = require('../..') +const generateQuery = require('./all') + +module.exports = function (dictionaryId, searchField, searchString, filters) { + const searchFieldFilters = generateSearchFieldFilters( + searchField, + searchString + ) + + const queryDsl = generateQuery(dictionaryId, filters, searchFieldFilters) + + return queryDsl +} + +function generateSearchFieldFilters(searchField, searchString) { + const mappedName = fieldMap[searchField] + + if (mappedName) { + if (mappedName.startsWith('foreignEntries')) { + return { + nested: { + path: 'foreignEntries', + query: { + match: { + [mappedName]: { + query: searchString, + operator: 'and' + } + } + } + } + } + } + + return { + match: { + [mappedName]: { + query: searchString, + operator: 'and' + } + } + } + } + + return { + dis_max: { + queries: [ + { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }, + { + nested: { + path: 'foreignEntries', + query: { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + } + } + } + ] + } + } +} diff --git a/express/models/helpers/search/generate-query/index.js b/express/models/helpers/search/generate-query/index.js new file mode 100644 index 0000000..d52577c --- /dev/null +++ b/express/models/helpers/search/generate-query/index.js @@ -0,0 +1,183 @@ +const debug = require('debug')('termPortal:generate-query') +const genAllHitQuery = require('./main/all') +const genAllAggQuery = require('./main/aggregate-all') +const genPhraseHitQuery = require('./main/phrase') +const genPhraseAggQuery = require('./main/aggregate-phrase') +const genWildcardHitQuery = require('./main/wildcard') +const genWildcardAggQuery = require('./main/aggregate-wildcard') +const genMultiWordHitQuery = require('./main/word-multi') +const genWordAggQuery = require('./main/aggregate-word') +const genSingleWordHitQuery = require('./main/word-single') +const genEditorAllQuery = require('./editor/all') +const genEditorExistsQuery = require('./editor/exists') +const genEditorPhraseQuery = require('./editor/phrase') +const genEditorWildcardQuery = require('./editor/wildcard') +const genEditorWordsQuery = require('./editor/words') +const genConsultancyAllQuery = require('./consultancy/all') +const genConsultancyPhraseQuery = require('./consultancy/phrase') +const genConsultancyWildcardQuery = require('./consultancy/wildcard') +const genConsultancyWordsQuery = require('./consultancy/words') + +const notOnlyAsterisks = /[^*"\s]/ +const hasWildcards = /[*?]/ +const hasWhitespace = /\s/ + +// Determines query type, constructs and returns appropriate search engine query(es). +exports.main = async ( + searchString, + filters, + hitsPerPage, + page, + withAggregation +) => { + let hitsQuery + let aggregateQuery + + const firstChar = searchString[0] + const lastChar = searchString[searchString.length - 1] + + // TODO Aditional sanitization/transformation? + + if (!notOnlyAsterisks.test(searchString)) { + debug('query type: all') + hitsQuery = genAllHitQuery(filters, hitsPerPage, page) + if (withAggregation) { + aggregateQuery = genAllAggQuery(hitsQuery) + } + } else if (firstChar === '"' && lastChar === '"') { + debug('query type: phrase') + searchString = searchString.slice(1, -1) + hitsQuery = await genPhraseHitQuery( + searchString, + filters, + hitsPerPage, + page + ) + if (withAggregation) { + aggregateQuery = genPhraseAggQuery(searchString, hitsQuery) + } + } else if (hasWildcards.test(searchString)) { + debug('query type: wildcard') + let slovenianFieldQueries, foreignFieldQueries + ;[hitsQuery, slovenianFieldQueries, foreignFieldQueries] = + await genWildcardHitQuery(searchString, filters, hitsPerPage, page) + if (withAggregation) { + aggregateQuery = genWildcardAggQuery( + hitsQuery, + slovenianFieldQueries, + foreignFieldQueries + ) + } + } else if (hasWhitespace.test(searchString)) { + debug('query type: multi word') + hitsQuery = await genMultiWordHitQuery( + searchString, + filters, + hitsPerPage, + page + ) + if (withAggregation) { + aggregateQuery = genWordAggQuery(searchString, hitsQuery) + } + } else { + debug('query type: single word') + hitsQuery = await genSingleWordHitQuery( + searchString, + filters, + hitsPerPage, + page + ) + if (withAggregation) { + aggregateQuery = genWordAggQuery(searchString, hitsQuery) + } + } + + return withAggregation ? [hitsQuery, aggregateQuery] : hitsQuery +} + +// Determines query type, constructs and returns appropriate search engine query for editor. +exports.editor = (dictionaryId, searchField, searchString, filters) => { + let hitsQuery + + const firstChar = searchString[0] + const lastChar = searchString[searchString.length - 1] + + // TODO Aditional sanitization/transformation? + + if (!searchString) { + debug('query type: all') + hitsQuery = genEditorAllQuery(dictionaryId, filters) + } else if (!notOnlyAsterisks.test(searchString)) { + debug('query type: exists') + hitsQuery = genEditorExistsQuery(dictionaryId, searchField, filters) + } else if (firstChar === '"' && lastChar === '"') { + debug('query type: phrase') + searchString = searchString.slice(1, -1) + hitsQuery = genEditorPhraseQuery( + dictionaryId, + searchField, + searchString, + filters + ) + } else if (hasWildcards.test(searchString)) { + debug('query type: wildcard') + hitsQuery = genEditorWildcardQuery( + dictionaryId, + searchField, + searchString, + filters + ) + } else { + debug('query type: words') + hitsQuery = genEditorWordsQuery( + dictionaryId, + searchField, + searchString, + filters + ) + } + + return hitsQuery +} + +// Determines query type, constructs and returns appropriate search engine query for consultancy. +exports.consultancy = (searchString, filters, hitsPerPage, page) => { + let hitsQuery + + const firstChar = searchString[0] + const lastChar = searchString[searchString.length - 1] + + // TODO Aditional sanitization/transformation? + + if (!notOnlyAsterisks.test(searchString)) { + debug('query type: all') + hitsQuery = genConsultancyAllQuery(filters, hitsPerPage, page) + } else if (firstChar === '"' && lastChar === '"') { + debug('query type: phrase') + searchString = searchString.slice(1, -1) + hitsQuery = genConsultancyPhraseQuery( + searchString, + filters, + hitsPerPage, + page + ) + } else if (hasWildcards.test(searchString)) { + debug('query type: wildcard') + hitsQuery = genConsultancyWildcardQuery( + searchString, + filters, + hitsPerPage, + page + ) + } else { + debug('query type: words') + hitsQuery = genConsultancyWordsQuery( + searchString, + filters, + hitsPerPage, + page + ) + } + + return hitsQuery +} diff --git a/express/models/helpers/search/generate-query/main/aggregate-all.js b/express/models/helpers/search/generate-query/main/aggregate-all.js new file mode 100644 index 0000000..ffc8dc2 --- /dev/null +++ b/express/models/helpers/search/generate-query/main/aggregate-all.js @@ -0,0 +1,42 @@ +module.exports = function (hitsQuery) { + // A shallow copy will prevent hitsQuery from being modified. + const queryDsl = { ...hitsQuery } + + queryDsl.from = 0 + queryDsl.size = 0 + + queryDsl.aggs = { + primaryDomains: { + terms: { + field: 'primaryDomain.id', + size: 100 + } + }, + dictionaries: { + terms: { + field: 'dictionary.id', + size: 200 + } + }, + sources: { + terms: { + field: 'source.code' + } + }, + foreign: { + nested: { + path: 'foreignEntries' + }, + aggs: { + targetLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + } + } + } + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/aggregate-phrase.js b/express/models/helpers/search/generate-query/main/aggregate-phrase.js new file mode 100644 index 0000000..1d2df02 --- /dev/null +++ b/express/models/helpers/search/generate-query/main/aggregate-phrase.js @@ -0,0 +1,80 @@ +module.exports = function (searchString, hitsQuery) { + // A shallow copy will prevent hitsQuery from being modified. + const queryDsl = { ...hitsQuery } + + queryDsl.from = 0 + queryDsl.size = 0 + + queryDsl.aggs = { + primaryDomains: { + terms: { + field: 'primaryDomain.id', + size: 100 + } + }, + dictionaries: { + terms: { + field: 'dictionary.id', + size: 200 + } + }, + sources: { + terms: { + field: 'source.code' + } + }, + slovenianHits: { + filter: { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + } + }, + foreign: { + nested: { + path: 'foreignEntries' + }, + aggs: { + targetLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + }, + foreignHits: { + filter: { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + }, + aggs: { + sourceLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + } + } + } + } + } + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/aggregate-wildcard.js b/express/models/helpers/search/generate-query/main/aggregate-wildcard.js new file mode 100644 index 0000000..6be1240 --- /dev/null +++ b/express/models/helpers/search/generate-query/main/aggregate-wildcard.js @@ -0,0 +1,68 @@ +module.exports = function ( + hitsQuery, + slovenianFieldQueries, + foreignFieldQueries +) { + // A shallow copy will prevent hitsQuery from being modified. + const queryDsl = { ...hitsQuery } + + queryDsl.from = 0 + queryDsl.size = 0 + + queryDsl.aggs = { + primaryDomains: { + terms: { + field: 'primaryDomain.id', + size: 100 + } + }, + dictionaries: { + terms: { + field: 'dictionary.id', + size: 200 + } + }, + sources: { + terms: { + field: 'source.code' + } + }, + slovenianHits: { + filter: { + dis_max: { + queries: slovenianFieldQueries + } + } + }, + foreign: { + nested: { + path: 'foreignEntries' + }, + aggs: { + targetLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + }, + foreignHits: { + filter: { + dis_max: { + queries: foreignFieldQueries + } + }, + aggs: { + sourceLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + } + } + } + } + } + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/aggregate-word.js b/express/models/helpers/search/generate-query/main/aggregate-word.js new file mode 100644 index 0000000..64da9bb --- /dev/null +++ b/express/models/helpers/search/generate-query/main/aggregate-word.js @@ -0,0 +1,80 @@ +module.exports = function (searchString, hitsQuery) { + // A shallow copy will prevent hitsQuery from being modified. + const queryDsl = { ...hitsQuery } + + queryDsl.from = 0 + queryDsl.size = 0 + + queryDsl.aggs = { + primaryDomains: { + terms: { + field: 'primaryDomain.id', + size: 100 + } + }, + dictionaries: { + terms: { + field: 'dictionary.id', + size: 200 + } + }, + sources: { + terms: { + field: 'source.code' + } + }, + slovenianHits: { + filter: { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + } + }, + foreign: { + nested: { + path: 'foreignEntries' + }, + aggs: { + targetLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + }, + foreignHits: { + filter: { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + }, + aggs: { + sourceLanguages: { + terms: { + field: 'foreignEntries.lang.id', + size: 50 + } + } + } + } + } + } + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/all.js b/express/models/helpers/search/generate-query/main/all.js new file mode 100644 index 0000000..a5af3f8 --- /dev/null +++ b/express/models/helpers/search/generate-query/main/all.js @@ -0,0 +1,64 @@ +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = function (filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + filter: [ + { + term: { + isPublished: true + } + }, + { + term: { + 'dictionary.status': 'published' + } + } + ] + } + }, + sort: ['_score', 'term.sort', 'homonymSort'] + } + + if (filters.primaryDomains.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'primaryDomain.id': filters.primaryDomains + } + }) + } + + if (filters.dictionaries.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'dictionary.id': filters.dictionaries + } + }) + } + + if (filters.sources.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'source.code': filters.sources + } + }) + } + + if (filters.targetLanguages.length) { + queryDsl.query.bool.filter.push({ + nested: { + path: 'foreignEntries', + query: { + terms: { + 'foreignEntries.lang.id': filters.targetLanguages + } + } + } + }) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/phrase.js b/express/models/helpers/search/generate-query/main/phrase.js new file mode 100644 index 0000000..2f19e0a --- /dev/null +++ b/express/models/helpers/search/generate-query/main/phrase.js @@ -0,0 +1,247 @@ +const { separateSlovenianLanguage } = require('../..') + +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = async function (searchString, filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: { + term: { + 'term.keyword': { + value: searchString + } + } + }, + boost: 6 + } + }, + { + constant_score: { + filter: { + match_phrase: { + term: searchString + } + }, + boost: 5 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: { + term: { + 'foreignEntries.terms.keyword': { + value: searchString + } + } + } + } + }, + boost: 4 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: { + match_phrase: { + 'foreignEntries.terms': searchString + } + } + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + match_phrase: { + synonyms: searchString + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match_phrase: { + 'foreignEntries.synonyms': searchString + } + } + } + } + ] + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match_phrase: { + 'foreignEntries.definition': searchString + } + } + } + } + ] + } + }, + boost: 1 + } + } + ] + } + }, + filter: [ + { + term: { + isPublished: true + } + }, + { + term: { + 'dictionary.status': 'published' + } + } + ] + } + }, + sort: ['_score', 'term.sort', 'homonymSort'] + } + + if (filters.primaryDomains.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'primaryDomain.id': filters.primaryDomains + } + }) + } + + if (filters.dictionaries.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'dictionary.id': filters.dictionaries + } + }) + } + + if (filters.sources.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'source.code': filters.sources + } + }) + } + + if (filters.targetLanguages.length) { + queryDsl.query.bool.filter.push({ + nested: { + path: 'foreignEntries', + query: { + terms: { + 'foreignEntries.lang.id': filters.targetLanguages + } + } + } + }) + } + + if (filters.sourceLanguages.length) { + const [foreignLanguages, isSlovenianSource] = + await separateSlovenianLanguage(filters.sourceLanguages) + + const sourceLanguageFilter = { + dis_max: { + queries: [] + } + } + + if (isSlovenianSource) { + sourceLanguageFilter.dis_max.queries.push({ + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }) + } + + if (foreignLanguages.length) { + sourceLanguageFilter.dis_max.queries.push({ + nested: { + path: 'foreignEntries', + query: { + bool: { + must: [ + { + terms: { + 'foreignEntries.lang.id': foreignLanguages + } + }, + { + multi_match: { + query: searchString, + type: 'phrase', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + } + ] + } + } + } + }) + } + + queryDsl.query.bool.filter.push(sourceLanguageFilter) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/wildcard.js b/express/models/helpers/search/generate-query/main/wildcard.js new file mode 100644 index 0000000..97a77ee --- /dev/null +++ b/express/models/helpers/search/generate-query/main/wildcard.js @@ -0,0 +1,207 @@ +const { separateSlovenianLanguage, queryForField } = require('../..') + +const whitespace = /\s+/ + +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = async function (searchString, filters, hitsPerPage, page) { + const searchTokens = searchString.split(whitespace) + + const termQuery = queryForField('term', searchTokens) + const foreignTermQuery = queryForField('foreignEntries.terms', searchTokens) + const synonymsQuery = queryForField('synonyms', searchTokens) + const foreignSynonymsQuery = queryForField( + 'foreignEntries.synonyms', + searchTokens + ) + const labelQuery = queryForField('label', searchTokens) + const definitionQuery = queryForField('definition', searchTokens) + const otherQuery = queryForField('other', searchTokens) + const domainLabelsQuery = queryForField('domainLabels', searchTokens) + const linksQuery = queryForField('links', searchTokens) + const foreignDefinitionQuery = queryForField( + 'foreignEntries.definition', + searchTokens + ) + + const slovenianFieldQueries = [ + termQuery, + synonymsQuery, + labelQuery, + definitionQuery, + otherQuery, + domainLabelsQuery, + linksQuery + ] + + const foreignFieldQueries = [ + foreignTermQuery, + foreignSynonymsQuery, + foreignDefinitionQuery + ] + + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: termQuery, + boost: 5 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: foreignTermQuery + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + synonymsQuery, + { + nested: { + path: 'foreignEntries', + query: foreignSynonymsQuery + } + } + ] + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + labelQuery, + definitionQuery, + otherQuery, + domainLabelsQuery, + linksQuery, + { + nested: { + path: 'foreignEntries', + query: foreignDefinitionQuery + } + } + ] + } + }, + boost: 1 + } + } + ] + } + }, + filter: [ + { + term: { + isPublished: true + } + }, + { + term: { + 'dictionary.status': 'published' + } + } + ] + } + }, + sort: ['_score', 'term.sort', 'homonymSort'] + } + + if (filters.primaryDomains.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'primaryDomain.id': filters.primaryDomains + } + }) + } + + if (filters.dictionaries.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'dictionary.id': filters.dictionaries + } + }) + } + + if (filters.sources.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'source.code': filters.sources + } + }) + } + + if (filters.targetLanguages.length) { + queryDsl.query.bool.filter.push({ + nested: { + path: 'foreignEntries', + query: { + terms: { + 'foreignEntries.lang.id': filters.targetLanguages + } + } + } + }) + } + + if (filters.sourceLanguages.length) { + const [foreignLanguages, isSlovenianSource] = + await separateSlovenianLanguage(filters.sourceLanguages) + + const sourceLanguageFilter = { + dis_max: { + queries: [] + } + } + + if (isSlovenianSource) { + sourceLanguageFilter.dis_max.queries.push(...slovenianFieldQueries) + } + + if (foreignLanguages.length) { + sourceLanguageFilter.dis_max.queries.push({ + nested: { + path: 'foreignEntries', + query: { + bool: { + must: [ + { + terms: { + 'foreignEntries.lang.id': foreignLanguages + } + }, + { + dis_max: { + queries: foreignFieldQueries + } + } + ] + } + } + } + }) + } + + queryDsl.query.bool.filter.push(sourceLanguageFilter) + } + + return [queryDsl, slovenianFieldQueries, foreignFieldQueries] +} diff --git a/express/models/helpers/search/generate-query/main/word-multi.js b/express/models/helpers/search/generate-query/main/word-multi.js new file mode 100644 index 0000000..92828b6 --- /dev/null +++ b/express/models/helpers/search/generate-query/main/word-multi.js @@ -0,0 +1,233 @@ +const { separateSlovenianLanguage } = require('../..') + +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = async function (searchString, filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: { + match: { + term: { + query: searchString, + operator: 'and' + } + } + }, + boost: 5 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.terms': { + query: searchString, + operator: 'and' + } + } + } + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + match: { + synonyms: { + query: searchString, + operator: 'and' + } + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.synonyms': { + query: searchString, + operator: 'and' + } + } + } + } + } + ] + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.definition': { + query: searchString, + operator: 'and' + } + } + } + } + } + ] + } + }, + boost: 1 + } + } + ] + } + }, + filter: [ + { + term: { + isPublished: true + } + }, + { + term: { + 'dictionary.status': 'published' + } + } + ] + } + }, + sort: ['_score', 'term.sort', 'homonymSort'] + } + + if (filters.primaryDomains.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'primaryDomain.id': filters.primaryDomains + } + }) + } + + if (filters.dictionaries.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'dictionary.id': filters.dictionaries + } + }) + } + + if (filters.sources.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'source.code': filters.sources + } + }) + } + + if (filters.targetLanguages.length) { + queryDsl.query.bool.filter.push({ + nested: { + path: 'foreignEntries', + query: { + terms: { + 'foreignEntries.lang.id': filters.targetLanguages + } + } + } + }) + } + + if (filters.sourceLanguages.length) { + const [foreignLanguages, isSlovenianSource] = + await separateSlovenianLanguage(filters.sourceLanguages) + + const sourceLanguageFilter = { + dis_max: { + queries: [] + } + } + + if (isSlovenianSource) { + sourceLanguageFilter.dis_max.queries.push({ + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }) + } + + if (foreignLanguages.length) { + sourceLanguageFilter.dis_max.queries.push({ + nested: { + path: 'foreignEntries', + query: { + bool: { + must: [ + { + terms: { + 'foreignEntries.lang.id': foreignLanguages + } + }, + { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + } + ] + } + } + } + }) + } + + queryDsl.query.bool.filter.push(sourceLanguageFilter) + } + + return queryDsl +} diff --git a/express/models/helpers/search/generate-query/main/word-single.js b/express/models/helpers/search/generate-query/main/word-single.js new file mode 100644 index 0000000..ebcb11b --- /dev/null +++ b/express/models/helpers/search/generate-query/main/word-single.js @@ -0,0 +1,262 @@ +const { separateSlovenianLanguage } = require('../..') + +// TODO Consider alternative paging when hits exceed 10000. + +module.exports = async function (searchString, filters, hitsPerPage, page) { + const queryDsl = { + from: hitsPerPage * (page - 1), + size: hitsPerPage, + query: { + bool: { + must: { + dis_max: { + queries: [ + { + constant_score: { + filter: { + term: { + 'term.keyword': { + value: searchString + } + } + }, + boost: 6 + } + }, + { + constant_score: { + filter: { + match: { + term: { + query: searchString, + operator: 'and' + } + } + }, + boost: 5 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: { + term: { + 'foreignEntries.terms.keyword': { + value: searchString + } + } + } + } + }, + boost: 4 + } + }, + { + constant_score: { + filter: { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.terms': { + query: searchString, + operator: 'and' + } + } + } + } + }, + boost: 3 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + match: { + synonyms: { + query: searchString, + operator: 'and' + } + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.synonyms': { + query: searchString, + operator: 'and' + } + } + } + } + } + ] + } + }, + boost: 2 + } + }, + { + constant_score: { + filter: { + dis_max: { + queries: [ + { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }, + { + nested: { + path: 'foreignEntries', + query: { + match: { + 'foreignEntries.definition': { + query: searchString, + operator: 'and' + } + } + } + } + } + ] + } + }, + boost: 1 + } + } + ] + } + }, + filter: [ + { + term: { + isPublished: true + } + }, + { + term: { + 'dictionary.status': 'published' + } + } + ] + } + }, + sort: ['_score', 'term.sort', 'homonymSort'] + } + + if (filters.primaryDomains.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'primaryDomain.id': filters.primaryDomains + } + }) + } + + if (filters.dictionaries.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'dictionary.id': filters.dictionaries + } + }) + } + + if (filters.sources.length) { + queryDsl.query.bool.filter.push({ + terms: { + 'source.code': filters.sources + } + }) + } + + if (filters.targetLanguages.length) { + queryDsl.query.bool.filter.push({ + nested: { + path: 'foreignEntries', + query: { + terms: { + 'foreignEntries.lang.id': filters.targetLanguages + } + } + } + }) + } + + if (filters.sourceLanguages.length) { + const [foreignLanguages, isSlovenianSource] = + await separateSlovenianLanguage(filters.sourceLanguages) + + const sourceLanguageFilter = { + dis_max: { + queries: [] + } + } + + if (isSlovenianSource) { + sourceLanguageFilter.dis_max.queries.push({ + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'term', + 'synonyms', + 'label', + 'definition', + 'other', + 'domainLabels', + 'links' + ] + } + }) + } + + if (foreignLanguages.length) { + sourceLanguageFilter.dis_max.queries.push({ + nested: { + path: 'foreignEntries', + query: { + bool: { + must: [ + { + terms: { + 'foreignEntries.lang.id': foreignLanguages + } + }, + { + multi_match: { + query: searchString, + operator: 'and', + fields: [ + 'foreignEntries.terms', + 'foreignEntries.synonyms', + 'foreignEntries.definition' + ] + } + } + ] + } + } + } + }) + } + + queryDsl.query.bool.filter.push(sourceLanguageFilter) + } + + return queryDsl +} diff --git a/express/models/helpers/search/index.js b/express/models/helpers/search/index.js new file mode 100644 index 0000000..1ec7bc6 --- /dev/null +++ b/express/models/helpers/search/index.js @@ -0,0 +1,225 @@ +const Portal = require('../../portal') +const { getSlovenianLanguageId } = require('..') + +const slCollator = new Intl.Collator('sl', { sensitivity: 'base' }) + +// Return a new array, with slovenian language removed and isSlovenianSource set to true if present. +exports.separateSlovenianLanguage = async languages => { + const slovenianLanguageId = await getSlovenianLanguageId() + let isSlovenianSource = false + + const foreignLanguages = languages.filter(language => { + if (language !== slovenianLanguageId) return true + + isSlovenianSource = true + return false + }) + + return [foreignLanguages, isSlovenianSource] +} + +// Simplify and enhance search engine's hits output into useful entries object. +exports.prepareEntries = hits => { + const entriesByCategory = hits.body.hits.hits.reduce( + (agg, hit) => { + const entry = hit._source + + switch (hit._score) { + case 6: + case 5: + agg.byTerm.push(entry) + break + case 4: + case 3: + agg.byForeignTerm.push(entry) + break + case 2: + case 1: + agg.byOther.push(entry) + break + default: + agg.uncategorized.push(entry) + } + + return agg + }, + { byTerm: [], byForeignTerm: [], byOther: [], uncategorized: [] } + ) + + return entriesByCategory +} + +// Transform search engine's aggregation raw output into correct and friendly format. +exports.prepareAggregation = async aggregationRaw => { + const { aggregations, hits } = aggregationRaw.body + + const hitsCount = hits.total.value + if (!hitsCount) return + + const primaryDomainIds = aggregations.primaryDomains.buckets.map( + bucket => bucket.key + ) + + const dictionaryIds = aggregations.dictionaries.buckets.map( + bucket => bucket.key + ) + + const languageIdSet = new Set() + const refinedSourceLanguageBuckets = [] + + aggregations.foreign.targetLanguages.buckets.forEach(bucket => + languageIdSet.add(bucket.key) + ) + + const slovenianHitCount = aggregations.slovenianHits?.doc_count + // "Match all" aggregation returns no slovenian hits and source languages. + if (slovenianHitCount) { + const slovenianLanguageId = await getSlovenianLanguageId() + const slovenianBucket = { + key: slovenianLanguageId, + doc_count: slovenianHitCount + } + let wasSlovenianBucketInserted = false + + aggregations.foreign.foreignHits.sourceLanguages.buckets.forEach(bucket => { + if (!wasSlovenianBucketInserted && bucket.doc_count < slovenianHitCount) { + languageIdSet.add(slovenianLanguageId) + refinedSourceLanguageBuckets.push(slovenianBucket) + wasSlovenianBucketInserted = true + } + languageIdSet.add(bucket.key) + refinedSourceLanguageBuckets.push(bucket) + }) + + if (!wasSlovenianBucketInserted) { + languageIdSet.add(slovenianLanguageId) + refinedSourceLanguageBuckets.push(slovenianBucket) + } + } else if (slovenianHitCount === 0) { + aggregations.foreign.foreignHits.sourceLanguages.buckets.forEach(bucket => { + languageIdSet.add(bucket.key) + refinedSourceLanguageBuckets.push(bucket) + }) + } + + const languageIds = [...languageIdSet] + + const names = await Portal.getSearchAggregateNames( + primaryDomainIds, + dictionaryIds, + languageIds + ) + + const aggregation = { + sourceLanguages: refinedSourceLanguageBuckets.map( + ({ key: id, doc_count: hits }) => { + return { id, name: names.languages[id], hits } + } + ), + targetLanguages: aggregations.foreign.targetLanguages.buckets.map( + ({ key: id, doc_count: hits }) => { + return { id, name: names.languages[id], hits } + } + ), + primaryDomains: aggregations.primaryDomains.buckets.map( + ({ key: id, doc_count: hits }) => { + return { id, name: names.primaryDomains[id], hits } + } + ), + dictionaries: aggregations.dictionaries.buckets.map( + ({ key: id, doc_count: hits }) => { + return { id, name: names.dictionaries[id], hits } + } + ), + sources: aggregations.sources.buckets.map( + ({ key: id, doc_count: hits }) => { + return { id, name: id, hits } + } + ) + } + + sortAggregation(aggregation) + + return aggregation +} + +// Enhance aggregation for display in search filters. +exports.prepareSeachFilterData = (aggregation, filters) => { + const enhancedAggregation = {} + + if (aggregation) { + for (const category of Object.keys(aggregation)) { + const enhancedCategoryMembers = aggregation[category].map(member => { + if (filters[category].includes(member.id)) member.checked = true + return member + }) + + enhancedAggregation[category] = enhancedCategoryMembers + } + } + + return enhancedAggregation +} + +// Maps editor search api field names into search engine ones. +exports.fieldMap = { + term: 'term', + synonyms: 'synonyms', + label: 'label', + definition: 'definition', + other: 'other', + domainLabels: 'domainLabels', + links: 'links', + foreignTerms: 'foreignEntries.terms', + foreignSynonyms: 'foreignEntries.synonyms', + foreignDefinition: 'foreignEntries.definition' +} + +// Generate search engine DSL wildcard query fragment for a single field. +exports.queryForField = (field, searchTokens) => { + return { + bool: { + filter: searchTokens.map(token => { + return { + wildcard: { + [field]: { + value: token + } + } + } + }) + } + } +} + +// Simplify and enhance search engine's editor hits output into useful entries list. +exports.prepareEditorEntries = hits => { + const entries = hits.body.hits.hits.map(hit => { + const entry = hit._source + + entry.foreignTerm = hit.fields['foreignEntries.terms']?.[0] + entry.commentActivityIndicator = hit.fields.commentActivityIndicator[0] + + return entry + }) + + return entries +} + +function sortAggregation(aggregation) { + for (const categoryBuckets of Object.values(aggregation)) { + categoryBuckets.sort(bucketCompareFn) + } +} + +function bucketCompareFn(bucketA, bucketB) { + if (bucketA.hits !== bucketB.hits) return 0 + return slCollator.compare(bucketA.name, bucketB.name) +} + +// Simplify search engine's consultancy hits output into useful entries list. +exports.prepareConsultancyEntries = hits => { + const entries = hits.body.hits.hits.map(hit => hit._source) + + return entries +} diff --git a/express/models/helpers/user/index.js b/express/models/helpers/user/index.js new file mode 100644 index 0000000..c0db29e --- /dev/null +++ b/express/models/helpers/user/index.js @@ -0,0 +1,42 @@ +exports.deserialize = { + userById(user) { + const deserializedUser = { + id: user.id, + userName: user.username, + firstName: user.first_name, + lastName: user.last_name, + email: user.email, + hitsPerPage: user.hits_per_page, + userRoles: user.user_roles, + assignedConsultancyEntries: user.assigned_consultancy_entries + } + + return deserializedUser + }, + + user(userData) { + const deserializedData = { + id: userData.id, + userName: userData.username, + firstName: userData.first_name, + lastName: userData.last_name, + email: userData.email, + password: userData.password + } + + return deserializedData + }, + + userRights(userData) { + const deserializedRights = { + id: userData.id, + userName: userData.username, + email: userData.email, + hasAdministration: userData.administration, + hasEditing: userData.editing, + hasTerminologyReview: userData.terminology_review, + hasLanguageReview: userData.language_review + } + return deserializedRights + } +} diff --git a/express/models/inter_instance_sync.js b/express/models/inter_instance_sync.js new file mode 100644 index 0000000..14d9dba --- /dev/null +++ b/express/models/inter_instance_sync.js @@ -0,0 +1,109 @@ +const db = require('./db') +// const debug = require('debug')('termPortal:sync') + +// Fetch all own published dictionaries from DB. +class InterInstanceSync { + static async listDictionaries() { + const indexSql = ` + SELECT + d.id, + d.name_sl, + d.name_sl_short, + d.name_en, + d.author, + d.issn, + dp.name_sl domain_primary_name_sl, + ARRAY( + SELECT jsonb_build_object( + 'name_sl', ds.name_sl, + 'name_en', ds.name_en + ) + FROM dictionary_domain_secondary dds + LEFT JOIN domain_secondary ds ON ds.id = dds.domain_secondary_id + WHERE dds.dictionary_id = d.id + ) domain_secondary_names, + ARRAY( + SELECT l.code + FROM dictionary_language dl + LEFT JOIN language l ON l.id = dl.language_id + WHERE dl.dictionary_id = d.id + ORDER BY dl.selection_order + ) language_codes, + d.time_created, + d.time_modified, + d.time_content_modified, + d.description, + d.entries_have_domain_labels, + d.entries_have_label, + d.entries_have_definition, + d.entries_have_synonyms, + d.entries_have_links, + d.entries_have_other, + d.entries_have_foreign_languages, + d.entries_have_foreign_definitions, + d.entries_have_foreign_synonyms, + d.entries_have_images, + d.entries_have_audio, + d.entries_have_videos, + d.entries_have_terminology_review_flag, + d.entries_have_language_review_flag + FROM dictionary d + LEFT JOIN domain_primary dp ON dp.id = d.domain_primary_id + LEFT JOIN linked_dictionary ld on ld.target_dictionary_id = d.id + WHERE ld.id IS NULL AND d.status = 'published' + ORDER BY id + ` + + const { rows: dictionaryList } = await db.query(indexSql) + return dictionaryList + } + + /** + * Fetch all published (complete) entries for given dictionary that were modified after since date. + * Entries shall include list of translations. + * @param dictionaryId + * @param since + * @returns {Promise<*>} + */ + static async getUpdatedEntriesSince(dictionaryId, since) { + const sqlEntries = + 'SELECT id, term, label, definition, synonym FROM entry' + + " WHERE dictionary_id= $1 AND time_modified > $2 AND status='complete' AND is_published IS TRUE" + const sqlTranslations = + 'SELECT l.code AS language_code, ef.entry_id, ef.term, ef.definition, ef.synonym FROM entry_foreign AS ef' + + ' INNER JOIN language AS l ON l.id = ef.language_id' + + ' WHERE entry_id = ANY($1::int[]) ORDER BY ef.entry_id, l.code' + const { rows: entryList } = await db.query(sqlEntries, [ + dictionaryId, + since + ]) + const entryIds = entryList.map(e => { + return e.id + }) + const { rows: translationList } = await db.query(sqlTranslations, [ + entryIds + ]) + let currentEntryId = 0 + let lastEntryId = 0 + translationList.forEach(t => { + currentEntryId = t.entry_id + const entry = entryList.find(e => { + return e.id === currentEntryId + }) + if (!entry) return + if (lastEntryId === 0) { + entry.translations = [] + lastEntryId = t.entry_id + } else if (currentEntryId !== lastEntryId) { + // new entry translations : save previous + entry.translations = [] + lastEntryId = currentEntryId + currentEntryId = t.entry_id + } + entry.translations.push(t) + }) + return entryList + } +} + +module.exports = InterInstanceSync diff --git a/express/models/portal.js b/express/models/portal.js new file mode 100644 index 0000000..c74714a --- /dev/null +++ b/express/models/portal.js @@ -0,0 +1,486 @@ +const db = require('./db') +const { aggregateSettings, deserialize } = require('./helpers/portal') + +const Portal = {} + +Portal.fetchInstanceSettings = async () => { + const text = ` + SELECT + name, value + FROM + instance_settings + WHERE + name + IN ( + 'portal_name', + 'portal_code', + 'portal_description', + 'is_consultancy_enabled', + 'is_dictionaries_enabled', + 'is_extraction_enabled')` + + const { rows: fetchedSettings } = await db.query(text) + + const aggregatedSettings = aggregateSettings(fetchedSettings) + const deserializedSettings = deserialize.settings(aggregatedSettings) + return deserializedSettings +} + +Portal.updateInstaceSettings = async payload => { + const isExtractionEnabled = payload.isExtractionEnabled ? 'T' : 'F' + const isDictionariesEnabled = payload.isDictionariesEnabled ? 'T' : 'F' + const isConsultancyEnabled = payload.isConsultancyEnabled ? 'T' : 'F' + + const values = [ + payload.portalName, + payload.portalCode, + payload.portalDescription, + isExtractionEnabled, + isDictionariesEnabled, + isConsultancyEnabled + ] + + const text = ` + UPDATE + instance_settings + SET + value + = CASE name + WHEN + 'portal_name' THEN $1 + WHEN + 'portal_code' THEN $2 + WHEN + 'portal_description' THEN $3 + WHEN + 'is_extraction_enabled' THEN $4 + WHEN + 'is_dictionaries_enabled' THEN $5 + WHEN + 'is_consultancy_enabled' THEN $6 + ELSE value + END` + + await db.query(text, values) +} + +Portal.fetchInstanceDictSettings = async () => { + const text = ` + SELECT + name, value + FROM + instance_settings + WHERE + name + IN ( + 'min_entries_per_dictionary', + 'dictionary_publish_approval', + 'num_of_history_entires_per_entry', + 'can_publish_entries_in_edit')` + + const { rows: fetchedSettings } = await db.query(text) + + const aggregatedSettings = aggregateSettings(fetchedSettings) + const deserializedSettings = deserialize.dictSettings(aggregatedSettings) + return deserializedSettings +} + +Portal.updateInstaceDictSettings = async payload => { + const dictionaryPublish = payload.dictionaryPublishApproval ? 'T' : 'F' + const canPublishEntriesInEdit = payload.canPublishEntriesInEdit ? 'T' : 'F' + + const values = [ + payload.minEntriesPerDictionary, + dictionaryPublish, + // payload.keepNumOfExportsPerDict, + // payload.dictionaryAutoSaveFrequency, + payload.numOfHistoryEntriesPerEntry, + canPublishEntriesInEdit + ] + + const text = ` + UPDATE + instance_settings + SET + value + = CASE name + WHEN + 'min_entries_per_dictionary' THEN $1 + WHEN + 'dictionary_publish_approval' THEN $2 + WHEN + 'num_of_history_entires_per_entry' THEN $3 + WHEN + 'can_publish_entries_in_edit' THEN $4 + ELSE value + END` + + await db.query(text, values) +} + +Portal.fetchInstanceConsultancySettings = async () => { + const text = ` + SELECT + name, value + FROM + instance_settings + WHERE + name + IN ( + 'consultancy_type', + 'zrc_email', + 'zrc_url')` + + const { rows: fetchedSettings } = await db.query(text) + + const aggregatedSettings = aggregateSettings(fetchedSettings) + const deserializedSettings = deserialize.consultSettings(aggregatedSettings) + return deserializedSettings +} + +Portal.updateInstaceConsultancySettings = async payload => { + const values = [payload.consultancyType, payload.zrcEmail, payload.zrcURL] + + const text = ` + UPDATE + instance_settings + SET + value + = CASE name + WHEN + 'consultancy_type' THEN $1 + WHEN + 'zrc_email' THEN $2 + WHEN + 'zrc_url' THEN $3 + ELSE value + END` + + await db.query(text, values) +} + +Portal.create = async portal => { + const isEnabled = true + const values = [ + portal.name, + portal.url_update, + portal.url_index, + portal.code, + isEnabled + ] + + const text = ` + INSERT INTO linked_portal ( + name, + url_update, + url_index, + code, + is_enabled + ) + VALUES ($1, $2, $3, $4, $5) + RETURNING id` + + const { rows } = await db.query(text, values) + return rows +} + +Portal.fetchAll = async () => { + const text = ` + SELECT + id, + name, + url_index, + is_enabled, + code, + time_last_synced, + EXISTS (SELECT ld.name + FROM linked_dictionary as ld + WHERE lp.id = ld.linked_portal_id) is_linked + FROM linked_portal as lp + ORDER BY id` + + const { rows: fetchedConnections } = await db.query(text) + + const deserializedConnections = fetchedConnections.map(connection => + deserialize.connections(connection) + ) + return deserializedConnections +} + +Portal.fetchPortal = async portalId => { + const value = [portalId] + const text = ` + SELECT + name, + url_update, + url_index, + code + FROM + linked_portal + WHERE + id = $1` + + const { rows } = await db.query(text, value) + const fetchedPortal = rows[0] + const deserializedPortal = deserialize.connections(fetchedPortal) + return deserializedPortal +} + +Portal.update = async (portalId, payload) => { + const values = [ + payload.name, + payload.code, + payload.url_update, + payload.url_index, + portalId + ] + const text = ` + UPDATE + linked_portal + SET + name = $1, + code = $2, + url_update = $3, + url_index = $4 + WHERE id = $5` + + await db.query(text, values) +} + +Portal.syncRemoteDictionaries = async (linkedPortalId, dictionaries) => { + const text = 'SELECT sync_remote_dictionaries($1, $2)' + const values = [linkedPortalId, dictionaries] + + await db.query(text, values) +} + +Portal.deleteLinkedDictionary = async linkedPortalId => { + const text = `DELETE from linked_portal WHERE id = $1` + const value = [linkedPortalId] + + await db.query(text, value) +} + +Portal.fetchDictionaries = async portalId => { + const value = [portalId] + const text = ` + SELECT + name, + target_dictionary_id + FROM linked_dictionary + WHERE linked_portal_id = $1` + + const { rows: fetchedDictionaries } = await db.query(text, value) + return fetchedDictionaries +} + +Portal.fetchSelectedLinkedDictionaries = async (id, resultsPerPage, page) => { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $2::float) + FROM linked_dictionary + WHERE linked_dictionary.linked_portal_id = $1 + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', linked_dictionary.id, + 'name', linked_dictionary.name, + 'isEnabled', linked_dictionary.is_enabled, + 'code', linked_portal.code + ) + FROM linked_dictionary + LEFT JOIN linked_portal + ON linked_dictionary.linked_portal_id = linked_portal.id + WHERE linked_dictionary.linked_portal_id = $1 + ORDER BY linked_dictionary.id + LIMIT $2 + OFFSET $3 + ) + ) result`, + [id, resultsPerPage, resultsPerPage * (page - 1)] + ) + return result +} + +Portal.updateSelectedDictionaries = async (id, body) => { + const portalId = id + let enableArr = body.isEnabled ? Object.keys(body.isEnabled) : [] + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const setAllToFalse = ` + UPDATE linked_dictionary + SET is_enabled = false + WHERE linked_portal_id = $1` + await dbClient.query(setAllToFalse, [portalId]) + + enableArr = enableArr.map( + linkedDictionaryId => +linkedDictionaryId.replaceAll("'", '') + ) + + const text = ` + UPDATE linked_dictionary + SET is_enabled = true + WHERE id = ANY ($1) + AND linked_portal_id = $2` + const values = [enableArr, portalId] + + await dbClient.query(text, values) + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } +} + +Portal.fetchAllLinkedDictionaries = async (resultsPerPage, page) => { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM linked_dictionary + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', linked_dictionary.id, + 'name', linked_dictionary.name, + 'isEnabled', linked_dictionary.is_enabled, + 'code', linked_portal.code + ) + FROM linked_dictionary + LEFT JOIN linked_portal + ON linked_dictionary.linked_portal_id = linked_portal.id + ORDER BY linked_portal.id + LIMIT $1 + OFFSET $2 + ) + ) result`, + [resultsPerPage, resultsPerPage * (page - 1)] + ) + return result +} + +Portal.updateAllDictionaries = async body => { + const enableArr = Object.keys(body.isEnabled) + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const setAllToFalse = ` + UPDATE linked_dictionary + SET is_enabled = false` + await dbClient.query(setAllToFalse) + + const enableAllDictionary = enableArr.map(async userId => { + userId = +userId.replaceAll("'", '') + + const text = ` + UPDATE linked_dictionary + SET is_enabled = true + WHERE id = $1` + const values = [userId] + + await dbClient.query(text, values) + }) + + await Promise.all(enableAllDictionary) + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } +} + +Portal.updatePortalStatus = async (portalId, isEnabled) => { + const values = [isEnabled, portalId] + + const text = ` + UPDATE linked_portal + SET is_enabled = $1 + WHERE id = $2` + + await db.query(text, values) +} + +Portal.getInstanceSettingValue = async settingName => { + const values = [settingName] + + const text = ` + SELECT value + FROM instance_settings + WHERE name = $1` + + const { rows } = await db.query(text, values) + const settingValue = rows[0].value + + return settingValue +} + +Portal.fetchAllInstanceSettingNames = async () => { + const { rows } = await db.query('SELECT name FROM instance_settings') + const settingNames = rows.map(row => row.name) + + return settingNames +} + +Portal.getSlovenianLanguageId = async () => { + const { rows } = await db.query("SELECT id FROM language WHERE code = 'sl'") + const id = rows[0].id + + return id +} + +Portal.getSearchAggregateNames = async ( + primaryDomainIds, + dictionaryIds, + languageIds +) => { + const text = ` + SELECT jsonb_build_object( + 'primaryDomains', jsonb_object( + ARRAY( + SELECT ARRAY [id, name_sl]::TEXT[] + FROM domain_primary + WHERE id = ANY ($1) + ) + ), + 'dictionaries', jsonb_object( + ARRAY( + SELECT ARRAY [id, name_sl]::TEXT[] + FROM dictionary + WHERE id = ANY ($2) + ) + ), + 'languages', jsonb_object( + ARRAY( + SELECT ARRAY [id, name_sl]::TEXT[] + FROM language + WHERE id = ANY ($3) + ) + ) + ) "names" + ` + const values = [primaryDomainIds, dictionaryIds, languageIds] + + const { + rows: [{ names }] + } = await db.query(text, values) + + return names +} + +module.exports = Portal diff --git a/express/models/search-engine.js b/express/models/search-engine.js new file mode 100644 index 0000000..6738761 --- /dev/null +++ b/express/models/search-engine.js @@ -0,0 +1,244 @@ +const debug = require('debug')('termPortal:models/search-engine') +const { Client } = require('@opensearch-project/opensearch') + +const ENTRY_INDEX = 'entry' +const CONSULTANCY_ENTRY_INDEX = 'consultancy_entry' +const client = new Client({ node: 'http://opensearch:9200' }) + +exports.initEntryIndex = async () => { + const { statusCode } = await client.indices.exists({ index: ENTRY_INDEX }) + + const doesIndexExist = statusCode === 200 + + if (doesIndexExist) { + debug('Entry search index already exists.') + return + } + + await client.indices.create({ + index: ENTRY_INDEX, + body: { + settings: { + number_of_replicas: 0 + }, + mappings: { + dynamic: 'strict', + properties: { + id: { type: 'keyword', index: false, doc_values: false }, + isValid: { type: 'boolean', doc_values: false }, + isPublished: { type: 'boolean', doc_values: false }, + isTerminologyReviewed: { type: 'boolean', doc_values: false }, + isLanguageReviewed: { type: 'boolean', doc_values: false }, + status: { type: 'keyword', doc_values: false }, + term: { + type: 'text', + doc_values: false, + fields: { + keyword: { type: 'keyword', doc_values: false }, + sort: { + type: 'icu_collation_keyword', + index: false, + language: 'sl', + country: 'SI' + } + } + }, + homonymSort: { type: 'keyword', index: false }, + label: { type: 'text', doc_values: false }, + definition: { type: 'text', doc_values: false }, + synonyms: { type: 'text', doc_values: false }, + other: { type: 'text', doc_values: false }, + timeMostRecentComment: { type: 'date' }, + domainLabels: { type: 'text', doc_values: false }, + links: { type: 'text', doc_values: false }, + foreignEntries: { + type: 'nested', + properties: { + lang: { + properties: { + id: { type: 'keyword' }, + code: { type: 'keyword', index: false, doc_values: false }, + nameSl: { type: 'keyword', index: false, doc_values: false }, + nameEn: { type: 'keyword', index: false, doc_values: false } + } + }, + terms: { + type: 'text', + doc_values: false, + fields: { + keyword: { type: 'keyword', doc_values: false } + } + }, + definition: { type: 'text', doc_values: false }, + synonyms: { type: 'text', doc_values: false } + } + }, + primaryDomain: { + properties: { + id: { type: 'keyword' }, + nameSl: { type: 'keyword', index: false, doc_values: false }, + nameEn: { type: 'keyword', index: false, doc_values: false } + } + }, + dictionary: { + properties: { + id: { type: 'keyword' }, + nameSl: { type: 'keyword', index: false, doc_values: false }, + nameSlShort: { type: 'keyword', index: false, doc_values: false }, + nameEn: { type: 'keyword', index: false, doc_values: false }, + status: { type: 'keyword', doc_values: false } + } + }, + source: { + properties: { + code: { type: 'keyword' }, + name: { type: 'keyword', index: false, doc_values: false } + } + } + } + } + } + }) + debug('Entry search index created.') +} + +exports.initConsultancyEntryIndex = async () => { + const { statusCode } = await client.indices.exists({ + index: CONSULTANCY_ENTRY_INDEX + }) + + const doesIndexExist = statusCode === 200 + + if (doesIndexExist) { + debug('Consultancy entry search index already exists.') + return + } + + await client.indices.create({ + index: CONSULTANCY_ENTRY_INDEX, + body: { + settings: { + number_of_replicas: 0 + }, + mappings: { + dynamic: 'strict', + properties: { + id: { type: 'keyword', index: false, doc_values: false }, + timeCreated: { type: 'date', index: false }, + status: { type: 'keyword', doc_values: false }, + description: { type: 'text', index: false, doc_values: false }, + title: { type: 'text', doc_values: false }, + question: { type: 'text', doc_values: false }, + answer: { type: 'text', doc_values: false }, + answerAuthors: { type: 'keyword', index: false, doc_values: false }, + primaryDomain: { + properties: { + id: { type: 'keyword', doc_values: false }, + nameSl: { type: 'keyword', index: false, doc_values: false }, + nameEn: { type: 'keyword', index: false, doc_values: false } + } + }, + assignedConsultants: { + properties: { + id: { type: 'keyword', doc_values: false }, + firstName: { type: 'keyword', index: false, doc_values: false }, + lastName: { type: 'keyword', index: false, doc_values: false }, + isModerator: { type: 'boolean', index: false, doc_values: false } + } + } + } + } + } + }) + debug('Consultancy entry search index created.') +} + +exports.waitForConnection = () => { + return new Promise(resolve => { + async function testConnection() { + try { + // eslint-disable-next-line no-console + console.log('Verifying connection to search engine server') + await client.ping() + // eslint-disable-next-line no-console + console.log('Connection to search engine server verified') + resolve() + } catch { + // eslint-disable-next-line no-console + console.error('Could not connect to search engine server') + setTimeout(testConnection, 1000) + } + } + testConnection() + }) +} + +exports.searchEngineClient = client + +exports.ENTRY_INDEX = ENTRY_INDEX + +exports.CONSULTANCY_ENTRY_INDEX = CONSULTANCY_ENTRY_INDEX + +// A wrapper, to simplify querying the entry index. +exports.searchEntryIndex = async query => { + const hits = await client.search({ + index: ENTRY_INDEX, + filter_path: 'hits,aggregations', + body: query + }) + + return hits +} + +// A wrapper, to simplify querying the consultancy entry index. +exports.searchConsultancyEntryIndex = async query => { + const hits = await client.search({ + index: CONSULTANCY_ENTRY_INDEX, + filter_path: 'hits', + body: query + }) + + return hits +} + +exports.deleteEntryFromIndex = async (entryId, shouldWait) => { + await client.delete({ + index: ENTRY_INDEX, + id: entryId, + refresh: shouldWait ? 'wait_for' : false + }) +} + +exports.deleteConsultancyEntryFromIndex = async (entryId, shouldWait) => { + await client.delete({ + index: CONSULTANCY_ENTRY_INDEX, + id: entryId, + refresh: shouldWait ? 'wait_for' : false + }) +} + +exports.deleteDictionaryEntriesFromIndex = async dictionaryId => { + await client.deleteByQuery({ + index: ENTRY_INDEX, + body: { + query: { + term: { + 'dictionary.id': { + value: dictionaryId + } + } + } + } + }) +} + +exports.deleteConsultancyEntriesFromIndex = async () => { + await client.deleteByQuery({ + index: CONSULTANCY_ENTRY_INDEX, + body: { + query: { + match_all: {} + } + } + }) +} diff --git a/express/models/system/eurotermbank.js b/express/models/system/eurotermbank.js new file mode 100644 index 0000000..db089f8 --- /dev/null +++ b/express/models/system/eurotermbank.js @@ -0,0 +1,183 @@ +const db = require('../../models/db') +const Cursor = require('pg-cursor') +const axios = require('axios').default +const xmlFlow = require('xml-flow') +const { removeHtmlTags } = require('../helpers') + +const Eurotermbank = {} + +// Push all changes to Eurotermbank. +Eurotermbank.push = async () => { + const dbClient = await db.getClient() + + try { + const { rows: dictrionariesToSync } = await dbClient.query( + 'SELECT id, name_sl FROM dictionary ORDER BY id' + ) + + for (const { id, name_sl: name } of dictrionariesToSync) { + // Create/update collection metadata. + await centralSyncApi.put(id.toString(), { + name, + domainid: 2841 + }) + + const text = ` + SELECT + id, + term, + definition, + ARRAY( + SELECT name + FROM entry_domain_label edl + LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id + WHERE entry_id = e.id + ) domain_labels, + ARRAY( + SELECT jsonb_build_object( + 'link', link, + 'type', type) + FROM entry_link + WHERE entry_id = e.id + ) links, + ARRAY( + SELECT jsonb_build_object( + 'lang_code', l.code, + 'terms', ef.term, + 'definition', ef.definition, + 'synonyms', ef.synonym) + FROM entry_foreign ef + LEFT JOIN LANGUAGE l ON l.id = ef.language_id + WHERE entry_id = e.id + ) foreign_entries + FROM entry e + WHERE + e.dictionary_id = $1 + AND is_valid` + const values = [id] + + const cursor = dbClient.query(new Cursor(text, values)) + + let entries = [] + do { + // Keep getting and sending entries in batches of 100. + entries = await cursor.read(100) + + if (entries.length) { + const tbxPayload = generateTbxPayload(entries) + await centralSyncApi.post(`${id}/entries`, tbxPayload, { + headers: { 'content-type': 'application/xml' } + }) + } + } while (entries.length === 100) + } + } finally { + dbClient.release() + } +} + +const centralSyncApi = axios.create({ + baseURL: + 'https://test-fedterm.eurotermbank.com/api/termservice/sync/collection/external/', + auth: { + username: 'SlovenianNTP', + password: '3l063Ni=p0tr4l(t3rm' + } +}) + +function generateTbxPayload(entries) { + // Opening boilerplate. + let tbxPayload = + '

Sync collection sample

https://eurotermbank.com/tbx-0.5.1.xcs

' + + // Entry content TBX. + tbxPayload += entries.reduce( + (payload, entry) => (payload += generateEntryTbx(entry)), + '' + ) + + // Closing boilerplate. + tbxPayload += '
' + + return tbxPayload +} + +function generateEntryTbx(entry) { + const entryObj = { + $name: 'termEntry', + $attrs: { id: entry.id }, + $markup: [ + { + $name: 'langSet', + $attrs: { 'xml:lang': 'sl' }, + $markup: [ + { + $name: 'ntig', + $markup: [ + { + $name: 'termGrp', + $markup: [{ $name: 'term', $text: removeHtmlTags(entry.term) }] + } + ] + } + ] + } + ] + } + + if (entry.definition) { + const definitionObj = { + $name: 'descripGrp', + $markup: [ + { + $name: 'descrip', + $attrs: { type: 'definition' }, + $text: removeHtmlTags(entry.definition) + } + ] + } + + entryObj.$markup[0].$markup.push(definitionObj) + } + + entry.foreign_entries.forEach(fEntry => { + const fEntryObj = { + $name: 'langSet', + $attrs: { 'xml:lang': fEntry.lang_code }, + $markup: [ + { + $name: 'ntig', + $markup: [ + { + $name: 'termGrp', + $markup: [ + { $name: 'term', $text: removeHtmlTags(fEntry.terms[0]) } + ] + } + ] + } + ] + } + + if (fEntry.definition) { + const fDefinitionObj = { + $name: 'descripGrp', + $markup: [ + { + $name: 'descrip', + $attrs: { type: 'definition' }, + $text: removeHtmlTags(fEntry.definition) + } + ] + } + + fEntryObj.$markup.push(fDefinitionObj) + } + + entryObj.$markup.push(fEntryObj) + }) + + return xmlFlow.toXml(entryObj) +} + +module.exports = Eurotermbank diff --git a/express/models/user.js b/express/models/user.js new file mode 100644 index 0000000..d81ba03 --- /dev/null +++ b/express/models/user.js @@ -0,0 +1,470 @@ +const db = require('./db') +const bcrypt = require('bcrypt') +const uid = require('uid-safe') +const { deserialize } = require('./helpers/user') + +const User = {} + +// Create new user in DB. +User.create = async user => { + const SALT_ROUNDS = 12 + const bcryptHash = await bcrypt.hash(user.password, SALT_ROUNDS) + + const values = [ + user.username || null, + user.firstName || null, + user.lastName || null, + user.email || null, + bcryptHash || null + ] + + const text = `INSERT INTO "user" ( + username, + first_name, + last_name, + email, + bcrypt_hash + ) + VALUES (${db.genParamStr(values)}) + RETURNING id` + + const { rows } = await db.query(text, values) + + const userId = rows[0].id + + return userId +} + +// Save an activation token for a single user in DB. +User.saveActivationToken = async (userId, activationToken) => { + await db.query( + 'INSERT INTO user_token_activation (token, user_id) VALUES ($1, $2)', + [activationToken, userId] + ) +} + +// Fetch user from DB by (valid) activation token. +User.fetchByActivationToken = async activationToken => { + const TOKEN_VALID_PERIOD = '1 week' + const text = ` + SELECT u.id + FROM user_token_activation t + INNER JOIN "user" u ON u.id = t.user_id + WHERE + t.token = $1 + AND AGE(NOW(), t.time_created) < INTERVAL '${TOKEN_VALID_PERIOD}' + ` + const values = [activationToken] + + const { rows } = await db.query(text, values) + const user = rows[0] + + // TODO Perhaps suggest to the user to request another one and make a shortcut. + if (!user) throw Error('Povezava je neveljavna ali pa je že potekla') + + return user +} + +// Activate user account. +User.activateAccount = async user => { + await db.query(`UPDATE "user" SET status = 'active' WHERE id = $1`, [user.id]) +} + +// Generate a user remember me token. +User.generateRememberMeToken = async () => { + const token = await uid(32) + return token +} + +// Save a remember me token for a single user in DB. +User.saveRememberMeToken = async (user, rememberMeToken) => { + await db.query( + 'INSERT INTO user_token_remember_me (token, user_id) VALUES ($1, $2)', + [rememberMeToken, user.id] + ) +} + +// Remove a specific remember me token from DB. +User.clearRememberMeToken = async rememberMeToken => { + await db.query('DELETE FROM user_token_remember_me WHERE token = $1', [ + rememberMeToken + ]) +} + +// Fetch user data that should be available on every request from DB by id. +User.fetchDeserializedDataById = async userId => { + const text = ` + SELECT + u.id, + u.username, + u.first_name, + u.last_name, + u.email, + u.hits_per_page, + ARRAY( + SELECT jsonb_build_object( + 'roleName', r.role_name, + 'dictionaryId', r.dictionary_id, + 'administration', r.administration, + 'terminologyReview', r.terminology_review, + 'languageReview', r.language_review, + 'editing', r.editing) + FROM user_role r + WHERE r.user_id = u.id + ) user_roles, + ARRAY( + SELECT jsonb_build_object( + 'id', cr.entry_id, + 'isModerator', cr.is_moderator) + FROM consultancy_entry_consultant cr + WHERE cr.user_id = u.id + ) assigned_consultancy_entries + FROM "user" u + WHERE + u.id = $1` + const values = [userId] + + const { + rows: [user] + } = await db.query(text, values) + + const deserializedUser = deserialize.userById(user) + return deserializedUser +} + +// Fetch all registered users on the portal +User.fetchAll = async (resultsPerPage, page) => { + const { + rows: [{ result }] + } = await db.query( + ` + SELECT jsonb_build_object( + 'pages_total', ( + SELECT CEIL(COUNT(*) / $1::float) + FROM "user" + ), + 'results', ARRAY( + SELECT jsonb_build_object( + 'id', id, + 'userName', username, + 'email', email, + 'status', status + ) + FROM "user" + ORDER BY username + LIMIT $1 + OFFSET $2 + ) + ) result + `, + [resultsPerPage, resultsPerPage * (page - 1)] + ) + + return result +} + +// Fetch all users with at least one portal role along with all their portal roles. +User.fetchAllWithPortalRoles = async () => { + const text = ` + SELECT u.id, + u.username, + u.email, + jsonb_build_object( + 'isPortalAdmin', 'portal admin' = ANY (r.roles_array), + 'isDictionariesAdmin', 'dictionaries admin' = ANY (r.roles_array), + 'isConsultancyAdmin', 'consultancy admin' = ANY (r.roles_array) + ) roles + FROM ( + SELECT user_id, array_agg(role_name) roles_array + FROM user_role + WHERE role_name IN ('portal admin', 'dictionaries admin', 'consultancy admin') + GROUP BY user_id + ) r + LEFT JOIN "user" u ON u.id = r.user_id + ORDER BY u.id +` + const { rows: users } = await db.query(text) + return users +} + +// Find searched user with specific username or email +User.findByUsernameOrEmail = async userNameEmail => { + const text = ` + SELECT + id, + username, + email + FROM "user" + WHERE username=$1 + OR email=$1` + const value = [userNameEmail] + + const { rows: user } = await db.query(text, value) + return user +} + +// Delete relevant portal roles and set new ones. +User.updatePortalRoles = async rolesPerUser => { + const rolesPerUserArr = Object.entries(rolesPerUser) + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const removeAllPortalRolesQuery = ` + DELETE FROM user_role + WHERE role_name IN ('portal admin', 'dictionaries admin', 'consultancy admin')` + await dbClient.query(removeAllPortalRolesQuery) + + const updateRoles = rolesPerUserArr.map(async ([userId, roles]) => { + userId = +userId.replaceAll("'", '') + const rolesArr = [] + if (roles.isPortalAdmin) rolesArr.push('portal admin') + if (roles.isDictionariesAdmin) rolesArr.push('dictionaries admin') + if (roles.isConsultancyAdmin) { + rolesArr.push('consultancy admin') + rolesArr.push('consultant') + } + + const updateRolesPerUser = rolesArr.map(async roleName => { + const text = ` + INSERT INTO user_role (user_id, role_name) + VALUES ($1, $2)` + const values = [userId, roleName] + + await dbClient.query(text, values) + }) + + await Promise.all(updateRolesPerUser) + }) + + await Promise.all(updateRoles) + + const countAdminsQuery = ` + SELECT COUNT(*) portal_admins_count + FROM user_role + WHERE role_name = 'portal admin'` + const { rows } = await dbClient.query(countAdminsQuery) + const portalAdminsCount = +rows[0].portal_admins_count + if (!portalAdminsCount) throw Error('Can not delete all portal admins') + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } +} + +User.fetchUser = async userId => { + const text = ` + SELECT id, username, first_name, last_name, email + FROM "user" + WHERE id=$1` + const value = [userId] + + const { rows } = await db.query(text, value) + const fetchedUser = rows[0] + + const deserializedUserData = deserialize.user(fetchedUser) + return deserializedUserData +} + +User.updateUser = async (userId, payload) => { + const text = ` + UPDATE "user" + SET + username = $2, + first_name = $3, + last_name = $4 + WHERE id = $1` + + const values = [userId, payload.username, payload.firstName, payload.lastName] + + await db.query(text, values) +} + +User.fetchUserRoles = async userId => { + const text = ` + SELECT + jsonb_build_object( + 'isPortalAdmin', 'portal admin' = ANY (r.roles_array), + 'isDictionariesAdmin', 'dictionaries admin' = ANY (r.roles_array), + 'isConsultancyAdmin', 'consultancy admin' = ANY (r.roles_array), + 'isConsultant', 'consultant' = ANY (r.roles_array), + 'isEditor', 'editor' = ANY (r.roles_array) + ) roles + FROM ( + SELECT user_id, array_agg(role_name) roles_array + FROM user_role + WHERE role_name IN ('portal admin', 'dictionaries admin', 'consultancy admin', 'consultant', 'editor') + GROUP BY user_id + ) r + LEFT JOIN "user" u ON u.id = r.user_id + WHERE u.id=$1` + const value = [userId] + + const { rows } = await db.query(text, value) + const fetchedUser = rows[0] + + return fetchedUser +} + +User.fetchAllWithDictionaryRights = async dictionaryId => { + const text = ` + SELECT u.username,u.email, u.id, r.administration, r.editing, r.terminology_review, r.language_review + FROM user_role r + INNER JOIN "user" u ON u.id = r.user_id + WHERE dictionary_id = $1 + ORDER BY u.username` + + const value = [dictionaryId] + const { rows: fetchedUserRights } = await db.query(text, value) + + const deserializedRights = fetchedUserRights.map(user => + deserialize.userRights(user) + ) + return deserializedRights +} + +User.updateUserRights = async (dictionaryId, rightsPerUser) => { + const rightsPerUserArr = Object.entries(rightsPerUser) + const dbClient = await db.getClient() + try { + await dbClient.query('BEGIN') + + const value = [dictionaryId] + const text = ` + DELETE FROM user_role + WHERE dictionary_id = $1` + await dbClient.query(text, value) + + const roleName = 'editor' + const updateRights = rightsPerUserArr.map(async ([userId, roles]) => { + userId = +userId.replaceAll("'", '') + const values = [ + userId, + roleName, + dictionaryId, + !!roles.isAdministration, + !!roles.isEditing, + !!roles.isTerminologyReview, + !!roles.isLanguageReview + ] + + const text = ` + INSERT INTO user_role (user_id, role_name, dictionary_id, administration, editing, terminology_review, language_review) + VALUES ($1, $2, $3, $4, $5, $6, $7)` + await dbClient.query(text, values) + }) + + await Promise.all(updateRights) + + const textCount = ` + SELECT COUNT(*) dictionary_admins_count + FROM user_role + WHERE administration = true + AND dictionary_id = $1` + const { rows } = await dbClient.query(textCount, value) + const portalAdminsCount = +rows[0].dictionary_admins_count + if (!portalAdminsCount) throw Error('Can not delete all dictionary admins') + + await dbClient.query('COMMIT') + } catch (error) { + await dbClient.query('ROLLBACK') + throw error + } finally { + dbClient.release() + } +} + +User.deleteUserDictionary = async dictionaryId => { + const text = 'DELETE FROM user_role WHERE dictionary_id = $1' + const value = [dictionaryId] + + await db.query(text, value) +} + +// Fetch user with role consultant or consultancy admin +User.fetchConsultants = async () => { + // fetch domains string for the user + const text = ` + SELECT DISTINCT u.id, u.username, u.first_name, u.last_name, ur.domains + FROM user_role ur + INNER JOIN "user" u ON u.id = ur.user_id + ORDER BY u.id ASC + ` + + const { rows } = await db.query(text) + const users = rows + + return users +} + +// Insert consultancy role domains +User.updateConsultancyDomains = async (id, value) => { + await db.query('UPDATE user_role SET domains=$1 WHERE user_id = $2', [ + value, + id + ]) +} + +// Insert new consultant role with domain of +User.insertNewConsultantWithDomain = async (userId, domains) => { + const { rows } = await db.query( + "SELECT user_id FROM user_role WHERE user_id = $1 and role_name = 'consultant'", + [userId] + ) + + if (rows.length) return + + await db.query( + "INSERT INTO user_role (user_id, domains, role_name) VALUES ($1, $2, 'consultant')", + [userId, domains] + ) +} + +// Insert new consultant role with domain of +User.insertNewConsultantWithDomainByUsername = async (username, domains) => { + const { rows } = await db.query( + 'SELECT id FROM "user" WHERE username = $1 or email = $1', + [username] + ) + + await User.insertNewConsultantWithDomain(rows[0].id, domains) +} + +// Remove consultant role +User.removeConsultant = async userId => { + await db.query( + `DELETE FROM user_role + WHERE user_id=$1 and role_name='consultant'`, + [userId] + ) +} + +User.fetchAllowedHitsPerPage = async () => { + return ( + await db.query(`SELECT unnest(enum_range(NULL::user_hits_per_page))`) + ).rows.map(e => e.unnest) +} + +User.updateFirstNameAndLastName = async (username, firstName, lastName) => { + return await db.query( + `UPDATE "user" + SET first_name=$2, last_name=$3 + WHERE username=$1;`, + [username, firstName, lastName] + ) +} + +User.updateHitsPerPage = async (username, hitsPerPageAmount) => { + return await db.query( + `UPDATE "user" + SET hits_per_page=$2::user_hits_per_page + WHERE username=$1;`, + [username, hitsPerPageAmount] + ) +} + +module.exports = User diff --git a/express/package-lock.json b/express/package-lock.json new file mode 100644 index 0000000..67dc4ce --- /dev/null +++ b/express/package-lock.json @@ -0,0 +1,6681 @@ +{ + "name": "terminoloski-portal", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "terminoloski-portal", + "version": "0.0.0", + "dependencies": { + "@opensearch-project/opensearch": "^2.1.0", + "async": "^3.2.3", + "axios": "^0.26.1", + "bcrypt": "^5.0.1", + "connect-redis": "^6.0.0", + "cookie-parser": "^1.4.5", + "debug": "^4.3.2", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", + "express-session": "^1.17.2", + "filesize": "^10.0.5", + "form-data": "^4.0.0", + "helmet": "^5.0.2", + "http-errors": "^2.0.0", + "ioredis": "^4.27.8", + "morgan": "^1.10.0", + "multer": "^1.4.3", + "needle": "^3.0.0", + "nodemailer": "^6.7.2", + "nodemailer-html-to-text": "^3.2.0", + "passport": "^0.5.1", + "passport-local": "^1.0.0", + "passport-remember-me-extended": "^0.0.3", + "pg": "^8.6.0", + "pg-cursor": "^2.7.1", + "pug": "^3.0.2", + "serve-favicon": "^2.5.0", + "uid-safe": "^2.1.5", + "validator": "^13.7.0", + "xml-flow": "^1.0.4", + "xss": "^1.0.10" + }, + "devDependencies": { + "express-debug": "^1.1.1", + "nodemon": "^2.0.12" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", + "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "dependencies": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.5", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@opensearch-project/opensearch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-2.1.0.tgz", + "integrity": "sha512-iM2u63j2IlUOuMSbcw1TZFpRqjK6qMwVhb3jLLa/x4aATxdKOiO1i17mgzfkeepqj85efNzXBZzN+jkq1/EXhQ==", + "dependencies": { + "aws4": "^1.11.0", + "debug": "^4.3.1", + "hpagent": "^0.1.1", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0" + }, + "engines": { + "node": ">=10", + "yarn": "^1.22.10" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/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==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/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==" + }, + "node_modules/bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "dependencies": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/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==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/character-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.0.2.tgz", + "integrity": "sha1-VThNavz4xrndSD6DR2RqeQ5FRec=", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", + "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/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==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true, + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/concat-stream/node_modules/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==", + "dependencies": { + "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" + } + }, + "node_modules/concat-stream/node_modules/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==" + }, + "node_modules/concat-stream/node_modules/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==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/connect-redis": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-6.1.3.tgz", + "integrity": "sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/connectr": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/connectr/-/connectr-0.0.6.tgz", + "integrity": "sha1-dwLIXh+SgF7lyIJ7lfch5tqszlY=", + "dev": true, + "dependencies": { + "debug": "~0.7.2" + } + }, + "node_modules/connectr/node_modules/debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/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=" + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "dependencies": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/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==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "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.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-debug": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/express-debug/-/express-debug-1.1.1.tgz", + "integrity": "sha1-jqvjeLPZa3QXLI8t+BfTQhYQV7Y=", + "dev": true, + "dependencies": { + "connectr": "0.0.6", + "jade": "0.29.0", + "xtend": "2.0.3" + }, + "peerDependencies": { + "express": ">= 3.0.0 < 5" + } + }, + "node_modules/express-promise-router": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.1.tgz", + "integrity": "sha512-Lkvcy/ZGrBhzkl3y7uYBHLMtLI4D6XQ2kiFg9dq7fbktBch5gjqJ0+KovX0cvCAvTJw92raWunRLM/OM+5l4fA==", + "dependencies": { + "is-promise": "^4.0.0", + "lodash.flattendeep": "^4.0.0", + "methods": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/express": "^4.0.0", + "express": "^4.0.0" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/express-session": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-session/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express-session/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/express/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/filesize": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.5.tgz", + "integrity": "sha512-qrzyt8gLh86nsyYiC3ibI5KyIYRCWg2yqIklYrWF4a0qNfekik4OQfn7AoPJG2hRrPMSlH6fET4VEITweZAzjA==", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/helmet": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz", + "integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hpagent": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", + "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==" + }, + "node_modules/html-to-text": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-7.1.1.tgz", + "integrity": "sha512-c9QWysrfnRZevVpS8MlE7PyOdSuIOjg8Bt8ZE10jMU/BEngA6j3llj4GRfAmtQzcd1FjKE0sWu5IHXRUH9YxIQ==", + "dependencies": { + "deepmerge": "^4.2.2", + "he": "^1.2.0", + "htmlparser2": "^6.1.0", + "minimist": "^1.2.5" + }, + "bin": { + "html-to-text": "bin/cli.js" + }, + "engines": { + "node": ">=10.23.2" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "dependencies": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/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==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/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, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/jade": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.29.0.tgz", + "integrity": "sha1-jEvRFlY0ysOTaMkt+cCquD5XZIo=", + "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", + "dev": true, + "dependencies": { + "character-parser": "~1.0.0", + "commander": "0.6.1", + "mkdirp": "0.3.x", + "monocle": "~0.1.43", + "transformers": "~1.8.0" + }, + "bin": { + "jade": "bin/jade" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/jstransformer/node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true + }, + "node_modules/monocle": { + "version": "0.1.50", + "resolved": "https://registry.npmjs.org/monocle/-/monocle-0.1.50.tgz", + "integrity": "sha1-mny9DMwQ3pX9eKBLm+skgq5JQLc=", + "dev": true, + "dependencies": { + "readdirp": "~0.2.3" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multer": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", + "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/multer/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/multer/node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/needle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.0.0.tgz", + "integrity": "sha512-eGr0qnfHxAjr+Eptl1zr2lgUQUPC1SZfTkg2kFi0kxr1ChJonHUVYobkug8siBKMlyUVVp56MSkp6CSeXH/jgw==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/nodemailer": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", + "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nodemailer-html-to-text": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz", + "integrity": "sha512-RJUC6640QV1PzTHHapOrc6IzrAJUZtk2BdVdINZ9VTLm+mcQNyBO9LYyhrnufkzqiD9l8hPLJ97rSyK4WanPNg==", + "dependencies": { + "html-to-text": "7.1.1" + }, + "engines": { + "node": ">= 10.23.0" + } + }, + "node_modules/nodemon": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/passport": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", + "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "dependencies": { + "passport-strategy": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-remember-me-extended": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/passport-remember-me-extended/-/passport-remember-me-extended-0.0.3.tgz", + "integrity": "sha1-6hp2IJQZ7T4qH8GEnf5NFkEonDQ=", + "dependencies": { + "passport": "0.3.x", + "pkginfo": "0.2.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-remember-me-extended/node_modules/passport": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz", + "integrity": "sha1-ndAJ+RXo/glbASSgG4+C2gdRAQI=", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/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=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==" + }, + "node_modules/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=" + }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "node_modules/pg": { + "version": "8.7.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", + "integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.1", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=2.0.0" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-cursor": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.7.3.tgz", + "integrity": "sha512-vmjXRMD4jZK/oHaaYk6clTypgHNlzCCAqyLCO5d/UeI42egJVE5H4ZfZWACub3jzkHUXXyvibH207zAJg9iBOw==", + "peerDependencies": { + "pg": "^8" + } + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", + "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkginfo": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz", + "integrity": "sha1-cjnEKl72wwuPMoQ52bn/cQQkkPg=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval/node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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==" + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/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==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dependencies": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-lexer/node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "node_modules/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, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-0.2.5.tgz", + "integrity": "sha1-xMJ25Sl3riXbUZH+UdAIVQ8V2bs=", + "dev": true, + "dependencies": { + "minimatch": ">=0.2.4" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/redis-commands": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/secure-json-parse": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dependencies": { + "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.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", + "dependencies": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-favicon/node_modules/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==" + }, + "node_modules/serve-favicon/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "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" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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=", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/transformers": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/transformers/-/transformers-1.8.3.tgz", + "integrity": "sha1-gWZgvhMj+IBZKB4enibvLSZo7kU=", + "deprecated": "Deprecated, use jstransformer", + "dev": true, + "dependencies": { + "promise": "~2.0" + } + }, + "node_modules/transformers/node_modules/is-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", + "dev": true + }, + "node_modules/transformers/node_modules/promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz", + "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=", + "dev": true, + "dependencies": { + "is-promise": "~1" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/xml-flow": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/xml-flow/-/xml-flow-1.0.4.tgz", + "integrity": "sha512-r19LXKPL7vkVGL6oWHlESoBgwUVom5w/w8opuS53qULh8+K2w+K9K72edTIQa+X/Vxx1R7ugnCabHFSZ1Tv2zA==", + "dependencies": { + "sax": "^1.2.4" + } + }, + "node_modules/xss": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.11.tgz", + "integrity": "sha512-EimjrjThZeK2MO7WKR9mN5ZC1CSqivSl55wvUK5EtU6acf0rzEE1pN+9ZDrFXJ82BRp3JL38pPE6S4o/rpp1zQ==", + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/xss/node_modules/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==" + }, + "node_modules/xtend": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.0.3.tgz", + "integrity": "sha1-YmAJAPCWrWoRHjyjfbuQh3ZJMJQ=", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" + }, + "@babel/parser": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==" + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@mapbox/node-pre-gyp": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", + "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "requires": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.5", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + } + }, + "@opensearch-project/opensearch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-2.1.0.tgz", + "integrity": "sha512-iM2u63j2IlUOuMSbcw1TZFpRqjK6qMwVhb3jLLa/x4aATxdKOiO1i17mgzfkeepqj85efNzXBZzN+jkq1/EXhQ==", + "requires": { + "aws4": "^1.11.0", + "debug": "^4.3.1", + "hpagent": "^0.1.1", + "ms": "^2.1.3", + "secure-json-parse": "^2.4.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "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.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "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" + } + }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "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==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.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" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "requires": { + "@babel/types": "^7.9.6" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "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==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "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==" + } + } + }, + "bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + } + }, + "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 + }, + "body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "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.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "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" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "character-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.0.2.tgz", + "integrity": "sha1-VThNavz4xrndSD6DR2RqeQ5FRec=", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + } + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "cluster-key-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", + "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==" + }, + "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": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "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==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "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" + } + }, + "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==" + }, + "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" + } + } + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "connect-redis": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-6.1.3.tgz", + "integrity": "sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw==" + }, + "connectr": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/connectr/-/connectr-0.0.6.tgz", + "integrity": "sha1-dwLIXh+SgF7lyIJ7lfch5tqszlY=", + "dev": true, + "requires": { + "debug": "~0.7.2" + }, + "dependencies": { + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "dev": true + } + } + }, + "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=" + }, + "constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "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==" + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + } + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + } + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "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==" + }, + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "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.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "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=" + } + } + }, + "express-debug": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/express-debug/-/express-debug-1.1.1.tgz", + "integrity": "sha1-jqvjeLPZa3QXLI8t+BfTQhYQV7Y=", + "dev": true, + "requires": { + "connectr": "0.0.6", + "jade": "0.29.0", + "xtend": "2.0.3" + } + }, + "express-promise-router": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/express-promise-router/-/express-promise-router-4.1.1.tgz", + "integrity": "sha512-Lkvcy/ZGrBhzkl3y7uYBHLMtLI4D6XQ2kiFg9dq7fbktBch5gjqJ0+KovX0cvCAvTJw92raWunRLM/OM+5l4fA==", + "requires": { + "is-promise": "^4.0.0", + "lodash.flattendeep": "^4.0.0", + "methods": "^1.0.0" + } + }, + "express-session": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "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" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "filesize": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.5.tgz", + "integrity": "sha512-qrzyt8gLh86nsyYiC3ibI5KyIYRCWg2yqIklYrWF4a0qNfekik4OQfn7AoPJG2hRrPMSlH6fET4VEITweZAzjA==" + }, + "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, + "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=" + } + } + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "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==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "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.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==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, + "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-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "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==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "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-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "helmet": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz", + "integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg==" + }, + "hpagent": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-0.1.2.tgz", + "integrity": "sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ==" + }, + "html-to-text": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-7.1.1.tgz", + "integrity": "sha512-c9QWysrfnRZevVpS8MlE7PyOdSuIOjg8Bt8ZE10jMU/BEngA6j3llj4GRfAmtQzcd1FjKE0sWu5IHXRUH9YxIQ==", + "requires": { + "deepmerge": "^4.2.2", + "he": "^1.2.0", + "htmlparser2": "^6.1.0", + "minimist": "^1.2.5" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + } + } + }, + "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" + } + }, + "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" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "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.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "ioredis": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.28.5.tgz", + "integrity": "sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==", + "requires": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-commands": "1.7.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + } + }, + "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-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, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "requires": { + "has": "^1.0.3" + } + }, + "is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "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==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, + "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 + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^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=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "jade": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.29.0.tgz", + "integrity": "sha1-jEvRFlY0ysOTaMkt+cCquD5XZIo=", + "dev": true, + "requires": { + "character-parser": "~1.0.0", + "commander": "0.6.1", + "mkdirp": "0.3.x", + "monocle": "~0.1.43", + "transformers": "~1.8.0" + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + }, + "dependencies": { + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + } + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "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" + } + }, + "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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "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.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "requires": { + "yallist": "^4.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" + } + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + }, + "monocle": { + "version": "0.1.50", + "resolved": "https://registry.npmjs.org/monocle/-/monocle-0.1.50.tgz", + "integrity": "sha1-mny9DMwQ3pX9eKBLm+skgq5JQLc=", + "dev": true, + "requires": { + "readdirp": "~0.2.3" + } + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.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" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "multer": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", + "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } + }, + "needle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.0.0.tgz", + "integrity": "sha512-eGr0qnfHxAjr+Eptl1zr2lgUQUPC1SZfTkg2kFi0kxr1ChJonHUVYobkug8siBKMlyUVVp56MSkp6CSeXH/jgw==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "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" + } + } + } + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nodemailer": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", + "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==" + }, + "nodemailer-html-to-text": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz", + "integrity": "sha512-RJUC6640QV1PzTHHapOrc6IzrAJUZtk2BdVdINZ9VTLm+mcQNyBO9LYyhrnufkzqiD9l8hPLJ97rSyK4WanPNg==", + "requires": { + "html-to-text": "7.1.1" + } + }, + "nodemon": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "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 + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "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" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "passport": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", + "integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.x.x" + } + }, + "passport-remember-me-extended": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/passport-remember-me-extended/-/passport-remember-me-extended-0.0.3.tgz", + "integrity": "sha1-6hp2IJQZ7T4qH8GEnf5NFkEonDQ=", + "requires": { + "passport": "0.3.x", + "pkginfo": "0.2.x" + }, + "dependencies": { + "passport": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz", + "integrity": "sha1-ndAJ+RXo/glbASSgG4+C2gdRAQI=", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + } + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, + "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-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=" + }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "pg": { + "version": "8.7.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", + "integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.5.1", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "pg-cursor": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.7.3.tgz", + "integrity": "sha512-vmjXRMD4jZK/oHaaYk6clTypgHNlzCCAqyLCO5d/UeI42egJVE5H4ZfZWACub3jzkHUXXyvibH207zAJg9iBOw==", + "requires": {} + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", + "integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", + "requires": {} + }, + "pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "requires": { + "split2": "^4.1.0" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkginfo": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz", + "integrity": "sha1-cjnEKl72wwuPMoQ52bn/cQQkkPg=" + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + }, + "dependencies": { + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "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" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "requires": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + }, + "dependencies": { + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + } + } + }, + "pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "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" + } + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, + "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.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-0.2.5.tgz", + "integrity": "sha1-xMJ25Sl3riXbUZH+UdAIVQ8V2bs=", + "dev": true, + "requires": { + "minimatch": ">=0.2.4" + } + }, + "redis-commands": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", + "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "requires": { + "redis-errors": "^1.0.0" + } + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "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" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "secure-json-parse": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" + }, + "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" + } + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "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.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "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=" + } + } + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + } + } + }, + "serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", + "requires": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "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==" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, + "serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==" + }, + "standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.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": "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" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "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" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + } + } + }, + "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-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "transformers": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/transformers/-/transformers-1.8.3.tgz", + "integrity": "sha1-gWZgvhMj+IBZKB4enibvLSZo7kU=", + "dev": true, + "requires": { + "promise": "~2.0" + }, + "dependencies": { + "is-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=", + "dev": true + }, + "promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz", + "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=", + "dev": true, + "requires": { + "is-promise": "~1" + } + } + } + }, + "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==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "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==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.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==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "xml-flow": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/xml-flow/-/xml-flow-1.0.4.tgz", + "integrity": "sha512-r19LXKPL7vkVGL6oWHlESoBgwUVom5w/w8opuS53qULh8+K2w+K9K72edTIQa+X/Vxx1R7ugnCabHFSZ1Tv2zA==", + "requires": { + "sax": "^1.2.4" + } + }, + "xss": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.11.tgz", + "integrity": "sha512-EimjrjThZeK2MO7WKR9mN5ZC1CSqivSl55wvUK5EtU6acf0rzEE1pN+9ZDrFXJ82BRp3JL38pPE6S4o/rpp1zQ==", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "xtend": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.0.3.tgz", + "integrity": "sha1-YmAJAPCWrWoRHjyjfbuQh3ZJMJQ=", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/express/package.json b/express/package.json new file mode 100644 index 0000000..bcddb87 --- /dev/null +++ b/express/package.json @@ -0,0 +1,47 @@ +{ + "name": "terminoloski-portal", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www", + "devstart": "nodemon --ignore data_files/ --inspect=0.0.0.0:9229 ./bin/www", + "devstart-wait": "nodemon --ignore data_files/ --inspect-brk=0.0.0.0:9229 ./bin/www" + }, + "dependencies": { + "@opensearch-project/opensearch": "^2.1.0", + "async": "^3.2.3", + "axios": "^0.26.1", + "bcrypt": "^5.0.1", + "connect-redis": "^6.0.0", + "cookie-parser": "^1.4.5", + "debug": "^4.3.2", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", + "express-session": "^1.17.2", + "filesize": "^10.0.5", + "form-data": "^4.0.0", + "helmet": "^5.0.2", + "http-errors": "^2.0.0", + "ioredis": "^4.27.8", + "morgan": "^1.10.0", + "multer": "^1.4.3", + "needle": "^3.0.0", + "nodemailer": "^6.7.2", + "nodemailer-html-to-text": "^3.2.0", + "passport": "^0.5.1", + "passport-local": "^1.0.0", + "passport-remember-me-extended": "^0.0.3", + "pg": "^8.6.0", + "pg-cursor": "^2.7.1", + "pug": "^3.0.2", + "serve-favicon": "^2.5.0", + "uid-safe": "^2.1.5", + "validator": "^13.7.0", + "xml-flow": "^1.0.4", + "xss": "^1.0.10" + }, + "devDependencies": { + "express-debug": "^1.1.1", + "nodemon": "^2.0.12" + } +} diff --git a/express/public/documents/Podrocja_TP_2022-11-28.pdf b/express/public/documents/Podrocja_TP_2022-11-28.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3a20f29a85738ec84e30e844670e4d58f3720937 GIT binary patch literal 154943 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

qW)CBh^w0lyzl0F`!24V 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�!-TUN5+17W)izMP(&ZGW0!$!c%z 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�Ep>(6n2_%e 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

5X|W*y^|Rv~O;7+v=2~hmezLOt}3ugbCl+ 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

}jhSG)tY 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 literal 0 HcmV?d00001 diff --git a/express/public/images/Component.svg b/express/public/images/Component.svg new file mode 100644 index 0000000..25a19b6 --- /dev/null +++ b/express/public/images/Component.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/EKP.svg b/express/public/images/EKP.svg new file mode 100644 index 0000000..7745c66 --- /dev/null +++ b/express/public/images/EKP.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/express/public/images/Ekran.png b/express/public/images/Ekran.png new file mode 100644 index 0000000000000000000000000000000000000000..94eb7ee57f5ab5e4aabe12ff44c1f1b92a93d127 GIT binary patch literal 86655 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 E0M>tZPyhe` literal 0 HcmV?d00001 diff --git a/express/public/images/Filtri.png b/express/public/images/Filtri.png new file mode 100644 index 0000000000000000000000000000000000000000..ea53506ff8a9d0be7b69e4fd5dc1b0fabba4ca46 GIT binary patch literal 30136 zcmc$lbyQnXyXHfM7AR0G6bhxdHMkTgP$alJ!J)VncPMSqV8PwpB}mXx2=4B*6nA%- z^!x6*^WFJlX4b5G@2quz3)CMpClyIiK=}~a7V6Cta}jwF0H7)o>(=Ng>OID1DQzbJ0N?rV589F$ zg*yP?A}=j2qUNr@*CMN=rrmll{A;P*Z_K=BLL2!Y;r!lt;Ci;%=QJ{36RG607??1=2LCkmzHd95 ziLAXCdM2GucX-!{Np<11*D`gzd)7x|s&Aq|UC3T?G}p--m%zkH>5fM*j0X6X6LTC$ zJ^4x_;=5W-;6FC(qOL-i$`imBMgIvZ$`%U_YRbtTnANHjtCbXMu@qyV1mqypDxpkc!LX>~$AB-Ns7xIkls#e8 zdYj)*voVS!h>E%@rC1*UJ|4Hj8KU%8rSJkj%8Y*JGJc+mg$6L>G_+8D+tLFAzJQ)) zV_SB*P*I~UMn*(zJsBeydkc(R^g~LDT0)fRZx`^3!2Yq>fw9>bTWu~>F3$mg6#rP- zh|}yq)E1i^>a4E|gFQkGM9@U`M;T=?8D%hPgP=OYBg}ZP)DojI5v9UK8Ezpa!_IX~ z1prif7(xi87?Yz^)L;@X{3m{QMJb~?q3E9l_UFnD<;uq1`Y9zfj|TW*_SQ6sI?qCs zbTp95*diB8nB~|G05I&30%7LjspsOPMNx&}FtPyvQg(!(Z7J%xDE_eTgp{aZ6jfPr z%EhsjA`kos`7GGej~a?Ar#&MbZ9AtO3`muaoL#wusI*pj% zc!4JqS@sP6yzUKUt%by#T}QLFR$=SRM}MInbyC!Xc>T)r(8u;JN%$`5c=>_PKtsbN zYthHc&R4%njam-9<L8GeJ#lxnb5wm~(XG zbUfo;MUe9(dS!fE_%eZlW$fO00x=evzn)>x;tRSM&lI%u&Mc4&8c9A1@e3wDB_xJ^ms0KTpHJPnKiZjC zqwvd~$4khU6Zmkgw2NMcu539P5j)F|k%vTF@e)5=Q?E_i_cJr5=p%e{jv!8!Yq;>h zzK+Yz+=WPLbib_%-Kk7tT{RVbod-?+6y3Am9W@)QOjb#An>Nl6#f#;N`Z`s->;<`L z%rIftjpfLsERz*oLAr|frp+WVYYMfhhPuGrZNNgDSYGmZLC$J**VtIoP8shO6Vh~f zyl9i=^g>trX_@8D=Wz{$!Sl{<*_;sn>HXna9$frsEQQQm}RhN<= zwB^q&KiZxhYa1aA9iFeZU-LEcU_Vjuvsj^Vb_so4mURYK-|xOkx#20RrjFWPZk*tym=Biy)f$eOL?Uy$Z>fGfs1Stt+ePpC{dzz9Fs~!Q@EA5E^ zQ^f)+77exI^|$)_`yGiS6ZeNFUDV`bN<=MS93_h(HSKSSOqejlI;b7v(EqkH?i^O~ zKKpjuqj-C}Y_08t2Rx=Lgdqu1L9T8qmYp99zfNtsoTh^u?Cm9#h`xP8xQIuzWnj0= zE)3-V9hYG@B3&p4IhEn2Ze$F7@OdcIMP@;8kt0Vh1)T4(5-P^>9(?UTmamNXud?!E z*m5t&<^ZRO2#SSO&i1$6?5RbSNrJ1_DBwDZD#v&Y`ucC%av1e%p=$d}5Q}GGf{U{16;Yu5o z!4E?1F%~__($fB5YJNP;$aJL!qDAzplRD$;Z`|ouSmC*X%6aMF!Yx5$86ocLgr~8z zUV+7s(E3bT|L?#p$1E$SoiXFWlVIXNaDw5L8TK z&C$cu^zfd|ROy--C~)A;STm(-mFidXc1j#0EvDL0(mX+TUH85!X~@<7vlL5-QdxZ8 zt2i!1DL6eMx}TX@jiRW{Gp!hR;yR{8jp3)W9+R2lEXGl$R>pL{rej>6&%<+M%m7P* zrbeLTn=#VrK;1e@NKR>aJ)B09kMe_YD>dio2m>F3^6GIPrr<{>$CvD#tLKYv_`lo9 zyxR^t3SAv0w?mL&6n}@{OD!nacEshqbdz_JVU*fpND%uZ1>0dTW%OBNBFHg8i>{?* z^&gad0!oHS+5nX2KqL`;=y5OmnsOo^IjU<7K*DB2zB917f&yWvDZ%LC3KH_VU%53X z{y9U>cE75t9WZO*+WD=TP?M9e$TsFhJJv86m3jjffihB?P@H}nvgd%OLy(b zB%<(G!KJ*&d>nP=T}T)uof>aJ_mcbIwlTkYB5@eG*CW3C>LeFS_K6!6U0UztukxMz za0|(FYAbQe`cLn_${pEy&`xF*dVsOvZU(;mab7S!yxiu; z%KP4E)Yyg{Pu+$;^p;`jrRazelcy_w8Mx+dFu3HqqH1NxOcXFjQdf@9tO6r3bJhCk;~=zCa`@}f;d*4q~?O8!lFO#S@_6v9cDh>p9v08b`-!a{s@ z-UkW0b)~7?6&ZgkT3iWrJ|P`)W1jp6=~NUpFf5C1`3|D$Zq~<}c*5hf#h|I0yrkwql;Wr+lN9 zn5g9%+|c%AMbRPWRo|M_yB06WxaIY_w$X8dUXhID7B6~Ur*|7+d~_A&-~7spa#r*E zinN^ey5z^kPl!2OK8hIbl^&*fv7nA+@ghaH!Erv{#MDH$FMEn+ zM1pjsyKeVyk|iTEderI2um-wn-*XLYzc=bL;u4RA&iIEZ@??RJHT6tX6Yrk-IW6b& zqH*i39echNR1QzE3r|(BXGKiWHH3G5U((s=FY!(Dl*uUS(|}w(=6>5rM-E#^DA&)S ztJ5|8nf`HvDi{q6jp!l&)7}VYu(+ECF@;Vqw(cv?5;jCK_2w8re>^<4`3cl@-iexW+i_(e>TMEr<846DV5iSv4;X<8laH$s90{mF?YRQt*4ODik$f%zGI*4tm5 zoE%?w-@`$bFl!4un?x6j(XbDmY45FIGNhAdbG}=#{Y=Kz3H6dJK|Pt-Eph=MHX%yQ zvU2^qqDht7Q9Qc5lTJNor{K~^4Hu8g=2AC3-I^$>1~8sn70O926)kF+SG9e-3%V{t}e}1De&IgND$*t#K1GYGS_-j4I)xqnrKGd)1~U ze{VHGD`u*s%(SWISrJoMr)JQ6>!~riusSgw3gOE=;k~d$#1jyMRC?*@$9ju^&6S0O zzfh%ALU}d2LnAk8*p4zcUm*SNTbl|FI)ZQ=AG;Yl%`eaN>dc*vV)(m1I&BD)#J0sF zd=^Scj^8(7wy8W$(t6WMci8FP{(S#t7Lag-LEs9)XYUqw7EyYBCX^$?K(5fmMWHZU zu(1T7#ir#IWOo|KLS1|cF(|)%LOd#!ebYrId0y`hbGyXuNqto_Y;0~Bv?c$Ewb93P z?Q^l_OSb%2cu(4ItvbZ3^+t_t^TolkUncmP`GqJm>;0J|#BZ(OwXsqhizE>{EDl-q zNLi{-gDOG&JFuvnKH=fuAx|&>xK`bDd|chY6*qQWGHt(ncQZ`BPr5W#z!_z*>Pz_& zH*{#BS5j}QO1EirYSAgu&R)>iN4q(aa}qZn`Fd+2X0%) z${wux8XXCf<&*@+=-S&B?2H*4QDvR|A$W+oarh40>&4TNllna24dj&?Rx0Nf8M?lI zbdy9IiXrIg`PLbtQu)5@5Np!Hhy*7?94!-dC4)<5YS3nKX#!A@`*F+N zx7&@jnaENl7S^&`e@Dckk`V_35mT|)XjR(+PiXsQ&PVk{QwNBO+$6H!`5j3N<}1Cg zzbp#U+#>X!$Yi`;K!&SZLIhRHC+#tYa7m|(u1be`Y`&&DiZ+p-LcVGmvu$I{Vj^v zeuqbp+xJgq9%{-;+dS_&p7BUL`|{Q_oI2qn;Xs?miR%1vaXinw&z}D0@3axn ze?rXQ?R0kVa8T9t5UnilFEo;^^#Fr6+!~$Xo>4yxKOE<-Hs)Z!>Gu>Rd;g#T-ugz} zocqnkAG4}6K0soQD})b~#GvrwKb9~ub36ks|A^>r`p`*3zlZ&r`=hm_>l(d)JE$W! zz))7z{p^78K_x9(IpsL0F;N)#NS35K^ENZv_Ict<8r$Bo$mLX5#q3(l*zhT z3o_Ds6$hGG>|Bm~+l|@Rt0j>2er+vO?^d94f{3)mRtP5sHmVL^cVlNsv4gNL4*JeM z)ho)M$SyQa#3fHJil+#@vz+$PP`8LcZ~F?i#V<$peW|0z#rjaUeh2C`*GR@S z(9NDXPAhrSOWqX}ICiqoL|QQ8zfDIH&mQ%(PN0+?MmnS>eVZ|@a=*v__d;0G+D3cP zzJl&%;~rl|eFia2W~}KD?Z+l#oI8B_Y;LDH`MviM0q*&_=TP_|cl&4uBAwtanFgb- zOYePWeR8LB{ZyI?9@}2`M4hU;!niO=qbYaPx5q8&9>oW5p8_nBJ+#8w&g;pyt7p6cn4wQ$?oh zt7FR#wmD}>x4wjL1LWxT`#iWB*lk7>@}eXSs|tK)AE&6E+Alv@-rlpNLcm`&?*#zS zoXg1HmyId)e0}`^ zU}OFQq#}6qU~S|tdV@6WHos{HPO&sJ|VyE(TUq z#lfZb;|xm!I9qGMKBZz|dQvNzIuqJ@I0{dOVAIEqI~hr@CwC^YIaYrL$v;22AL`~1 zodm8m^mS0?oJ>?pKUu>=tCTm|zoF3N0xcPeSim%VML`lIs7YIO0V1tzMXrpVoq?7r zFF?Lp$$mL?Y39WW2vt`3KH4t+T8kL&j^?(LsxT$UgsXn5`j*0^mzr3{voCuC=aa_Y zVVjKSh|fK0UMtk2^w;mkP4kC*ED=vAb~P4aKR{wHT=ps3x<@w93UcG03x>02y*z!zId6$^H4KYKhtCAl;vXk{9K2Iv)2 z`5ULBpZ(`YYry{|1EAUz0|30#%+)nUR`&Z{(9 zr^nP=JR6Sh_S;|56Ts7rEBVtethreKicM|CFbxmYwa#zmCbKMVE2&ai3&eD~O%Ez> z2na@u;c{-y1?!D9O=-)b)S4d{5$R(Nhz3giu>1{#YX2jVR_FToXhhTfQ-jK!{TDxg zT`R3@zlG=0drXX}Ea8_w+amW1Tt!*vDBAba$r0&4f14soEBQa?F>_Zi3qf9>S4Se; z^pbT~WbxpI`!9G1J`5A%R7H;OEyjNx6noICbI2ZPK2F^DY-@P?c)qfZN5^jtE{*Ox zq15JKx=pM%I~W5IjG!=Ov_=KO)2TLFkDVGpRp#!5pSn_qj<>p1=Fbe;N*dZ+WV%>e z3pH_xGm#*LC!nu`P-&=jKeYXdSHfM;_v?~tEy1mAH@xBCnzPE%(|EU2I*aM+d@+Y1 zS8pYR#IGpTYi3es#1WO)~3U9U3g;CiM7Mp_e@8nLb@8`5jhPEO%8?}NM}hdRgg zDcWKx=V@W6pUxa=IM5&qD<7dcz#1Tt#xqh>*10)oC4%Zg_iBv&pD&$TadS(yJ2U_X zX9LxxPOhKLNN(iBUtg;@wUnJW!VH7F`QHDy1zw9<+b4%E3Rr({e`+Id^`Y+=S8&|V z;?Eb2C*dn4Q|G&zUw;0qSzhp2>LN@XDk~_+ zZUO7%Dg{o*cPp+Y&5zpDr(qj0C8j3iY$4K}aMz;WzQ6pn5Z;S@?q)s_xe5N`miKPu z+PJflyY>~C@8|uoOuX&prrE{Na=~+!>?f_(!FF*?9rHBfMs>9VVv*}L*{#JxRmG$S zc8(bcjp5pc6WO}q@`^^+gh)%s=`R1)(vkWwMq~DSruq_@)zC95hcop%?M92~-^tJ9 z({L4152&mQ93SxiEavOvD2?8cEb8gI#q@LHahM@d@b6cMy-7Nni#!cNy#7oH}6wDHQU^{>*Qb~ z0j_M#?)h1U!=;^Jq+?|aDPFo0b@Dm`z0Z~c;~S!0X?t*;Q%5YU%6(a~ujrYh_;+g< zx5_$pjpI$_5?PCakiYRrtnGe4W~k*`?$|R?ljFWrfJ_d=@z` zM}w-hWF)T}37GC@z)A)9II}_Ku#DX^$AI5>1|5>>UYVd?d;6!c^RjSOVb*Velw2TO zge%?G!>69`p%jOUEvrY9VwnBL*B41lGbS{=N+lLP<_YiN*280KIb53!dvE>x$|`M# z?5r^vxYk73q8H-Yuz?;;mhLJOu`;+pa3|9Rs|DNk&|V&UsOHhv9-^`0e5fy>rj!+> zUeIvtS^GVr@5D_N2K2!GMx2*ath(Pa$m!^lh(()UC#6sDHKw1eiY~cwvbNy^W7Aly ze;IEXt=$yK0Pzgg)F#t{|>W6ybQo9b7C^UbF^rsr*xKa)r2Ne34{M#D(RjHWj z2ESxWd9aqH*8>a0l7xXqRFF67_7KkL7%O(7ZMdfs`wVBiVC1VRlLP8@Uo4VX$MA_| zkcV#&PJ#!Jl&6#tKG2TWdpZl5KyZ$LS+p*++Mm(I>?>|pNT<90SzMl2C*$1!(=7vJ zL7mUD#BYI=PVVIAX@qFMuGCrM2VO@^CVz>E#)>WzR21ZR1#j?Rw^UxG z(0REvw0!ERM3;KBV7Juw^&UjbEqoFot8et80*psu`pBdK%OSo?5)1mF$osB*rCoBTd_Y7Vyh;{Q?S%Ajm``az#M$mMUl~C(gnj#?bfFqX> zSNmpNLZ1YEwMKEPeb%g{#{=3le4*}wzRk)vtRt5TL|p2=v*W85aVezvu1UAx9nKt z&Sv-!FDqIr<(=4)=hIKSmS}De;3uvS<7^Xo__mx#AF5_TW}GutM4L12EcDM)8n0Nz zO6MTu72GW!0j7|(H>?52<-+ckSM^UkFMYUg)aRB7oqJ7Ip21&HTrNo0R$~ByB^yNm_c-t zEX&vPk4w2UyH7)PL8EnbYHM2cV=ZI@QUW^x3~0g8pQcv|*iG=QV8719wVB}rR@Ngo z@)8oB;SVjk=x?unu^tFMQ>Y#2Axce(kAaVoM$|D1;9LRtfQuUb{71KOeg#z*W0Omoj?fvt!Dx3emsm*mqLZV;ptHNg z&=IEMN59{e(-8Ls<=70`WiMJQj`7L)K4G`!Mni`cGi1`~3t!fxr{xmMrM?Yo`Y6ao zVHG%l!}IFM@|2Y!A?2i&gx70xCveG~OAheaFqu1JyySMDDFtXyRq9o^Riq2Ana~tp zyZDq+TjJ9}Qwt0cPlC~RrN7Wr7V93YD*->1Lz8%xst)Dcui^8;`LypAXW;6^qDe@R zZGxL_l?2q;umg@6rwzyQv@-GkPD&A}>XZz{{p73fSc_a#)>$#$??+97qwp1oHs98> znuz#Hp0B}j5X+3I*9^GA&W#X6W4gb1MYijG-*~CK(TnEymJWUz3J?kZlCLb9dwpgJ z0%N77LPDM$!&BZT=?Ckz$HTpK>-}giS;fu%n6{fwuQ<a;cWP-!kn7WA;~+)69oc^ZRcmyB7bw2CY=_ebLTH)o$f zXx^EnrYu|37mJa;1F;OSwz?G>9sRESmYmBa!4ef#&D4DWa*fkqM%!{K+p3$cJqilR^qzPD|Gv7@Nj5bSZ+R}7RR!i5dDJ`L1bhMP`J&g z)roycv!L@Mr6VyeU`K*0qgKU)HM*Ij$F`?Sr7w>x908s( zSMTOl3bn=StS*|0b@rdo5l_-R7XF~CJ|qpb>gdcz#*s|bCk_hmp8-H$-&4(*YhzPG zMx6?anlnfce>l}~i64hgyclz8n#hh$l6Bt=Vy?wPwh>5#Wa4PdE##>YuNG2*HwId`KDDf`D?&w9IJ19 zw})(ZtUFWLoBMo;imYKvze6mG%ps4Dae{si@Z zccvl*ZND3QvR~`dfiBIVSC1gM`t48(>a(+{7*%DoNAc4m&UZN&ajUrLR**dAxm91g85=Ds6*A$Q^4knge=5{BvPL=-}HmSqu%*3j(w;*V)R{_OUhMK?p_J_*8vj|R5&W2^}WiUDgW{r^lK=FY8uo&jD5nWoYxCt3r>c z?~#WVd(H(g3!Wdub~OB9K(I|@zmV!1bsj;KcoTxu@BafIhnAjgpvt4gZ@X4T8djIuz165lI@BRRpsVRz( z`}e{`RfjW9OPBFb<^^7{=l%7%GIQSX2T5#8ZV6^{Df2JRKCgLEIUnUv>U>k?cy>mF;6v|$TK*o2PNfZ(BX8JG7^#3meKOlExg$4lVBw|cR z{Cm94%YS_#g^40JACLc=_|5+ciVVkJdf#MmzI;J|T1WQi@d8i;X@)H7_%4fyWK%ix9Mun=p0ST6 z7ZD~QE>uPi28o|h<*)^56yOIXsK3G48*(~meS-^v zun_7)f15n5dm(lQnMx}Y25~myyW=F;9q?4-;wy7E_e9duValg`dcRkYYQksLEp2af z5%wY2yzM6?f`)`-A!LWxCMgC6r_!7F9!M-=f&6DR_Hv3K{iOztk5xygg0fr+P+ zg7%S72XJg<=LZH$=WyutkRIs=w<6Xw;T=6wlRuPi;KfLJQFqW++pk&3$-DsGb`RCf zt(&l=JF!xsA5W*JnRo{mT13n8%8MC&(d|lnrZX73St?1tc~0y~nNx84RNJ5M#G`cH zbWNYNrCEkyW|D2iIQADFlvYB^WoNmmyG4HQWtj^ou4@z<-6j-9S;)!_}- zp>3Rk0e9E^Q7yqUV$-S<=qUdMb0AP%qhKg$;OEn6zXZQ^xwMfqw(8Jx)xMD9~;eH zt`I)CQI>$NL%%jA(Njn<3LQI;Nvb+S1{*;wV1fo-2k0hswawNSn%~?ILsMnQm~=gl z^ixc$Xx#OqH>neS4rPIDETH4AN2U>>S=S1Fmf#B<*W-J%(dfjCQsXjT!BYy?D(k&Q zuHFhF1*ojp-NX-R!JTP-%uM8-e-4lWXTR?(b(424GxV260*aL?4DQ%POM;7#xa~o> zDD7s8+NYK!3Kru zn+uYNR@;HrljyKZg(~>L0;dbnk9l@RR#X%fnbxL-a{SvSmg_k+ou%g8*9&xetQsQn zIWv+DdQ)GSk^^l>b|I^S8)@7!-Kjl?`5%)$E7%cegE5Z3Pvsmp9?xa;jt5SxKq|*e zYI73o)#sRA%Dg0ALGrLeXmCTVpDvS{b`bhMH)6I_E;<)LHDijwGJl_<1-J~4Z%}QG z#`eJWZOD5n^86|~A{>YKO!PWwS>X`zUIH3Iz@uTB}8P*)>lYimh|P@8Lu< z99nP-YauN6K+V3V{T+_?z1LyEO(=KX)cn`DQU@?QfWl*wqO3KJP($7f2g#s8{|08yx z8O?s>xK->}7-?_QLmL4JD=e-jpl|(TP=m;;`&JqR<*cdu3+;AYk3CV;sL|SgFd_@Q zjss-(0!qvKJw_c3KoMkp zVSu@&=XW@EY>#nzcw=>50&ip7jPCA?EXxJ6Z)Tlxbq{s4r%}?;qMr8{jG2~Q6)@^L zGwGmgYapCbCa#Ul)ifSl-(GcS=nEp+u1`M&8_yqAXZ% z1bwLz>YqYei&F))U0T7{o2>nPQWeLnJ@R2&b*h%n6l>+iyOI0R1OK2VGmikl^u2{B zY>Q#SR(57bZ$=Q_&{yI%ynl_4avHnKeoU01IaB%%h67k|k{#VTY_OSme z*x~}R)8OpN2LtNJZ%v0|&0%xn{d{WR_fD<(? zeY=_G(#2ro@f4I;_7*dLUNMinN4h{FS{-^{Ekzsb(m>H8CA^aqW-aV>Yz31lB{8_t zVH(Ocue9=jnB5;?2{{?0SA^1!o$4MuwauV5w~Cu4Y$>F((@32gW_n1vIqBDVqgcuR zAYDeglZixrX}Z3|yEh)_;nV+(kvLpm{mO#*LD$B#qP3)@Vinlir)zI=gg2#9NioD3 z<-3)|KNmDdTJsINYmM{{YrV9FW5ar!%86}fWE#8W$ifFuDU`2$!q?Jw0HhsC#W1MC zcm8+kl6UY)XQBH|347mPK6Dj0-1 zPc;p5NBhR}S$i0hZuHhl?S_YLPm)R+>EH%P=$0`P{4!t7WUlu-ggbY9rV8 zWDRinJlMNO*1t43(dpN};1yirv(|+EBkF(h6>9mXL5@RQ@_k^ckwnEerDQSC53o(z z^>J%0tR+Vd*!@0=tz?l$Y-eYY2X2oI+Nsp`;12Wq4Hy0b{iQ1ENP{r1A{MLSUxD*NfD>b_|mRv6DX#@otWQ#f1(Y#xE|ft*8w-8njw zj}*UEQzAMu8cL)q1o1=H*CD#^q#I536f+y8XZ=Qf=04G4EI)8*QZDliF0AN#w6V1{ zyd546T18Qe*sheF;Le_k^wxx+pOUAnsd53YnUcF zI7kIGe-W`cqoVlQ$;lQFsJy*N64X}C#soA}*$NgaRK(RpSBGvl$&RKLQ%b)A9m_|E z?6d0B-snw&+#bb1<6Y5&b)Qd=oQ4+Ojq7;|Js?Kaj}InPatyQ)R5+)v1+LGqR?{Zi;@JC z$A>;$>tAR{?jy~aF9XW*ON{>EtGo!gbl?Aq?nd2(O^QB3~r8VDW_=sOeR>iEjg z>xnk8f|7o#?IB{Ko+{`|$fq0PYS~<(*y%bCdwl{Y45vPH52DfcI{!v8+}fKvU{rJM zPTHM(0t?MZHi#~kr{3w5skw=Xcc~aBbqvx#_%VQjI0&EKm*SUUYf1K1J`ZAs3xDvJ zs<&3s+%@&+ZUGe&{=F*RHSfnU4lLd2TdW-Ho2?qNsvZbU>9XTdpq;qWWu{CIYy5wp z82T_SHlO|gBx3ZoHr2%n=AJirZcOkt+2^Er(6Mr;zN*yS*7~X| zskOi-uK%dXh#eLNStu2LSGOXdXlb&CjRvsch*pMn=5#AY-O9?QlM*KgDg@cJUsc9tBC-IFsXm!&D2dl$gkT-YN1EB z!s>a5^V5btZ!f6DncnWI-8s+A z$%wLCD!qKzoz|zx&>zZT`k8dX?XvrjW|d_*qid>lI=O27@T0o1G=GqnmDlDkE`lj> zib4T27~^{dV>qk1s?@y@nya=e?gv?;*DDX=1sP|F53>th(tpJaPLve?Hdvm_q*fcXa4Icl zU02ULY3m+kZiQxR9(`Qjpw-k_Adf519{=&m-C-nK@cyX;a3zQL)@G3R;L1*)`5|@J zvXu;wK?akp+4h#5OIb=4E|?c`+m@ctZqSqCYcAxyzuW6A2UFphty+FOU|9Zop00fu z9}_6lmX(J#O+~9!F{;k)R>NkZXx0&YZ$)Z5L~l-HGhYt z?QUY*^?71oG%OmbF!lNr2*AxsLmCLS9N`gxI_$=6MZbSZ|8i20(Yf-AfCqvWxklc7vcnewe=}i($ zKuGoMGy90t9(_w9Dmw-^!zt4^5D2xdPP!4}pQNKGKr)wo!(}fy-rZ|v71L<9W2-;w za_IpMy3sd`F7`hmNN8iThIw%QDi`WA(_|OR`>PimqrY#jc$5FybP+<>!t?AzFFgIP zU;w1Bhj}~$2$45`EBtkwt4l*x4JRKhj5d|As2b|7w+N1#Z1Ggo{0G1NEl#BYDsQ=n zKj4c}?B$!)t=#zNQE%~xz@#+eD44@4pC^0p-&BIGPybX2CjV&Z#I}s;pUiNPj=tsl zRmP&s_Zib@)j}gH2beQ%O%n})VmMOa)c|Kx0X)^C-O;(ZiuM@8bv4^9{60a75|i)- zwym9(jSMbpnXujlel5RjljRka%)I>aT^`Ln{@TqF%8g=y!$dLYukjkLKTVQI5sU;Z zM%j&whXA3Q0&UxGZYm*TMuz2}&>^4kU97+w=4shuD|QD38e`Nz-t3PJ2$CdOKH~^& z&cAQZ;)m3(pwSec@NHP-Wm)GF&C675_CVb$;iE&3pk) zFI`l_XPrhSzS3ztiu0bLq#!JDT{A<;I7t%rJa@=Ec^X23*K6XUC!G@P_D6`kifK?!08 zn#*u+?5$&zE z&*GA;{?%+zdhu_t>&xG2`j^TzX9aO_O`$hBXP#sN#ZC7Cx+^GKnY&6W8CevRRP3$@ zp{K5D#L}s)M`n32fAdr)=^Cu*da@cQYyEz};W-k7%8~a?#{TRs`?6(W?=d6V zYqbO@6M`p0MET7n6LZW^hHf_=%tgmb${>NOLU0dOSy}jt{apF=H?CD(4jYM=S?1Tc z*wk$mt;-~aN7H4*>^8Qj@g9sc9rsBm=RO|kKN^cJA3mNLJb2#=nVqU1pEo}vatuQ0 z8!26nLxIQuUtgZjc`1828CU<1XtMdD90!~lT%A|TW-@C?cPaXW*0LnH_QY&s@*VE_ zTu)fSz2pTl_DlS7x&40B(SQF7iy3UGQMNQqpITp#V^ZMc%AC7X!dQeE$iiMV5tGjR zSF}LhC%LWn5T7Ma%Ssm&7Tc(>Ydnot9+!HI(6rW9>^3f-;x28^_wWQ=*HY%2=(Zvs zhDf&@hO_g@A{AntD{VacNKNO19w$!TBFMrOZOQlj>tbuSt5-U0AJic|5py~mTFYCk zc{!U=F?Vj*oPGL8wS)`t6D?Jz0Xm;u9zL2oi0lB>`#fO3HRYo%X`1$tp zE@f!@{E}MjaUSYP0T0wIG|{|IXH>{gd-;3t#~DL}=kH~6c#a1am&g0}-8s+nym97@pSjF5coRBFK?Kuvg>%Vec=}g#&Ut=pH^*x-&y>HnfbnJwUd30wK#ZiEiD$%v!8|6k1<;sr?=VObxEeKy{G^4cX!hD4D@qrU!(6I~K_ z{99BPo=5gZyb4G)jh5xpkY6)Bm>?CWpW%OWca}kMt?im-lRyLl!6CS7sa>Ca!VJC}=T3)=5E%Sy-l*$sgwe)nL znW+z1_(4BSyv%6*3N(wElg_TqZ@%5AuI`Xt7Zp5*KEwuxDGr$UD1;R{TTJG6@D$f} zlLkDTwKuW43lXkV$Grl$%nC~b>X8}TjELpDj>X$jNKrUpd$(ghO&mVy6~2Oh9;mUv zB$JkS*dTajBSk*{)vgkG@A7<66H@svlQ-FqP;6Tj&c z!K4w0X{hA-vdEGSG%Bim3QBaBB7{{CS}d+OEDqPoVeXZYM$5@N6N*l}Q)T`NreHUN zZIHMx>EfIsi7^6?TjVccm{i6DS`TbfxP+sU zJrTAk9vZ$X!##Dbn0eLXW#r!wlnzG9ppFKn14*)BhRgysr9%6mO_j$!WAz=7QLRSmiAP11FM+bpwRo>K9}pF{8(>4uvgz&!e|M>mUyg9E%(FDHjh5q zq4H|O%}Ke2;$m|cyXRP-H^e*Akut!n2?U_032 zrgWn@KbGdOx&A!qLiCwi{Rwvg!j1zMNY{(PPYNPuqE4pBn<{=L(xl)oHfZ0D=@p0- z5Cv_Wk#sj-b16S;STr=unz~r*TZ<@9sO(OYnyL0A*A9DFNN?ON_`a-VF{R2d(M;eq z^S2gVH3GVZN^r46Lc*c!X4V+hE2i`A|6E25 z5Ug$?H#I|NhO*o;zQk+ICZ9hl^;Ht*DChC7=M7eP%VZ(LLtTHI;v2$qH{94vA!2qp z8m@Py>5N8rve(j!Z6OtkX}5ZQB%&1!o1SJqyv792dR zn9q+dmFA`)KtcE<*An5%=|{2Ip?>(_7T+y&&@5( zt%LRNvx@eNDg1M5ANT~-A*|nYgo?Z>Q~2EVH9$Z$CQbE<<&L_)k^4Rpc!M95Xdlw; z`xol@)LZ$FK321APw3E0MhR1pqSvMa5L2f8_|_7mAOw$o7PRR)7Mh>~|5;hH@y_@+ z^jWMqpwumRYI5l`<7dHP;Y~NTn4XM)x`hg}?e%=XdwYDcaIC{>tBhsPpturza87u8 z`BT}(M_Lq!f4D%^@jQ`Cp_rwkn$J0pOCFj}lfs_&X%UBJ$nwe2bH{C^*ExiGzjC!o z%FXua>N=762Gw~w?$x5`l9iVZ@Tz_Lo=O@iO1SG^H~3R}5zPTFfV9X}O180^sJWoy z09M`lgU%J6-=gV!>(J=&Vrwb;t(opjEZ0R4)qGtQa)B6f0?nfmivo$2-6 zhB4*W8{Af;wV#bj@x1K~)qBer$h(15DJH0vrbx z)ww6E`}jn(o1oqvF*W@yTfGx6iJ)W*4(@zG@Y2_gqB`9MIk36hP>pz4g0zA&_o&(j zh7I{KAf7;uxZL^7(fIt9tWAtu2m_im)%2^E(`LfIc z_C4O#T9nMQz?kYB#NWM}?CKqzHR1FS-+N`<@I)OmUtwGm)QPoqcibk@JdUPKA zpkg!Y9)@*}1zmlr_!>9MK}R}emC7&6TDq?6!_xq9*--OwX)>d1gz6lo+iuH-+8d`M{Cob3oZIe!h!?KzN8IvbQk_4hd?7vp=EN) zCv{Bcg|a@6(>$=oEK*>Q4<2uT*U;jw_pFd{)&j}EH*9mOQo0#ouv9R*NQBTOk;p>; z!_G0uY0kd97@>B=O@B9OTE1Hip=p+3S^fURERoeaP>5+3Nh|>B)0;|$No}@xKr(Zk zT@2j3Z1oqkC5L9ZBc+sG_d$G9EEx=VP(As-g>5MwD@O$B<;v|ig7|pZI|63P^7?(O z#g5k=I9zDB5kd~sbfCc6uI?deT7z20MwD04P+`^C?d=AWC%0z0U24UI8Ai>Od5ewt zPQue3GTtKWRJ3|<^zV(`%>1Hx!Ji-!XLy?;-7laU#*TfYi`}YqnH|kMadz0Nq?e69 z+UKm7&W}zftS#W44Q*V@LWmrj;RkH&kf^ryxtB!9b{>miF|Zjan2b57b1`IJtDvb` zn6omk+e@cJ7yEH4B4>wxI(kUkslKFZE;v||$pu3w<0SLYzarKnBADKRg-On{UzO4# zto|oC3!fvs7V(H=o_qNEC4(f({Toi1CPSZ3u4cv1TL+`EgO~<+_3Sd~W2KerP)`06 za*j)?oGC%-lBJ8URHC{*n`IR=f__bR;l)ycqrt`pmwvRK`;Nt}~g6;Qg;~iVTU!_>uMWjwW`v3MTFT-+MN$PB1 z+q1%S@4&SNxSnC?UeZB{S3f6SKeDsJ?IGZ3m?UyV>FSpDs1Fx7HHtsQn>$R1Qa~6M`r2b;YU{u^~)n6yoGH0bo=LVP;X3`n4&}80&=7F2U z2J_|!V(^;uWxU^)_rAIWefS3Ego{1|m|?Z;?XZIqYo9L*%s#So6dX<(yS)R3su~lZ**V-+VH67^8*GM$-g2=7Se!%#58G0ek5(~8M)zAW+qFD z_24<-{4vLyv=E6}M>kW{(Ia4Ta-84>MzPEx12;R={yO7AIO%|&ky<-*B@LJ)W*IbO z@Y=u>Dt}OKSTgP74PNVNAb-P~2nOB>4>T(X8ILsJaxkhPV+#D*vI}?S(N!akit~59 zdvXaaoJx2hUCbvNCy`k(lL>s$f&rE$qWh!w*fwvHsxh{6G=IC!+zxOq0Us+^Ienwe z_CGuwEj5zPm{tO-(H!McXPx0I#+c-0i z#XsqCr^#>?72M*oWv#9X%K6T3Tkcz%be(s#zWT&Tx*%Xc4|h7vGiNk92Ln>!(YNO7 zJgOV&DwZhGK<#k^9z?>pvDK&AZ)Vm5MG?#6_+434lxZ+93Q4DJ|rZ`_J3;qCsfn`Dwt{SpKFv;!x5f9PF$sg3R#m{ z8M8QC9^Ml^-`iFR`v)2R_$BvuOOF{bg|xt{0a`6Is-U6CG~RFh$2%Zbc6K(jHV60W z(${DK5*0>(3P44qx2CuyDaXKBwny^~tL)Fq<11_BMyJqaAY`sxM3i5J-iM*RLyD(r z&)9lTpR|!g9OxIC{w{wzi3v4s3D}w)%w@OKQ>}NYLGI?O?c$V5z(AWKJr`3B&;jHe z)E9K8$Uak9=eXCo%yIK*$!4#P``LP-7I!pitiHsL)#Qpbvt2wjvCHP)f-fNvWJUoc zcQ-c`yWfTVHr5oVP>U!h$O$5%!iuZ2p6f28>@wO=*e`bQMPm@7;(RBAsdX58Hk!Tv zZzOhC(lpXoBQcjvz>m&{i2lTn8eVB+DOtOSU`9QB$ihu8FpQj40ALt{57h5 z2%WGS=Sy?EVsHbmbUlFOhr-#fH$CRp4sl%fc4l)TDV%~g<{p1Soyt%R(Iz!L7@n?a zL9vUtY20~pIMT7$l&cL2?42d=Y+KxY}R66NaAg|8pJSpP!ZX!$wXElZ>; z##Cgask+?AFartaXoN~+TFWfWEV|t4Li&zs*+ApAgWe6bD)YyU+~}FZ!@|S!t%NBN__vlB4x-bu&b0+}Xp7H9)LN zG5BTD->VJ3H;(B+M;iQ6yI+4BAte!!xB6h;2~GK0Aa_l2~$`t+k~lf`SzY=GBz4z<%J!$NQ;2?hpmX`BmqFBR=E zuy3js4+b*pK z90pUNA_6uKPIP&6lUhHH=Ou800oIkcvzUI;BPSdLl*Eg{-#(WwZT&cf?on{2VjHHa z1?kw$3n^kQOhi7-@0iH9*E3gd%75f;|D%AL*$%`+A8oRPLYXd*Cd^Pw=wX5TlKKU# zRbzz8V(jWzGbSQnoUN{`B>Y*u8Y0hBS?#7m(ezod`0fP3&WQ@j!JI^608^HHX6%9y zmoW9#r4-@!PPJ*8ui)?cMQ%Wq-&1URz~qmih^x%-XRLoQpN!yJNK zyNwD?qTNmWtZRm$xbwdC;>~pz14g}~@Umu$)Q}R;mnr|Ja8Bu>5IRdzke%p5dSrDx zz(oPy-7S8yY43mwvXjWxO@yPNs;JjX;s_MEuvYO-)qu6Ad+X zJTq73u6s{6U6I#@aEYv@b}|zo4aIjo)qO1aPuJx%>fYNAjr4j0FaW~HI zjw4#gS#a5vW5TC_lyu@g6kVU9DHtg0(o zY=i!d9ET4BZ!MqOLv5U`zM!QBvT@y-zVe8S4xp}gn1-i*Xr}d69mfFq4Q5h0)4LMs zbHF08M%9*&^$g_e@_sXfFYR16fip2r_<$(bocikb5Gz#Ubd`whq#msL*5{}RsL2ln zGIG2Ci7E%m&b#kxlZEB0(`1D{Uk;==&MRsf3r3OwozJznFy%7Nv6WtVdmg?Rlk8f- z90=T8@NHiYz=&^o*p2i`t%%J#nGgAd10e3>DkcC?pKO}PhRS~?0zc*@9Y|26xwL1#1g)$+NW>uP(>pGZ1|FFqf(w<(A68!~>G zeB+)2Dn=k}PQ?E!ZLZ>KmjQqY;R}fyJscA$SnVg=iI|ClH_9IVBEvveUspAoI)7Sa zjmsD$i1R9p_z$Q&deMp!<|N&39YCe?dObrf)bs^!6Dolx&!w5ePD>Fr7+{#J8eMDk zsexk_;-5G|Xl7&b8d+M$5DKMC;ap-sPebs|3%f4tf9)Sem* zQ$QjhxzbNaWj{2}QbE_>s#=gtuwycD9bQ3QoKY2ma(Dtk7*!k@25|v%fQb)~JyTo;A|qFq7Ulk7I4F-cGKVt6>eqzi_I3&dL+asa%N zmw%HB5K}{3kUK5ZbxY6la~a~Cx><;0u@nmri4U_fSuc!#k!{2T19z*{!VTSgt(pnH ztfJNJwA&52qvx6o>aaA>YG$rwtzp9$R%>ZO`|rl6h_4N-c6D_>1?N=-bdiEl1gIv? zHVCFL278`Gb_IqMxYWn0h^R@Mi0;L1peM9EzSQ)H+B>2qayar2z8z~*r3aAsDw7My z&Jz;zGDA8X0O&i}RIKV~fW_5AX|N4D-=M5ER3}evix7A;(@=wc)RYa(y60vdaTgYD zPxQdhv|`oZxdR0xJotd1AA#T*8n9SPQymojidi3=A!pOwe^YEX$<3heI3WVC$Z;2E z>`-(?AUmEf>dwt0vpE{sc=^V1$*=qorx;u9%*tLK9({koaSu)?v+?dwzf51hSag)0 z+#xQ?J`hX?76$Vu6}+7;a>hj4p>c&EoE$q+4L)0nJ5zy1k*(o+Tvux>&pWo38iB689L2a0Wk2z4D0!{WA4 z53FEgK*pcyI+l11%YOYr_1ba4E=_bXAZ^;kOvsF5E+SmVaODFLrtH`&vow`k9?;+d zYfc|&Eg?JIT<}(^heH{5=|<61FlE!&4FOnWJ`1e8g^|h$;cqp!E$#q!d2LLR2g~rt zYBU-O@EWL@%$xMv$X>djiIiJXs-WV00!JY5{Zey95o@29UE4NIL-ILwN3qx)NslCY z=c5{XON@3?XAJjTgo_QQsPs8j0YNf6Q1givyQEYFcZ9;hgUVYgzVin2qY`#_90>`8_5DsVlqDVkDBpQ{xr(fY&K5Iv+ZCiKbrSE0?DxV+k*&V@igGs3z64PeqBI*<&L zMT)c?_fk|-63a2h*>TShQKfT@VVHyPf&#(eme?R(ol6=h?t{BuMK^_ysMn-eRsQ&F zltiDdL1_5GqGREYhRsC4XI}dUsb4*5E^|R64!;g$e&E$JeQQaEBB|PkElRD|d{5R8 z2q_)XdQl_sgUnXT)MaWKjgyaln%HxjM6_7{;nvH zZCk0e9-vQk(vN1isS5VK?%%*%L+*3Ec-f`Q5h!66Z9zterJMov+dkH@UlYgXJmtYB zb07TC{!*(mH5?g2P42hiA6`YoQ;>5`n`UjmREou^nRjgS1c-K{SlIbwTTNU-ILCiQ zpTlJq#Khk*H$_=nr;wA#Jr zOsC(9>eEsWcs%<8UyUldg8?;DW*F1jvk|WAirwJ+J{~*N*;XiAMDZkA+#hH~Z1CmQ z6J+aB!vOKZXPl7dC=$YJ$c%g=B_+naJvknII2#td^9yy{m12>4tuxj9^X}?N)-QVK zwkN3wDtOy}`H$g=`QqaYSJ$w=u6%cwRf|!xc@sED@hn?1WJ)$X-H=Lh%YHpgUy2eFF5+pSGkxa-q zWacZqAzi=|Ih3}E&*+xs9dDrp$#3naVT=VLc z_Q6yxuEq`fU>?Vfu%|AA#wl9nA#O9#N?lvW@6b1yif&^1jI-zKH3kJ+G1d!@@!wBn zY)%@EZJTe+Q7yi?WHTI*V`eBZg5cWk+4Z7|mExbehFOZQkq)ipZGeujdtGf@tDHLrnbeA;v-1*heTyxhcixlLt{O`2;4sLk9N~T$-B7~!c-e=Z2@7>V+ex(_r-SY zl6qqEnW<)@pvvfaxmRC6${WBsO4()eyayb}Ap8q~Cc|5)mC)!sk?q|_dws7rTHyKh z0r(Se0zcb!3JJ{u82rL#pccn*W^mq?+~%87aSUrHEBSV48W_)K-(}h zE!_%G>hohE9UKCmA|o}^KLo4`|CuNBf5D*smQerKC7FPz0w7vm>cH$mp4{s_QU3XZ zkgWTQaT?6um*ni{Mz`u?254yFVHMc-<_HNDjJGRLg!077C(C=$Ft9OIRm<>7(@pdj zu%e|t`8^?9MY}fK5#8SzO|8Iq=ae#m!#Mm1nsslxML|NE4U85W&n9V1J`yV~yOqSI zLg8Joi}{wNV8@1p^piKsQ0H?dtC~bs6&H$zI(!xM*Q4&-Hjyn@$gSToWyw!` z7-Ow!#9r`gIx(;56{y@+(yi%vFQo_G`;&cvICB=mZV`SAF|oODO1(I2GFDRs{M9nd z0AtkbBx!nhxsycDf+8|Zb#K|o`9Hvad7rgZlM6m*Vb=$;pE<_|z*Br2_=9mjt#L=T z$1w==&TAJ2l(g@Ur`rX)s&`f42UCupi%r)>-UvUP8?1|sf@}N-flrBx?n^Hp9sf#S zxBn%5)q(1e)xcl(oJL3X89n;Db+r~iZm8}(tqAE^96;*<2u{CPJ|=e&63c9KyG##L5pRIr?etx|6zsK-Vxs>haJPbDe14 zduB1f{=rkvFhx&h?*U|sUpp$7HudWgR53}+eU9HxSM;R%BUv(`i+E~29cKa(he3d z?d=sv_Xha(%>f$2r+`!==JJv5Xz#SoS?XIrHJkoP?MZ13oBU5~sE+#>RGhDEQH`l( zR=2L_-Xlr$aUi5T)deFL_00{JGA-PxAE>b1O%#y*8ppq zf1i|M0Y4Q0MD24uva2$|t934FMx{^h|Afp1fO_yTR zrqZ&{PV<1k2ju0#^`Sv~-xo6*tgCY3#BK8`F1*JVUp9=%ToW@$MLV;8? zi?d&Ppi1NC3r)aAg68A~7D{x~Pe4ob>^AbTxel%bA0<9d)>;2ea(~7Tc*K~}K5M(x zqU*Mw?`uDt(eV+efXJ$eOarf?QlLMcp+Ba>Yk?*jwco(hH+1gM9bKj9Scl!E`+s)G9RuZ}-Tx%fD>GAWY;;OF;n!FNPP|nQ07npL7wXz_yBucVVWT z0EO$kx;hAKS%LKOi@0OwV6$aB#d#Rtzok|GTdr<)?kiKft872~T)k1c`$c#6;IixX z(9-zov|cL=SXs<)?w1lLbYVi$G`HKGiDX^d0ZGCO%asj2g-3E&1Tr^q093Dt+){%$04=r zJEISt4&GOG^LX&~9cRyNiK*VY`@pWS@LH{SffG8XZ(8g+uw$<}eyBXX>h3-3m09jP zSX`X6VVb2BYR0pT$}zARm5Iw;Ls>YOy?GcwzkEPkpYur`DX)U88M@Js;o79$) z(_`_(?o};XDU5~3?i3LC$K||FQ*9)wU%dq06VrfjbB-by8XdW&dygxvGp6JM-Hw=F zoz+y08tNWS$`H_X zVo`0Og)e31DMZVtn{pXO!XS6w+KL=S4z->@03)9;pnNYcTrxbt)+b4?86VNo!dSf| z#xWPFL16rD4iaC~#EAh0wB2#I(mgi-Z%bh~A&eXlz(`LLWN1V9EibD`N|VN+{wsUR8n*ig;kdNnf%Qf3Y8yN*1n1C;$$ayq0kRI(h9q#)nlla)2hv zw;d6xYuRc&h9qE^chCI5_@nEB(oCAopbO##(BR5sSSsdAHY?VqN21^O3-GyKV69$4 znsg9H*J(Vra^{vT0s__VrF}-Liqeg_N3@JeiesD+?K;4K0s=RLb~_-BvYR--{W&s} zYg`Ju>#^bXOJW;`bq{d@=wp6{v~$z%w0=Ku5fs{!{=*M~O3%1(ub00*M21i+|8yiD zfPS9f*AeaB!ctQ5zY`=nzeA|_XeKcBi;#Z5y(wg2_ffP0q$oY(+kiE{i@GLJ@y8i= zL)Px?@kLQEqnTA+(adr-(wbJ%8R>}K?@^-RTVe27)L$FvrAx|~X&E8(At@X-?Q z#&Po5SYB&7`Ix(^vGv73C6!=vDf+nmpbAfRW({u3v4iMu&<4LCpEzAM-C*$H7Wzzx%s(b z=xAQfJ)~zn16sWE9iDz8pz%i^3$0SOvO0S5NE4sP$uST z@Q`pFKOA3oKz>+#@M`?7H9NmZ@8Ny!^`IEM@4fe@@6goa9+QY47{bP>Oc>GN?G@Ng zHe(cup|u3<6z)k^?vvu-?U1cIlND9l3vHCJ1>7K=0MbWu4FLhkaTDD{Z0~T4TFy@=5$pH%`;SpXsf8gf@6 z7C8T5!{h0S{SzX5uCRuenNd@y-PoEnl>EF_V&e1hSyBCcM?ig(gdL_NzFM#cr*UHm z#EC}vpg{M-k57m?SCAn=-IwE?=N1)-&!DpC_`b7mKd9FfQ2psxi5RB-PK0p^6OJf1 z*X7;J5xccWJF}_5;xp>rru%$&Oib=*FK444nBj`<2(hUs`S?#YW)+uCk_? z4Y=p8Hox95V`1#mdN~sASmgJVSxo-tIBq<)fc1G@Q|*W#T{GGD^KlPx!q&-FPA#w! zoM7Ar{nqL1iewz_A`i-02=F;MUm`V-%SDgoF!nRzj^BJQb!Tl~`b!j_P_DQfd-+mq zHCjx~1Pxv3=$)H`S10`N<`%6ik5KQx_C@ge#O7-Jq#pWnmV>o3MLZ&fgrdYNS?fs9 zTGWBdC4mA0QyL2V#GeZI#ftO|z>dp%=xsWByISeWkJ=}84(-)bD57U3t_r!X#|_lm zKEg8SPL%7wh%yaz_adR4y>WB`h}=Sp(iTrH;o`DyFDQd%E|A=We>iW0-UXu8AYLRH=ZkFd}|*M6l2C+dvG| zP1HdnWFUyJN7cU4O+f)k9`ueU2n)Qu3|O2zY3SbjiWAF9E)v8{hGshEJLQ6>-fiSwD&_Nh#MIcqtz zK|%=$W?9tPZ^i|8s+D7xAQg*E+Na$z{73=+7ereZS!R3_IS*l~rO-R!yVx;HKI=5rAT1$0 z9Cujc+V#uqrLKh4a9^}DYbk)qkGeCp8Y&Utas3Wyr@-xou`#h_89s>5<)%UxJ^La@ z0_v88m5{mGhc}T3c6Irdyj2u9ZdEH>+8|Xis^+b8-E}JRdxu)vj*TSMok)h{L;UC@ z3`uo$RDBt?bD6+c0{R$11UQ7TXmTpI&Wi%@N_&*$YeV4?E zIM7-61g>h7mkiSv!hrcQsuGO-O=rvwXZDDQr_X)xvoX=h3^d&qu#DNo^l1--nYL)| zP!G;T@^b>ep{GP9f6yb+DB?#A!*mAJncUDQ?J~vW%-z8B#ThwzO#Tm@`kVH^c+q@aO z>>3$oGZ&QZ)Db27!+jyw)mWiHqwIKPxPJ6uAdfj!W`|;~wJkDBTBPU^NEiZ@RobG~R(zb;@#L z0#(P4JrUekk@fAHr47lOQOF?;k5$;(aAZT?j;}?d?jz|2SdS^{*&R~Y0KQ%er$Pd^ z3@q?aPcj(!q)J$bgKwFpbL>9tT2fS{h5LeT;WQTbWSbKsXyHg+wgR(zIWMhd%P-dI z>SUp%(;Z1Zd_?@H@d4zTExaX$-zuYF)jARraIMDX&ymdg?X0w1C?-P!Iw6k;jn0bgF{CG_;>&^F+5 zcRuv8^6B4IHsa$YS#G*;47c)Vgijcd`~6s>>hi_Td%&`^p@u5@nI%G43V)RBJ@IDJ z?d+8eQx1+vL`5#*XC;2MaWZm2jo(09ku;?=neClvGlr%cv3~p7ic-_w5XsGu0xj*` zggt^={n|LgjM_c#$;M)KXqAaDiAt}mCoamrIO`imN_J4W*ir+h|4`9KL|{3Qq; z)&b1Py1n|84Ku!Xu?w+rPWM%Os6msJMf}<@FWIfkC(Q_U6g2MasX2wS9B%f?g@4%o z2qVcUxH)_sjT?K-{DWY#w`!mG&&jml|2>)NVJ^-FyxpW9z5fkZKj#87WUiXuTn5Hv zcgFjM`F{2-uc|`saN-SN4p&G+j8L^aT`}nV2dz})8LOEqakneVV0a?ZY&0Eun@iPp z@CPuBO)n1D0OBn9g12;*zn|m%&?Y*2HTbcO#LWX}m9Dc``!}In zaO7RQu~FnVkFdhe?>q@29)Oa@F~pWnUKEkTs4x`t=L>q0$2f@GwF2^Ivj~T`&?6e? zPcq^QE*}G3HPn+8`<`H`fg6U!a0&u4r=1;wk?=2kYUs2+y{^PA1%?xoRhLqo!LvtZ zlY0!RM2w)@c!fg-HHbxuw4qc4SfweIrYV-|Pc2slG0Saee`1yfHT$gB*DBXExTs z^piPLE-)9tRUr`bu!Qh1!Y~2!cGW{^#n6a~#V^+8bXBOHVm?!`!-HJfQxyJPChXpT zHrIT*gwnNybg~DFm9>ss#!v??=1un`)b_3aw4_(+u5G^(3&u;WaM%)o7Z6{9&vzo~ zcqc0Z_%83cxG(CS&714<`-_ns%bFmceZvn;BpHXxsH_K3XL$#N>uwOA0A+Z&xU=Hs zl8wkw6kkw)emW*!tJKzQ!dAjeF`3m%&wB~&919o}8Z@~a97=}B@^5kQ-~KGJvSikP zf{$?VFM#L7n{qX&dH-$k8^?tIO+7ipAcO(Z&*mp0AfW5oGN1Js;6k3o^FS>pLgVJo zCBfF$Wy}zS6g`~Ck z{D=2(?#_ew@@diQpYO#mwLWZ8$hamBzbBQcH74B3xwQ0`$bl zqY`3~!1o(Po}mHxYHHt!^#xJ7p8|dtXA{89jd=u+J@N^OxUA2|kd*!{KJ0DcR0u+( zX_l%lH{0z>pm_sgMvxA^k&~f@nP*Q-9i@Q*sp_8-dX%!95Uwf7(A)DbqGW97K1w8Hxaj1%q=9Rz8+n7X7my7bGeEPd}5bzq_SRH4SU^uoR zU$|~pz(;abXrU=&5xiu|!p6jTS!&iHc>U2(z71_{SstH+-z$CE|nRZLRKn528==irQF8L zs@|lNxXwnFG@hsVXm~|gB8%^l^;gs?HeQp9ADui@Y4c(y#kd?S<R3Irw=FJ=mFqRA^b-1o zYda>kmP-BJ5Ox#7Q=NH}W9+;R@q5 z63*+J<^}yrAFQ`1RF{#SnJ@0d?dG^b^rP?O@?zt7 z<^Ou|)%4KwJ@IW!({7QkjAn;H;j43uZ3u%EAXBvBigELTC}P)d$Z@70Pq-%E!DeHfsB3#Jitfpi96>B946VFK@ZHDe4}6h64nN%M|z< zrS9AJ7NF&fpL*T!uR-v!1Q+5Sjsk5+)wfqp;^oHVQ~bz^qJM?)cU;HsDeMQu0+aRE z6#6$lmcOvVRrnh&qsa?Ixp-A__)1ogr$5j`8kmzY{1W;R-WLt{_3n{5(wxY4vByg@ z!;5S1s{Be_zSMubnigl>E0lPc{;<4DV`I#B72m9uT;VPyDVP-Fwu+SJE`WYq{YAdg z>fOLm)c{j!+HNQK0>`gJu&>w2XYNQzo^uELrNBSCetx{2#-x7Lb-EqSym+60el5e_ zOJdxXhbSDQO#*Q84@Ew}Le9xdPrmX=VKi)Q>avq`dmUx_R)LJ^V%<&x8kN4Qj^lrU zB&{Wn2g{Mnb^+_l+|j4ZiXeot^XWcPBAA^hrYcgx-zktNuXm@tOpOK&M1E^8E-VlotWq!8&grYutFPl+|CvZU0HUdG z7^UOngRde)Ce=}z{7_;VfC|7?5%eSBZJf4lAz^+4y#hVjsw4&}fJ)|%)l(L>2xNQ% zpKj+URaZ&AXV%?q;*0?;P6rUuOkX&`W#11p2?`LlTF0x=h*zA3KN4UYZe)cG$m+IH zhPDVep=8Vozch1RF+U&Q`!_C6!EDPD;7Ttbh6i;tJb}S4qILteoz_kqxh`8}+0{;wb{q5B~24 z(KsAVZ5guhK;VG71E6CA*NdKrk1GTuU;&`p{@BcMK;193k)MF8e8y?V|Kn+*6F2s3 zJ4a-*#ckcu&7T5qCI9tK$4B_yzmE?7%Zew>mHRjEWV{8m6yUmXb^83~jT=WcQ}KTq zv17U5KU_NY?=Eix8Ut{h#_X5+;LQ8mea4%AclPf-B30#pxNmlR+F~<70--qkZzCjW z_7*7t_C{JZP0F+jLqhQ;Q?j{`C*m8fS6_}(`Y3ovEJB}J1z+ORhl2dV9n_bHa*_Pe zj);g6lHdDZOr>r`!WSNQv1#bHtGvc_n7E^5>rOl7yc^-{#+Zp;odQWz7e1ArFF6Z& z$mO!NiOl;w6%~BVX}+|Ls?~G%Kkvidd&SMWC*}(A*~pk=c+cB~l!WNVSr8E^4koG~v z^}GIl&I3*_ND^wrIhSBYJu$2=1D^Lf=PuhvmUKVVTl{e3Z#4BPP$^6hj>f07uxpk} zNRPi+9<7rc5gYDz5x2KvxoLbmbdx19FU7vF=WpnwM)cY^myYo~jYIv8FD8>u`c3<( zo6((r9Vtsby-{NT$kI}&>S^t3zl^K;D&2+()v==HUw^Uqq`{r`XKg|0T4hw#l7G)( zG^HiLkthsB2iY^;pz+rXPg+YOKd0#%;rqD}Czy*$qI^H-C?uU@!SS0Rua&FE0UvH65Y1?Zgthvm~L`=%DlJxumd#-;dTVYgepI<7cU>4 z%ehc^=q&y_``rmUb{X}XuVDdGV_CJxwV@fbZd!n*SQmxia(4v|Uxr6|9O{DnENW5P zC_4Uexe5@ANJI9qKB=gWO;bbS?!4u3BT|E ztO#MMcVD&|EU``M`VPV3hkO~fP3|ICkW>Ft?l;CvkrzIwfYah)eMMp%5LoxR3jW-m zJo0%o4g(EYB6b%lJGYLnm1b(UJ$yT8A>)iKH0Q~ZyRQYD_zeaM0sN8Vj`;^Ayy|{h zP=m_YN>`M+w&xBU>t0~=F^PMJSX3*2=O$bgJQ{xJjyg$tMw)LilsHPos8@C}Y^4-umGC=Y&Ep(eTSXqWoeiY63he zB`9?Te}8T_K`>M(ENt7Ic=rR%57(^%8*5A0>BVS{MAoCF2 z>)%c$mS=U*^PuO|x1^T~-+!QCNGe*6B5po5eV?F8i{j{n32%@}q zG58{;9ee4HLD}a>v4fM+5RXl`H+FS$Mto)y^3W|;lNrfekh_Pnf0M}NU{*8n@TA0W z|G^jvp7%h?52_&CamF%gXWLL7K?0#ceD{jq`BVvniJ!XftGdJkhjS;B56rt;jUE4{ z{w1x)nJwrQ&S12E8M$#rufI^%(BI#mGXJ9Drugk$P;t+oo;9?~UiBkiqO44?o`VQeB}k6!-T_mLV^mCz1#c4)J|-;# z;({l89vzAOVN!2xUTnk-TPZtN&g~3K-%;~fUkU4Dy)Gu{BG3ycpkD`7R6?vZ#TSzm z{G3KraeIn%UKGcX6Rw`xzdswU+V@s}wZ7@%ewi!b5Y$t`_yX)>6eyT><=STCj`%0!4Nku=dx>Y{yL2x&X(>mJi@jB za_xqe*z|?~8$L0+nBTv!n!>213gHgV{#+a`L%Xl%Ep*B9A7 z>vCtuhLFE->(3ulK&%|d`{p**cRsv>6<-bOo5$6q~lO*oj-M-x63 zQ*ivjDfo2^?Gyj>Eh!YldrV0pajHS;%g|A3cuqM4Y}U)UIMw*U;!Q5x;EhDgMmqW@ zCqWZM{K~)Ax_CA>3L6CR#SHXx+N3|_H+w4f&(DuYsz@!Ej#!n7kDf@|)6+DxOV5ZT zycXd6UWNvg$mt)dE52#bOV=1n=x|q&XV2^b;J)R4%F|d-)}4e=S)i@8jK%W=&u$Y| zN*OAQJmPzD=Qo}6?r%1$fUeU@U_1cYM?PKd5tzO8vo%c-jR z3OQFJWBS1{XhNpMyNlCnwp+?*m z>*5kfiffi0RZe|s&8f%9?N2wE!M?C{FMcEDitNG2sb@odzpkMBFhqqYaCD$2lel+$ z-WYFjYE3Rrm;gn34XEvVus2==wjdwnuK7Yv_oQgZVk+_ZX=+?WY7lAnM&uIDIC+rp z2~Uv5x0lb;*{l#k^rz1rN4@6DR9@<75$moc;|x}ETN0AhbEvFdc$Cg3r5?p98l( zR63tWv&liwd}F$i3-csc74?J0p`yGYHLu-GoZc52%WXNdw5D0%8^yweg26*rlilEI zeKC+PZN1MeK?V&RHAc5~N2$!kSbgjWFZ>CfCE2$hpXIy6eIE+Zt9?GxO1ES&|vPJ;L^M zs)urE$zu1OUGBi(i#y+VIB;CinBgL5JAA-#!p?8M5v%1kmsv znEn{M+T>c3)b*d&kjOKUa(hmXBC2r6 zktH+6SJ@I(9rt_IJ1u)4e?UxqI%p!o(y|IG`0agaA!YXZ8UeJ=hKQM70_C6QkI!EN zxhoG1gD<4b4WAvtfHWv75Vh?nNan+`7S&Suf^fxdByRDi(1P7-2@bD%@4R7;&0&xZ zPHtkM5N1)8&k8MG_{Sfe(1R|Z;*PRRg#)oJ^eyV7!+5u+S2T?scma$7GD+`_N{u>sx zk=+Fj=>Lm9W`zC!+DYpl0&;fA?60!&S4jGD9iaZeb>r&4dEWndGyi9n9MHG!tB6ue zEmZMxfVu|>#XYhu>bDzjb+z64H=+k_IuC+a#a?Z3kG7X690&cSX1DeGN2&ju<8d6k`W{UFoY{6qEs`kF?W=<)V)Fvr7gyzbK5 zqw;yLpKt2F0ynzf{Kv2hR78sE;)G|z6*xEtNk%+G&aJMG%Y z`SUMRuQ?!|{A>7=3XrS+GIc*n;^bd`m=Qt{j`%wZjQ+=NvtI;S8ePUMx5$tl$DcC@ z!pR+jGMIj}jnjAn#o+{D_Z`l>EU}`WZ-)yljH*^LQ+Kw}Q3s{cAvCD+cZq=&ZT40VASd>$X{St>4x~8c)+l6*iLekjt?LlFSaLj=Tz9@(R76O(7r?y@Ff~t zZ1{LMIsoQV-o-neUZR}mnt|;!>O`n>!fO#^6A@@UfD0b&k)Uyag_~IjD&4Q%9 zdhGrQs*m@PC*S6Edqxp-Qm$Y_k`TpsuWezEp;wBB>-92tfv?W8(DKuoIk^#)U$IPf zWMKkm;JKRC={`?$EUnv}>Q>q&C{v^Ou^@ZVzUZ}t;;j1yi98*5WPn{Ck!=2c+QS_3 z@rnzI=r{=Ge{GIie&`Y#sS%53jgZ<>(0$7%E0uwE9 z!TZf9!f!{wK(@ZRkL@Ci_4C_>vNG~3KT0Q&v+U|^{g3i%a25f*ZD=ihpt9I^Wbj^} z_7rE7F`?DsGmyFx`eT7%xVBc^`jP+bVN0OrX@CjOJIZ+up3J|j`iJbAkYTgpvhX!a z!OZRLpl*fyCiT^RN8z^8(Xh8%u~CGJP@f8*$L0n}LeXK~6@(MFDSk3{{18wBFb zYbmC;mGj}Ecqv*k4fQupN_6gfIBYomfFwbox~^NLO^KZ0XPwMwvqiHfGW>0g z4l*VMc^H?myjHvQil}5tyz)RJ=S-kkpK~N5Qf+8tShu&BQ_>axom7Tv18yGO%Q*8OF;WmJyYHHf3>6|y~Zm1 zk2G=`FgZ5d+k?@0uFPPx3+zDkhD2UgirXhPxE zXHS@iOUVL;Ho|D(V;9VuIYb*(8?60;tLL5(lQISV{RFGVo=QvgJW9~QLSZjUsxOTD z(z9~9*&-bg%QQ1n4ZqS~Y-#=F+0TZ38x}fM>TN~N#N}yf<`~LEwVvCKIJ1I+(nm48 z@Q*+v`$hItNJ(g;)C^*=^r)iHxQ#RfbMR7 zLOcz^tNN^CV@u5ei!DZSy^^_*cwlA*~rkFj%9;l+V(^3|uu^rSD4 zQFv-~y%(0zG>+aE4gNZea=|(A8%PIsBneg;x8C9XyBtK#h=$}z4G&| zXS7t8K)yj-Kx|12K=LaZRLMLB3R}hv3U%Zob!6&}4Cft7VuEcp#5h}@F*SaozC8&q zSNtGplx+boh+kNXjeGa>GYV=wg>PO|)R39F$mognN#keA`ZufMhn+(%`DZEjgr+a1 zqn|W9pZDUv!ICfBDDXUT`mV&qXPBoLhcmQvmRfWQOrmAbk2hqU%~=ph(jZ>2sa%}2 zSjKp?JVPY+ONqK-8!&Ajm1mfB$1Vt6_1_KIIK?eMa6;803TNPYP*MVxQLw%$W2owZ zPxCR1iFugkQAe#fXlXd2ZFe-VLFkt7Hoe-Z?Fjj41|-_dCw$L-j-9W8BTy4o^!U-^ z*08hQyFh~-W8@A$AGE0HI)q{0PP`V$p#Vv*Df8o<8FG_`8Qi z!k0k(mRRcBQ^jQpQwGl_6>?q@(_R!;gDy2F@Ufo(oTa}WjSQ~nV?{_TYTUQ9q%Yqo zx1+inGuPHo#XWXY-Vzc^5@X8Qs%X{BisHlQIPP}JBT)9`jYIF!J!biqmF~_1X5^nW z^cpv_#)Mf7ni={?dv4fu={2@cBbcU@r$oIx)R*r(kD|EyRsQOKm+G>3vUgC-20DISljxoPAhV3(p1ox^eR2q3etpMq(BrU56Sp{t88`2tekqXEx1Z zkgi+tu;vNlDa55d1-x%?vd`tix_D;d$YIU)@*0UDcp8-Ze4xlJn6*2|LL;Bz2Cguq z{D8UPeTK$8XQp*yoOuCCmTS$npn5*%{fTb(5r)mEEShXWJmGC++wfeq1}@IKFQNb4 zKXJ(k;cc7Yiyi?ZUC*GPv#Lnjp@x>#@f}!6Ues)Ap?zCYA?FE9Gq+6+F!~?!R)evO zTB6f8g%dMVr4$3@3KV4dp?Sq9J7#wa=T>_;SEBHm2p=Rff*1=F+KE`cFN{e~`t`Ta z%L=V}p z9o(8fv~rZ~VixN`UlNPOTK!=L+ZxPHGY* zHlr+kdQ^hgh}SUY+E$?2U+A!)T?hM5hR+3x`Ric(s1*9jN!Rteh)Xv!;XJnL<}>f47C4jc-VZT!ZtCJpic#|aDjH<+j%Dh+$Z~yw ztP&yCVodj9&ga|CScdE)WCftl9!red6L?0Ipt$d8wW#I8@b@CQRV_}txz(I82B4;> zjhrg}ApN5k6DbjN#{kc2&E&2;UmB9SUaJdo&xLtk41S|W6K<|d#imy~kE(DydK}rU zI((VaGE4R6*;vte(Nt!y;*J0d1N_{;^#(>z>J`I#n*L`YA1Dm1>xk9e%Y${=Zn1nB zfbf)^YT;m#MCsF&3ioBzmnOfiAv8w@X$DUXiY*nr5QY(hM!STK)E|1kc%Z|Wp_ts~ zl5`kC@6Lapk3~@bj4lAmYRGq;9a#q&Ic(v)g#(w}TB6YP4{H1Btj?S)E(O zr8ez9waeg-`YMH!9F%Bg8V7MW5_WGpM-$NDB-6#Z#2tzW)cj)aN93@+c}CD=YN3q< z?SxS8@(#w6Nz0ttfjV+&29FgxHq>3}ljEld8<_iUZ?%>^!df3l?=d+~)aIgepld={ z@8^i`h@$BiW48STBr$K51eV+KOL#IDy0rqqGEX?+dfhESj^?bQilM0r^=G~jzuSC^ zBtaf6?>tq?{6+0)sApCAu@v;u8q_Fz&#yw(`tqh3UoNzJAC{_+=H3FQN8bp!I-oFT z_d2L4QB&A%%c$DoVB=w{d9)$-UXTpW)ev*y5T{Is!Ocui?7{el>^;G$U+NxD?OXNL zoMA|qHksGk(?5D!)wArD`FkG0(&5c(+ajj$aQnbaFmdqreJU3TI9R3T=r+VMs5n0bR z<)3g#F|$6N4(?uWdQw~ROOL{o120Hd9QvfWqn}HMq{*mg+hZxW8lOi$ThNEZ*_+~r z4&k~!-u5LKmhSodn~@yq-*(EZCeQ5pkWvc@+O5kD&OU5hH)%*^UudZ3yThh!2 z$bQ~S>FyQObT4Sw36O&m)N8-!GzGz#>mwDl4qiW#b3OKAHV-S>wSj=W;Qgu(oFW@5 zg`!cK(r2J2Uqr6hmw)N_5el&Ixv2*v*!tatJKGotO3)KGel_0GDb;f+73|d&aNG`Z zNBZmcJHbxSnV$CU$nZy3h>^OsebOVNpRt~%_%*QirOVGcrLMfuQ{ew$TD!WvR=ji9 zz8K8Mk_@MPd`cDDT}jCKbqnuR=|3~C{HV7kibgBrDx)gO1B&-i5}uPVnVD|QC(g;c z49k2iPhteb_D7_?(1t$rtwH?KvogtrL(^aHL%nH58Qdi)bx2aCO}`v; z)7?joKQbL@(@?&F^s=7Dos<4)a%NsNYrtHOcpwA8%Idju`q^oh3>05<#Dcff79D(f z6nTFR;*xcSq3exvGzr1koZ%ap;D<6KlIzc&k=RXRLMX8AKN*T9Ri)a(+Tfq za+cAh%8P5YsxM0>ej&@|aLCTU^G>+v6G0vHEMItxoX!qo14e*Sypl>+fjiIT^(lO` z$AVQ(Z#Pf;Pea?SBt~)w_j5xOFyp_SQfrqOOzLPU0UsG{{L}K|oC#ZAhoQgl*0FSS z)!I?4A8SwoztFGhY`10AXgBabG!G@-I(=qmP(ikGuPHYvjW^|pDA{kl1@!&SiG@8o z`$dTr0<}XkuehVA2E~zg52+eyX4*C}^s6Lr2m!WmL)9%+Bkba&^~LZ!KfJ0>MdbE# z(1GZEl$m$ahHvjXhp?`90W`==_w^0aRV@$YYGspyotif@xcUQ2Hobd}-luE#86#bb zaVo&1wjvg_wtZ)Z_)b?3g4cZ3#6%LGk(8ukW7oKIciB2%iIC_8^c+=16^g=KzH$?L z$1wjnJy#Nym~GHKZ)krvfN}(?Fq&PD=`BQ91}m$rw=0e?3@gyJ??n_!Kq^6L5SNCc z&z%O!!Nf}Wst%Ngd(i!BKlZ0OoRm-|nq;*fL~8En`VQf!07s7xT*@w-!6Xf8l&pNr z)|?Y?#t>W`j=uZNg{0|3hDPL=vhoQatQh$0fO4hx10|1DE8kOz zw<-t_o+)?G!HJhvSU}!tO%3?4Kme`XqhIS!a}p|Kv}p=sd^G8(uhkwN--;X%ZrXm6 zTD0r#hq~&^A4D$QFMuo*Ke+0;%gHwVOwilg@qAZ5C1;gi1T^hS{vZ9%h6h`62QF1g zbh+G%r~Y|#f!h)Hu=AVnw{n}~R=H!WNOzwQth=Mco;D*vVo}^~XN21%NMp$<2-8)r zbAQk5X`y%QlcefJ?+UCYv26g@C@uf7xHn4B_--n* zz`F1pd`sgEUy?Ao8dq79Z+4gab1E=EcHO{zU5h0aB(j@Q#&z?xzsPIKOW<4rQ|Mg1fOahG`e`U2%I{$v!3ZS@S(Gn zd1Njsl=(Hi3aR~0*@>`2MinmqbirQ1ja7k@8s#`W zjv6;z!q;UoCujkCW;b~0>y#4dAVI}H(ry-h>Ce8Q)g!jZ&vS@TaL8?>E?>m2p?P-d;vK}LI7l7@rtuHRqbc4*`2$RXh0d{E79b!Qh z-QyROKRRcm_HgK~=dBuV$*Wb^JdhnKQZV(cct5~A;1feFMJE+5Ydn=Yk$5Y{J;R)P zB!qbH%2}zI{xjO3>cgKIWL=+3jbHf*R41dX8qaoh)GN1-K7Cg{!X}e%yTZd~1E~9g z#G8VwziDVEG{t2Aad%n{L_s(I*Ut++CUjL1T|X@je+5lH-1loAWx}H;o#YhV z=JmjlS8W_aznJ7pVqEP`=v&{GaOo$`J~`C^r*qppJByoV3+Q9I!Kn?&$1JH?`NUI? zs%G4>(KpX*1Ud5HYM5!C(LSuonZDNnC11HNUi&|!z%Sj0JnHSHz$DX_EkHSldLHW8 zNKf6__4Z!>mYCsN)M_yKlV=41_3KtvQpaOr5Pi|Q@~01d%S^~YNe)`0XLu$pMfcg) zVFfO>Wj&(pnOnBar85rOxadxA^|vm{F)nBs0Eb(Eb-I64h1gl)Q+k*O?Vn$5pP}5A zD;zL^jhw&Ul#^EN`1;j=55^B97iVKZKnJ2g&sBymqVi!b0KW3;cQvD^>{$**2=G1MMbbaVAPs z;dvK=vmS~VSPw*6>rZEW$peG|4Kb4PYwn>29pQOJa46qEQtP~%!ostx*h{nk9^ITE zb@bXYftr@&+n}GhduAY-E;dBj=4`AgeJizz=hg5~{q8dbWdC!C)Ju+Exv%ePVsLYV znC#{AGLJQuE9M`Nf299-{@%852L=N17ZVgACzlPUopVwAfawWFWUK8whLjFfD>?t8 zL`gQd)RdlQJyXz9`CG_f`(_b%qQ%Uv`Hh}Z=7F$LQfBsOgylGL`Q;M3Ei2_kJsy4n z-*LiY;m5qF;;ThiopSSm>-zwjt?;1)MO5_7e5{>1xbua70l1PK?$(=2dM9-^bmnlE zdnvWsxF44@5Cq>TFn`IdCtl;bX9|LP#R1eXEMuw703z%j8-^kG>9rO0J-@8_Q?3b4 z)$@cp%WU6_?KfM6B9_(t2LD^5s$KL7{wSSw)t99TiMmLe{~-NB9sj}S>#GzJ_r+ON z7jP@01oiU*zY?Yr_Azea&hcX#U=7jgqa`ydJY?2;JCwMaDbA*ydiDG>Xz}83>L^{u zbM(#kqwsjO1?gJ*+1@^9Xppt+KO_8Jjs zllo_%3Zyb0UY@}3b5OVC`k<_&BdFk##}a*Go9H~ry0_1=aXF~NC2TR3wes>$;nfHF z$~2lI-m4UbS0*53C`7YSP=!hVn-CrCL%Z14rBDEgR zm$2X=Mf2^29&}M%l2Ud@JrRcYyZqHE=e_}r2c?v!o8<9%##(?wI^$3Uo>FPc%0UVKwnDx;n> zgjemWd-RI`v@3}Jo+e|oBs;Z^n>{6k4LucoPu`JcQoP5@F@_h>7U&jQn)hP2+drpg zks;*M`54{10s_(H!%duv41HKn&XR4Z^u7Vv5`$>gVt;n~Z}o%z*a}xDc~D9JP!T0B zACf21UI9mUQN=>2Ddy@BevXTK7;MjH6w&o$^n}xEM1onP_dcs@u7*Tc6V*1c;Z@bt zHRISs=EBrcEjjBbj?q@JszR}|=%N1O9a-ebf2@4vkKfBM_cdnwk#O}6HqE)}fzI^~ zR>8^A=+QU3MUt4-1+3}Nb3qdf2SDe<@QnU1;@&f$sjk}^#a>WQQL%uC2#7QR0qH6# z9hBaK^d6H`E-$t^F|pspZ4_{G*c0ykJ{R4I^_xYKjlfH zw7S=Al1`JJlCdhJI|saiK&4NdgnwUad!915_M!e@Q(4H4;by~%ZTk?xZ#Pk0Evq3a zY(QnDZCJXm`~~|CX-ZM(Z@RTo)+Qog%>(j~cH5u0brqG-?JHFh>fDtln=maSICWjn zx}jQUIzyq0bZmGeky@K|Z6{Ce8lcC2>$W6I*GoHOn)p`6LwP3yM_x}b!lBJZ9_BiC zu7meov>)BHtRFuU?zX;{jgk2ryPj%PyE?L%{8$+a@HQK3J-L}$^+)wh2?cPb;%rdJ z^Db{`RNqxQeho(~>kH)l`$IMeZBNb}bI7KA-@ra?kLn(74VrBL*7T@<~5yGA)Aa^`)@1Jk06;EKrp30Z4+~gVf81Vl6PMpU}i2 zC}UUiL!{n|m*l4d%bOul*A_eE@4clx-tpeag%!1>5t~$+t<_~1_v0k`s%s{!>*?J8 zoR$ybAG{AiE`;~8C7-#k6|Js(qsNyfa)7y7Fm2CAEO8MUJ1Jvo&$Ri@43#PQBQ}dr z$TdUTe{`7P&6x%53CMuua}0U3DN$_Hy>TcCvV^d2a-E*J1l8QWco?TfhE;1l! zHnijG8y#}GOPe3YKe`b2vqqcm0bo0k<1{LKRJ43ZCA*ZP86Q!tUt+Ic=2a)^rHoA^ zTX@sf8?`CH(>-Ai(ncv|r)y}ZR`((_N3f7{g{dCd3JsM3MDerk0qFNOG^Cv!Q$pA2 zuG^({Bz6{FV0n?}VDXsV2^KSxA)L#Z5u#dd<}ViT4NuoMqMys<7gS2GxRvP6>~nT; zK5Y%4j4B>y|lC%O!N`mz@HJNBtfJ!wE%P&F&;`0|bc=kUe-TV9i6KnzjV*DtfH^C z1+(sCH$T)Bdr1iM)=cB5OuojWV6`k~5-&@Hb2T`P@S-r8(T=s~ak(w^7KFw%i9*;% zGxcimA9qLJfX*AKk@#$yhHqchLiZ2feV5uWs5f{mog3-ro7nx)3tcR=+F++wiOjH$ zh((F$)riDA`|L|l|D**m%g@WJ$RzrE^2Q8%m1|BkfG?e|939@1-}F0Z1~<^xuSO^(Z-8&mzZfWQ3SvM6E$Wi-`f^cMvcncgcao#mm?0(dKU?i>*%NQ zXxY9AUgcGo{maD)dQKTT%<~RR^Y@ypj+dVC7CZ6CBjuzVWS5*RA21`8lD26a3YLQ_ zjLf6vxLd$8Gv~^5)mA$#I0p`bx2QS|UatrCr1$U5F+)Ja{+|P9)4S^5mA+kO5C+l~ zrC7=FSO98&@7J3Oaff*>%t;O*PD0Z5ZaW17WQ(X+oY>!DvnvY!wcP9fxcu;6#Lxe6 zg`rd&1+kBZ6A*OT=6pvMFfYIZ{qTwH`P8QY5|5;LMG=OkUjYX!;C1x^r!g-bmQLZ2 z^RvEu_0R9D)sLb9=Rtl-%r|Fm7@GkTrlu+ zwasbEZaa#~c1J}7nMC9n^RGs(6_s#!|MqnFpaKg65J^M)WE1ZWOMncsSYzAa@OBCQ z=(g=r10J;pOuz`w$FzShQ&az?E}i$`Gk*Ud$>RL}A%-_vy~iMCmKCVew?)=h#W~ki)f78}>@;sw!460HU9U-q&#)mfF#JT<)xZ)drSNVY9&F0p+;KFm*CFNUjuX)h7QE7k1@%ryLw#%M+^{D&VI({lR zdfn+BVAvFzGOy5u_IG>fTYEKHW6B2IGbRU;xXOZlyA6ZZ@yQD-fP2Fi(`>pNX4 zC6Q~0On^rky0+-Q9c~}u@|d95GK?>Y!mEe3qZI?f&njIzv##W`85vNE8v#Y2 z2s6ycGFmmC+1J%RC3UdGO%-U=n@lan3!ataNDkF;x&6Ajsd!5p7f8Gkg9~46*kR8< z(3p+=#{G=g^gI!mp?`g47?SV^d*bKvcH~#XM(Q`;cV|o|uSc=EIB*it+RbJm1^GRv zV)$=h@Y~EBR{uUl8MZ;vE#MrsLBzUf)89W5n!EJE-^s8 z8AKj+>e)jwEUNwd_SzH-2dInJYgL+CSX*x{u1cIPIQpcE!8w#psLJ z`zA9lz!6Q#T9*X^;FHDau+NNL98!SJ_EQ+xfYYJi3*KjY$^zVRe)_>x{YvDtm-|v* zXX}IkwKeXuQS5Eet9IYYN*^@ey{z9ZE*Xp#+MlT^R13yd^V!@dS8x$|AbtZ>1l zyBv3k5dVBx{`%KQogP;#>oaM7CnBi8bVFtSZF@YW$5@n!s!eE7bT={r8D8*$i6`M=T=70O0Gr8;2IXtGNc^{IdH6^>4-L(TW+ifg<<-ZNu{t-qG+ zbt_<(dDqBl)@1h&8c#JbQ0wZ?>VIt9A{EP><5dj-xjSmMkl}K6B@g z5rt~ccToofR$-uf6`u7=kaie}R}|X8UkroZ|K!t*S96%Pt%p#b{YAUCDC|qkm+rYP+Rs z7=tB;$%QXu;fhZ&ja=;R&`Rlac_#G1$gW04!RRI{AGF}oSkvS29my2WQTvdE9m{Ga zqMC5ZAr$|hXn4HepwXTf1vdbee5Yw%9GUE&IaJW>d2+@^?&bheSk!;aMm$uh>5|&u zqxaS(0#ldoG18rjb3t-x_8;W{>#L^iOeB$k{z5^ni4rM7x9_6SGn z__we2V|Yf#GbQuHuU`$v3TFFK^j5NN`-2%(F%wzRy0^tSYdx zC+(}gHH*q^GBGI8cB<$$N-sUQzThz^?GVP5Vzn9DWH1=~%ahqnxR3^4)E^Kc{;u=k%pIJ}fkWru623ZbCQJ<17F=HO!)<;zg&hf@~JrKgxbjl)L&>6+m zvEI#E4b0A;D?s!jb%#&x=!-A~K2iFoXIP~-!lmJEb~HOWcDm4Xj`R46UHfzlARmz9 zJfigM*)t`)XGV--?y@ZOjbw~OW61@=1p@}j%qi8WWl_5Q*T*3cy8x-D{0!cu8N3-D zTGQPdc++*j>+?~Nwfy9{{g^A!h?%GCd5lh`Qr}T*nXk;e?@dmb>X_&Z3>GEaBi0<0 zdY!g~m9(;91QT2t?=K-3$#6{2!3z7X4GiPWN#wdF3!~%f1&hKhooeuM!{dVimIUmD zn9$mS-jxOWr~VTp`ycVan?8NHEOUI9>cds%iX>c$Sj!wot6wx0`luDvPd1tSBz>JT zJF9^z(ICNX1cXbNPcbb2c2DKb+1L7TtY}aDiMMatqrj~EW9Q<`Dl$Df@Gkpk?q`05 zs_lwRvL&AIh0gZSA*~eT?Wf#IYd?Q7N5+SdLQmPa87W-28Y!#kS*s-{J0kUpkSXs<0+#E0>kgT`)fa#OGzn8^UOD*HkN((aYlr1%@Fmi$ z#@g_^_ibrPP2$%XOI9f^(lPJ34Kuz0s2j5EdaYzxG;dSM`vYvj^Vz8x?k;Lmbxz1I zi7MeO$|^PHCkk!ZS%9}3TnZobp=hB%-x`bOJaFYcCTv#$YvLa%XTaFiG0WweH%-m@ zil1(ZDtv88qwHU=?HF+`se-O52^sPdNzMM7I93wN$~(%(^$zP>!!iCkdQp&P;-}9A z1thv&{8iy(rVE_d^v|u`ttFg?1+-$E=Fr~{n-&{a=PnS5*uJHu zl7INmjKBL#^O?iUuI8f#{>!;ns6P2R5!0MUekgw(P*=63{d5W=w3icH zz4Ct^7Lz3^usM%cXxc*dL8fk2ss6dP?pOoBI_;z+nfU~+fbEXs^6R+6O|a>B2LHAW zyyGSZbFa=L1KptA{V3i=S{83kisqVWV5gB{O+F`&wLYuifCwr1QvHB6Ee2cS7<1Sr zZ*sPZ7h9ls>edVNepVQs0v0do*%}bUEGgSnH{Jv_PwFw=^*k*awzoWjJkJ8Z%r4sT z3HbOvyGYZVELcc?>&}QXNN`7oTwPiQ$GW~Rk4jTN``1F#B=GOHl@lAv~yBrWzTnXHt zgo*wq{Avsv1fv(OgkFbn^hIy^LE@uHMo#fT^Ll$3@2=4bdRt3he@ZW8{%9%F3saI0 zas~rdURZEeo@>0UKa}735LLEAeBsfFz;BPyx*QKqs>+W&#FC3O0jFRy-6!F{6Sf>A zRjJq1-oZ%*vvf`8DOv2umf`mqagj#%himBpP~2DXAFUJ99@8xF{ix#}GvwxbaTn%u zqk$cRPZUwBU(5&=o)`aFZ|8W~j#d?M_s39zR}XX8F7?~`gF8CY*HL>OvHZmS3tzaC z)SCF@UMr_b(6eAOOTjyj#bb7T<5f!rjW=ewNmA@8Yzl?aD`k~*^_R1fdL#l@hhDC=+(f1LD;l2MpCn883krPe6QoCXfL&Q81A9%QraC- zz4s+pn5ghe$t5-N)NvFWj-Wj;5>Fv%oNiNGWeAOJ9y^u``?L8$#&_VQI0J=J$1l

ezP!ao7zC3c+FPW;OWW@E+rMw9 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 literal 0 HcmV?d00001 diff --git a/express/public/images/Napredno_iskanje.png b/express/public/images/Napredno_iskanje.png new file mode 100644 index 0000000000000000000000000000000000000000..7d7be3a5a927f4458f7d170b74a59e642536a2da GIT binary patch literal 10126 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 KRIT_==>Gyt9}r*w literal 0 HcmV?d00001 diff --git a/express/public/images/Vnosno_polje.png b/express/public/images/Vnosno_polje.png new file mode 100644 index 0000000000000000000000000000000000000000..67676809f12e83e395430c1e38000e01f33b7ad7 GIT binary patch literal 2908 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 + + + + + + + diff --git a/express/public/images/alert-circle-modal.svg b/express/public/images/alert-circle-modal.svg new file mode 100644 index 0000000..7b99d41 --- /dev/null +++ b/express/public/images/alert-circle-modal.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/express/public/images/alert-circle.svg b/express/public/images/alert-circle.svg new file mode 100644 index 0000000..711170d --- /dev/null +++ b/express/public/images/alert-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/alert-triangle-dark-red.svg b/express/public/images/alert-triangle-dark-red.svg new file mode 100644 index 0000000..47b7f12 --- /dev/null +++ b/express/public/images/alert-triangle-dark-red.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/alert-triangle.svg b/express/public/images/alert-triangle.svg new file mode 100644 index 0000000..fe0163f --- /dev/null +++ b/express/public/images/alert-triangle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/areas.svg b/express/public/images/areas.svg new file mode 100644 index 0000000..9a3d2ed --- /dev/null +++ b/express/public/images/areas.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/express/public/images/arrow_drop_down.svg b/express/public/images/arrow_drop_down.svg new file mode 100644 index 0000000..af76db0 --- /dev/null +++ b/express/public/images/arrow_drop_down.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/express/public/images/arrow_drop_up.svg b/express/public/images/arrow_drop_up.svg new file mode 100644 index 0000000..52bb27f --- /dev/null +++ b/express/public/images/arrow_drop_up.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/express/public/images/book-colorized.svg b/express/public/images/book-colorized.svg new file mode 100644 index 0000000..1c94929 --- /dev/null +++ b/express/public/images/book-colorized.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/book-open-blue.svg b/express/public/images/book-open-blue.svg new file mode 100644 index 0000000..9c577af --- /dev/null +++ b/express/public/images/book-open-blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/book-open-white.svg b/express/public/images/book-open-white.svg new file mode 100644 index 0000000..c00ad09 --- /dev/null +++ b/express/public/images/book-open-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/book-open.svg b/express/public/images/book-open.svg new file mode 100644 index 0000000..320d0f0 --- /dev/null +++ b/express/public/images/book-open.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/book-white.svg b/express/public/images/book-white.svg new file mode 100644 index 0000000..14aa1b2 --- /dev/null +++ b/express/public/images/book-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/book.svg b/express/public/images/book.svg new file mode 100644 index 0000000..d0b46ca --- /dev/null +++ b/express/public/images/book.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/burger-menu-button-icon.svg b/express/public/images/burger-menu-button-icon.svg new file mode 100644 index 0000000..d35ca57 --- /dev/null +++ b/express/public/images/burger-menu-button-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/check-circle.svg b/express/public/images/check-circle.svg new file mode 100644 index 0000000..44b60b6 --- /dev/null +++ b/express/public/images/check-circle.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/chevron-double-left.svg b/express/public/images/chevron-double-left.svg new file mode 100644 index 0000000..8a27f82 --- /dev/null +++ b/express/public/images/chevron-double-left.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/express/public/images/chevron-double-right.svg b/express/public/images/chevron-double-right.svg new file mode 100644 index 0000000..c6b045b --- /dev/null +++ b/express/public/images/chevron-double-right.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/express/public/images/chevron-down-darker.svg b/express/public/images/chevron-down-darker.svg new file mode 100644 index 0000000..5aadfce --- /dev/null +++ b/express/public/images/chevron-down-darker.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevron-down.svg b/express/public/images/chevron-down.svg new file mode 100644 index 0000000..e8bec02 --- /dev/null +++ b/express/public/images/chevron-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevron-left-blue.svg b/express/public/images/chevron-left-blue.svg new file mode 100644 index 0000000..aaf0b42 --- /dev/null +++ b/express/public/images/chevron-left-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevron-left.svg b/express/public/images/chevron-left.svg new file mode 100644 index 0000000..6825b68 --- /dev/null +++ b/express/public/images/chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevron-right-2.svg b/express/public/images/chevron-right-2.svg new file mode 100644 index 0000000..4be70e4 --- /dev/null +++ b/express/public/images/chevron-right-2.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevron-right.svg b/express/public/images/chevron-right.svg new file mode 100644 index 0000000..424b5d0 --- /dev/null +++ b/express/public/images/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/chevrons-left.svg b/express/public/images/chevrons-left.svg new file mode 100644 index 0000000..45e7067 --- /dev/null +++ b/express/public/images/chevrons-left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/clock.svg b/express/public/images/clock.svg new file mode 100644 index 0000000..3dda17a --- /dev/null +++ b/express/public/images/clock.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/cog-blue.svg b/express/public/images/cog-blue.svg new file mode 100644 index 0000000..f626f99 --- /dev/null +++ b/express/public/images/cog-blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/cog.svg b/express/public/images/cog.svg new file mode 100644 index 0000000..a6da6aa --- /dev/null +++ b/express/public/images/cog.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/comment.svg b/express/public/images/comment.svg new file mode 100644 index 0000000..3211efe --- /dev/null +++ b/express/public/images/comment.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/copy.svg b/express/public/images/copy.svg new file mode 100644 index 0000000..3b59c46 --- /dev/null +++ b/express/public/images/copy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/download.svg b/express/public/images/download.svg new file mode 100644 index 0000000..892fe95 --- /dev/null +++ b/express/public/images/download.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/dropdown.svg b/express/public/images/dropdown.svg new file mode 100644 index 0000000..e121858 --- /dev/null +++ b/express/public/images/dropdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/edit-blue.svg b/express/public/images/edit-blue.svg new file mode 100644 index 0000000..a5d6dd0 --- /dev/null +++ b/express/public/images/edit-blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/edit.svg b/express/public/images/edit.svg new file mode 100644 index 0000000..d7765a0 --- /dev/null +++ b/express/public/images/edit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/exclamation-triangle-red.svg b/express/public/images/exclamation-triangle-red.svg new file mode 100644 index 0000000..41fadad --- /dev/null +++ b/express/public/images/exclamation-triangle-red.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/express/public/images/external-link-white.svg b/express/public/images/external-link-white.svg new file mode 100644 index 0000000..1fb5db5 --- /dev/null +++ b/express/public/images/external-link-white.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/external-link.svg b/express/public/images/external-link.svg new file mode 100644 index 0000000..9ceac4c --- /dev/null +++ b/express/public/images/external-link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/eye-off.svg b/express/public/images/eye-off.svg new file mode 100644 index 0000000..a747ef2 --- /dev/null +++ b/express/public/images/eye-off.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/express/public/images/eye.svg b/express/public/images/eye.svg new file mode 100644 index 0000000..8e1d1b0 --- /dev/null +++ b/express/public/images/eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/favicon.ico b/express/public/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..932281102cf93e8bacf0ea6eddc57345dbd9e7ef GIT binary patch literal 1150 zcmb_c-%C?*6#s5bq82d}DkREYB9cnzp`QB#g0M&b0BdR)7FrgS%~8Je5@H0t__7C! zn7en=t+o}R)AnG~#x1PouVy&=!7?|uPv?BsomWH!>0ZwFobS2kbAEG$FwtwX2|6o8 ztwo4ELWm|69jxc;l92suwexo9F1@EC~i8|BDx z{jCQvGunqp=UEI9#hzY+raBON){Hj~&%k?WJCt>5W&gqUDx_1B$SnTEa%K_6=TAC? zXm^dw%X@hTd{=fuua$Z5?orHXLFDs!BW#r%@4Exf1+s0c#6+kQf$RIF4`1U>B!+rc z+3J^EE{pWSG(Nq4f)_Ur!BZrJOl8rLLq9 zo8)g=NZKrX8G*lfFT(A|2|p=yoc(M}MVRMc-zG7>CL3PeKZP;s3Ql+u88G0ANo6>)|+JyLXHzieICYi zv=>Ufg?6C~$#|e>Zxq95PonP bYJ+7{yq?z@{x8Qh`gL}DGdul1uvPvS%u=vH literal 0 HcmV?d00001 diff --git a/express/public/images/fi_arrow-right-circle.svg b/express/public/images/fi_arrow-right-circle.svg new file mode 100644 index 0000000..ebb7d26 --- /dev/null +++ b/express/public/images/fi_arrow-right-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/fi_blue-calendar.svg b/express/public/images/fi_blue-calendar.svg new file mode 100644 index 0000000..fc0e152 --- /dev/null +++ b/express/public/images/fi_blue-calendar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/fi_calendar-white.svg b/express/public/images/fi_calendar-white.svg new file mode 100644 index 0000000..c2c610f --- /dev/null +++ b/express/public/images/fi_calendar-white.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/fi_calendar.svg b/express/public/images/fi_calendar.svg new file mode 100644 index 0000000..8f4b138 --- /dev/null +++ b/express/public/images/fi_calendar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/fi_check-circle.svg b/express/public/images/fi_check-circle.svg new file mode 100644 index 0000000..485ac75 --- /dev/null +++ b/express/public/images/fi_check-circle.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/fi_copy.svg b/express/public/images/fi_copy.svg new file mode 100644 index 0000000..06909b4 --- /dev/null +++ b/express/public/images/fi_copy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/fi_copy_border.svg b/express/public/images/fi_copy_border.svg new file mode 100644 index 0000000..e671c4c --- /dev/null +++ b/express/public/images/fi_copy_border.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/fi_corner-down-left.svg b/express/public/images/fi_corner-down-left.svg new file mode 100644 index 0000000..d880677 --- /dev/null +++ b/express/public/images/fi_corner-down-left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/fi_down_left.svg b/express/public/images/fi_down_left.svg new file mode 100644 index 0000000..44b5365 --- /dev/null +++ b/express/public/images/fi_down_left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/fi_download.svg b/express/public/images/fi_download.svg new file mode 100644 index 0000000..1a33c09 --- /dev/null +++ b/express/public/images/fi_download.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/fi_folder.svg b/express/public/images/fi_folder.svg new file mode 100644 index 0000000..d8886ff --- /dev/null +++ b/express/public/images/fi_folder.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/fi_save.svg b/express/public/images/fi_save.svg new file mode 100644 index 0000000..c862a4d --- /dev/null +++ b/express/public/images/fi_save.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/fi_upload.svg b/express/public/images/fi_upload.svg new file mode 100644 index 0000000..a9ea406 --- /dev/null +++ b/express/public/images/fi_upload.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/fi_x-square.svg b/express/public/images/fi_x-square.svg new file mode 100644 index 0000000..ebec736 --- /dev/null +++ b/express/public/images/fi_x-square.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/format_bold.svg b/express/public/images/format_bold.svg new file mode 100644 index 0000000..f991fe1 --- /dev/null +++ b/express/public/images/format_bold.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/format_italic.svg b/express/public/images/format_italic.svg new file mode 100644 index 0000000..b242cec --- /dev/null +++ b/express/public/images/format_italic.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/globe.svg b/express/public/images/globe.svg new file mode 100644 index 0000000..8e6fb4c --- /dev/null +++ b/express/public/images/globe.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/gray-clock.svg b/express/public/images/gray-clock.svg new file mode 100644 index 0000000..831abe6 --- /dev/null +++ b/express/public/images/gray-clock.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/help-amebis-logo-pug-demo.png b/express/public/images/help-amebis-logo-pug-demo.png new file mode 100644 index 0000000000000000000000000000000000000000..a81c316d0717688de141c9dff627e7a795151135 GIT binary patch literal 11406 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 literal 0 HcmV?d00001 diff --git a/express/public/images/icon-user-x.svg b/express/public/images/icon-user-x.svg new file mode 100644 index 0000000..aa0b9b3 --- /dev/null +++ b/express/public/images/icon-user-x.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/express/public/images/icon-user.svg b/express/public/images/icon-user.svg new file mode 100644 index 0000000..f4beb77 --- /dev/null +++ b/express/public/images/icon-user.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/keyboard.svg b/express/public/images/keyboard.svg new file mode 100644 index 0000000..794be69 --- /dev/null +++ b/express/public/images/keyboard.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/left-arrow.svg b/express/public/images/left-arrow.svg new file mode 100644 index 0000000..a3984df --- /dev/null +++ b/express/public/images/left-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/line-break.svg b/express/public/images/line-break.svg new file mode 100644 index 0000000..0c34072 --- /dev/null +++ b/express/public/images/line-break.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/link.svg b/express/public/images/link.svg new file mode 100644 index 0000000..4c9a296 --- /dev/null +++ b/express/public/images/link.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/list.svg b/express/public/images/list.svg new file mode 100644 index 0000000..7d4328b --- /dev/null +++ b/express/public/images/list.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/express/public/images/lock-gray.svg b/express/public/images/lock-gray.svg new file mode 100644 index 0000000..0d5e7e3 --- /dev/null +++ b/express/public/images/lock-gray.svg @@ -0,0 +1,6 @@ + + + + diff --git a/express/public/images/lock.svg b/express/public/images/lock.svg new file mode 100644 index 0000000..ddcc7ec --- /dev/null +++ b/express/public/images/lock.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/log-out.svg b/express/public/images/log-out.svg new file mode 100644 index 0000000..9ed7965 --- /dev/null +++ b/express/public/images/log-out.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/logo.png b/express/public/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d684d0cb2e1593a36a54d7462b4e1953da91047a GIT binary patch literal 11023 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 JPDHLkV1k`h7yJMK literal 0 HcmV?d00001 diff --git a/express/public/images/mc-hyperlink.svg b/express/public/images/mc-hyperlink.svg new file mode 100644 index 0000000..02e6c00 --- /dev/null +++ b/express/public/images/mc-hyperlink.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/message-square-black.svg b/express/public/images/message-square-black.svg new file mode 100644 index 0000000..78c8070 --- /dev/null +++ b/express/public/images/message-square-black.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/message-square.svg b/express/public/images/message-square.svg new file mode 100644 index 0000000..c82d47e --- /dev/null +++ b/express/public/images/message-square.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/printer.svg b/express/public/images/printer.svg new file mode 100644 index 0000000..e436b2f --- /dev/null +++ b/express/public/images/printer.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/profile-loggedin.svg b/express/public/images/profile-loggedin.svg new file mode 100644 index 0000000..816dd33 --- /dev/null +++ b/express/public/images/profile-loggedin.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/profile.svg b/express/public/images/profile.svg new file mode 100644 index 0000000..61149cf --- /dev/null +++ b/express/public/images/profile.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/quote-marks.svg b/express/public/images/quote-marks.svg new file mode 100644 index 0000000..b89bef7 --- /dev/null +++ b/express/public/images/quote-marks.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/radio-button.svg b/express/public/images/radio-button.svg new file mode 100644 index 0000000..bdb3f10 --- /dev/null +++ b/express/public/images/radio-button.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/red-trash-icon.svg b/express/public/images/red-trash-icon.svg new file mode 100644 index 0000000..f2052be --- /dev/null +++ b/express/public/images/red-trash-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/refresh-ccw.svg b/express/public/images/refresh-ccw.svg new file mode 100644 index 0000000..6a45697 --- /dev/null +++ b/express/public/images/refresh-ccw.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/express/public/images/rsmzk.svg b/express/public/images/rsmzk.svg new file mode 100644 index 0000000..9eeb013 --- /dev/null +++ b/express/public/images/rsmzk.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/express/public/images/search-error.svg b/express/public/images/search-error.svg new file mode 100644 index 0000000..8a025d5 --- /dev/null +++ b/express/public/images/search-error.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/search.svg b/express/public/images/search.svg new file mode 100644 index 0000000..5a9efac --- /dev/null +++ b/express/public/images/search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/search_blue.svg b/express/public/images/search_blue.svg new file mode 100644 index 0000000..092afd4 --- /dev/null +++ b/express/public/images/search_blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/share-2.svg b/express/public/images/share-2.svg new file mode 100644 index 0000000..7de0812 --- /dev/null +++ b/express/public/images/share-2.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/express/public/images/sliders.svg b/express/public/images/sliders.svg new file mode 100644 index 0000000..e0333e0 --- /dev/null +++ b/express/public/images/sliders.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/express/public/images/square-checkbox-solid.svg b/express/public/images/square-checkbox-solid.svg new file mode 100644 index 0000000..4502e84 --- /dev/null +++ b/express/public/images/square-checkbox-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/square-minus.svg b/express/public/images/square-minus.svg new file mode 100644 index 0000000..9877cbe --- /dev/null +++ b/express/public/images/square-minus.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/express/public/images/star-blue.svg b/express/public/images/star-blue.svg new file mode 100644 index 0000000..1bdaa59 --- /dev/null +++ b/express/public/images/star-blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/star.svg b/express/public/images/star.svg new file mode 100644 index 0000000..e00fc8a --- /dev/null +++ b/express/public/images/star.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/statistics-blue.svg b/express/public/images/statistics-blue.svg new file mode 100644 index 0000000..9967c1a --- /dev/null +++ b/express/public/images/statistics-blue.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/statistics.svg b/express/public/images/statistics.svg new file mode 100644 index 0000000..b48ac7a --- /dev/null +++ b/express/public/images/statistics.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/subscript.svg b/express/public/images/subscript.svg new file mode 100644 index 0000000..602a06b --- /dev/null +++ b/express/public/images/subscript.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/superscript.svg b/express/public/images/superscript.svg new file mode 100644 index 0000000..c5a591d --- /dev/null +++ b/express/public/images/superscript.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/threedots.svg b/express/public/images/threedots.svg new file mode 100644 index 0000000..e7b2b13 --- /dev/null +++ b/express/public/images/threedots.svg @@ -0,0 +1,57 @@ + + + + + + + + diff --git a/express/public/images/trash-2.svg b/express/public/images/trash-2.svg new file mode 100644 index 0000000..2d02ab3 --- /dev/null +++ b/express/public/images/trash-2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/u_comment-alt.svg b/express/public/images/u_comment-alt.svg new file mode 100644 index 0000000..b7f244c --- /dev/null +++ b/express/public/images/u_comment-alt.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/u_edit-alt.svg b/express/public/images/u_edit-alt.svg new file mode 100644 index 0000000..90703ae --- /dev/null +++ b/express/public/images/u_edit-alt.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/u_redo.svg b/express/public/images/u_redo.svg new file mode 100644 index 0000000..9ede81f --- /dev/null +++ b/express/public/images/u_redo.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/user-gray.svg b/express/public/images/user-gray.svg new file mode 100644 index 0000000..609e365 --- /dev/null +++ b/express/public/images/user-gray.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/user.svg b/express/public/images/user.svg new file mode 100644 index 0000000..8cf3d03 --- /dev/null +++ b/express/public/images/user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/users-blue.svg b/express/public/images/users-blue.svg new file mode 100644 index 0000000..c117a70 --- /dev/null +++ b/express/public/images/users-blue.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/users.svg b/express/public/images/users.svg new file mode 100644 index 0000000..4dca255 --- /dev/null +++ b/express/public/images/users.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/express/public/images/valid.svg b/express/public/images/valid.svg new file mode 100644 index 0000000..b145dad --- /dev/null +++ b/express/public/images/valid.svg @@ -0,0 +1,3 @@ + + + diff --git a/express/public/images/vector.svg b/express/public/images/vector.svg new file mode 100644 index 0000000..2daddd7 --- /dev/null +++ b/express/public/images/vector.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/express/public/images/x-black.svg b/express/public/images/x-black.svg new file mode 100644 index 0000000..de92b12 --- /dev/null +++ b/express/public/images/x-black.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/x-checkbox.svg b/express/public/images/x-checkbox.svg new file mode 100644 index 0000000..1b28923 --- /dev/null +++ b/express/public/images/x-checkbox.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/x-circle-blue.svg b/express/public/images/x-circle-blue.svg new file mode 100644 index 0000000..84a2b90 --- /dev/null +++ b/express/public/images/x-circle-blue.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/x-circle-red.svg b/express/public/images/x-circle-red.svg new file mode 100644 index 0000000..170fd1a --- /dev/null +++ b/express/public/images/x-circle-red.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/x-circle.svg b/express/public/images/x-circle.svg new file mode 100644 index 0000000..7535b75 --- /dev/null +++ b/express/public/images/x-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/express/public/images/x-gray.svg b/express/public/images/x-gray.svg new file mode 100644 index 0000000..d7b5919 --- /dev/null +++ b/express/public/images/x-gray.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/x.svg b/express/public/images/x.svg new file mode 100644 index 0000000..48e8476 --- /dev/null +++ b/express/public/images/x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/images/x_red.svg b/express/public/images/x_red.svg new file mode 100644 index 0000000..9e058bb --- /dev/null +++ b/express/public/images/x_red.svg @@ -0,0 +1,4 @@ + + + + diff --git a/express/public/javascripts/admin-portals.js b/express/public/javascripts/admin-portals.js new file mode 100644 index 0000000..3eaff08 --- /dev/null +++ b/express/public/javascripts/admin-portals.js @@ -0,0 +1,222 @@ +/* global axios, bootstrap */ +const mainContainer = document.getElementById('offset-main') +mainContainer.addEventListener('click', clickHandler) + +function clickHandler({ target }) { + const createPortalBtn = target.closest('.create-portal-btn') + const linkPortalBtn = target.closest('.link-portal-btn') + const syncPortalBtn = target.closest('.sync-portal-btn') + const portalEnableSwitch = target.closest('.portal-enable-switch') + const deleteTaskBtn = target.closest('.delete-task') + if (createPortalBtn) { + const indexURLEl = document.getElementById('index-url') + const indexURL = indexURLEl.value + createPortal(indexURL) + } + if (linkPortalBtn) { + const linkedPortalId = linkPortalBtn.getAttribute('data-link-id') + const closestTask = linkPortalBtn.closest('.task-declined') + linkPortal(linkedPortalId, closestTask) + } + if (syncPortalBtn) { + const linkedPortalId = syncPortalBtn.getAttribute('data-link-id') + syncPortal(linkedPortalId) + } + if (portalEnableSwitch) { + const portalId = portalEnableSwitch.getAttribute('data-portal-id') + const isEnabled = + portalEnableSwitch.querySelector('.form-check-input').checked + updatePortalStatus(portalId, isEnabled) + } + if (deleteTaskBtn) { + const alertModal = new bootstrap.Modal( + document.getElementById('alert-modal') + ) + alertModal.toggle() + const taskId = deleteTaskBtn.getAttribute('data-link-id') + const modalUseBtn = document.getElementById('modal-use-btn') + modalUseBtn.addEventListener('click', deleteConnection(taskId)) + } +} + +async function createPortal(indexURL) { + event.preventDefault() + const form = document.getElementById('form-connection-new') + const payload = new URLSearchParams(new FormData(form)) + try { + const id = await axios.post('/api/v1/portals/createPortal', payload) + await linkPortal(id.data[0].id) + } catch (error) { + console.log(error) + } finally { + window.location.href = '../../../admin/povezave/seznam' + } +} + +async function deleteConnection(id) { + try { + await axios.delete(`/api/v1/portals/${id}/deleteLinkedDictionary`) + alertModal.hide() + } catch (error) { + console.log(error) + } +} + +async function linkPortal(linkedPortalId, type) { + try { + const r = await axios.put(`/api/v1/portals/${linkedPortalId}/dictionaries`) + // if (data.length) { + // await insertPortalDictionaries(data, linkedPortalId) + // if (type) { + // changeContent(data, type) + // } + // } + console.log(r) + } catch (error) { + console.log(error) + } +} + +async function insertPortalDictionaries(data, portalId) { + data.forEach(el => (el.linkedPortalId = portalId)) + try { + // Ta enpoint je bil odstranjen, ker je itak nepotreben. Tudi ta funkcija je nepotrebna. + // TODO Odstrani to funkcijo in prilagodi lokacije, kjer je sedaj klicana. + // await axios.post('/api/v1/portals/insertDictionaries', { + // params: { data } + // }) + } catch (error) { + console.log(error) + } +} + +async function syncPortal(linkedPortalId) { + event.preventDefault() + const responseModal = new bootstrap.Modal( + document.getElementById('response-modal') + ) + const responseModalText = document.getElementById('response-modal-text') + try { + axios + .all([ + axios.put(`/api/v1/portals/${linkedPortalId}/dictionaries`), + axios.get('/api/v1/portals/getMyDictionaries', { + params: { id: linkedPortalId } + }) + ]) + .then( + axios.spread((obj1, obj2) => { + const theirDict = obj1.data + const myDict = obj2.data + + const results = theirDict.filter( + ({ id: id1 }) => + !myDict.some(({ target_dictionary_id: id2 }) => id2 === id1) + ) + + responseModalText.textContent = `Spremenjenih je bilo ${results.length} slovarjev.` + if (results.length) { + insertPortalDictionaries(results, linkedPortalId) + responseModal.toggle() + } else { + responseModal.toggle() + } + }) + ) + } catch (error) { + console.log(error) + } +} + +async function updatePortalStatus(portalId, isEnabled) { + try { + await axios.post('/api/v1/portals/updatePortalStatus', { + params: { id: portalId, isEnabled: isEnabled } + }) + } catch (error) { + console.log(error) + } +} + +function changeContent(data, type) { + const nameEl = document.querySelector('.bold-weight-black') + const name = nameEl.textContent + const indexURLEl = document.querySelector('.link-url') + const indexURL = indexURLEl.textContent + const imageLinkEl = document.querySelector('.link-portal-btn') + const id = imageLinkEl.getAttribute('data-link-id') + const syncedDiv = document.getElementById('synced-terms-div') + const contaner2 = document.createElement('div') + contaner2.className = 'd-sm-flex justify-content-sm-between d-grid' + const gridEl = document.createElement('div') + gridEl.className = 'd-grid' + const spanCode = document.createElement('span') + spanCode.className = 'bold-weight-black' + spanCode.textContent = name + const spanURL = document.createElement('span') + spanURL.className = 'normal-gray mt-2.mb-2' + spanURL.textContent = indexURL + const centerDiv = document.createElement('div') + centerDiv.className = 'd-flex align-items-center justify-content-sm-end' + const btnDict = document.createElement('button') + btnDict.className = 'btn btn-secondary align-items-center d-flex' + const imgDict = document.createElement('img') + const spanDict = document.createElement('span') + spanDict.className = 'ms-1' + const hr = document.createElement('hr') + hr.className = 'mt-2 mb-3' + const betweenEl = document.createElement('div') + betweenEl.className = 'd-sm-flex justify-content-between' + const alignCntEl = document.createElement('div') + const alertDiv = document.createElement('div') + alertDiv.className = 'd-flex align-content-center mb-0 me-3 mt-2 mt-sm-0' + const alertmargin = document.createElement('div') + alertmargin.className = 'ms-3' + const deleteBtn = document.createElement('button') + deleteBtn.className = 'p-0 btn delete-task' + const deleteImg = document.createElement('img') + deleteImg.src = '/images/red-trash-icon.svg' + const spanDelete = document.createElement('span') + spanDelete.className = 'normal-gray ms-2' + spanDelete.textContent = 'Odstrani' + + if (data.length) { + const container = document.createElement('div') + container.className = 'container-fluid task task-completed p-3 mb-4' + const aDictEl = document.createElement('a') + aDictEl.className = 'btn btn-secondary align-items-center d-flex' + aDictEl.href = `/admin/povezave/seznam/${id}` + imgDict.src = '/images/book-colorized.svg' + spanDict.textContent = 'Slovarji' + alignCntEl.className = + 'd-sm-flex align-items-center mb-0 form-check form-switch' + const switchEl = document.createElement('input') + switchEl.className = 'form-check-input' + switchEl.type = 'checkbox' + switchEl.name = 'isEnabled' + switchEl.id = 'checkbox' + id + const spanSwitch = document.createElement('span') + spanSwitch.className = 'normal-gray ms-1 mt-1' + spanSwitch.textContent = 'Omogočeno' + + container.appendChild(contaner2) + contaner2.appendChild(gridEl) + gridEl.appendChild(spanCode) + contaner2.appendChild(centerDiv) + centerDiv.appendChild(aDictEl) + aDictEl.appendChild(imgDict) + aDictEl.appendChild(spanDict) + container.appendChild(hr) + container.appendChild(betweenEl) + betweenEl.appendChild(alignCntEl) + alignCntEl.appendChild(switchEl) + alignCntEl.appendChild(spanSwitch) + betweenEl.appendChild(alertDiv) + alertDiv.appendChild(alertmargin) + alertmargin.appendChild(deleteBtn) + deleteBtn.appendChild(deleteImg) + deleteBtn.appendChild(spanDelete) + syncedDiv.appendChild(container) + type.remove() + } +} diff --git a/express/public/javascripts/admin.js b/express/public/javascripts/admin.js new file mode 100644 index 0000000..e9b3182 --- /dev/null +++ b/express/public/javascripts/admin.js @@ -0,0 +1,1300 @@ +/* global $, axios, bootstrap, currentPagePath, initPagination, removeAllChildNodes, unsavedData */ + +// const currentPagePath = location.pathname + +window.addEventListener('load', () => { + initAdmin() +}) + +function initAdmin() { + const ce = {} + window.adminElements = ce + + ce.textDescription = document.getElementById('text-description') + ce.headerTitle = document.getElementById('site-header-title') + ce.fixedTopSection = document.getElementById('fixed-top-section') + ce.offsetMain = document.getElementById('offset-main') + + window.addEventListener('resize', () => { + adjustOffsetBy() + mobileMoveContent() + }) + adjustOffsetBy() + mobileMoveContent() + window.onscroll = hideAndShowHeader + + function hideAndShowHeader() { + const { textDescription, headerTitle } = window.adminElements + if (document.body.clientWidth >= 1200) { + if (document.documentElement.scrollTop < 50) { + textDescription.style.display = 'block' + headerTitle.style.display = 'block' + } else { + textDescription.style.display = 'none' + headerTitle.style.display = 'none' + } + } + } + + if (currentPagePath === '/admin/povezave/seznam') { + const { offsetMain } = window.adminElements + offsetMain.addEventListener('click', handleClick) + } + + if ( + /\/admin\/povezave\/seznam\/\d+/.test(currentPagePath) || + currentPagePath === '/admin/povezave/slovarji' + ) { + const resultsListEl = document.getElementById('page-results') + let portalId + if (currentPagePath !== '/admin/povezave/slovarji') { + portalId = document.getElementById('hidden-portal-id').value + } + + const updatePager = initPagination('pagination', onPageChange) + + async function onPageChange(newPage) { + try { + const { page, numberOfAllPages, results } = await getDataForPage( + newPage + ) + removeAllChildNodes(resultsListEl) + renderResults(results) + updatePager(page, numberOfAllPages) + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response?.data) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + alert(message) + updatePager() + } + } + + async function getDataForPage(page) { + let url + if (currentPagePath === '/admin/povezave/slovarji') { + url = `/api/v1/portals/listAllLinkedDicts?p=${page}` + } else { + url = `/api/v1/portals/${portalId}/listSelectedLinkedDicts?p=${page}` + } + const { data } = await axios.get(url) + return data + } + + function renderResults(results) { + results.forEach(result => { + const rowEl = document.createElement('tr') + const td = document.createElement('td') + const div1 = document.createElement('div') + const input = document.createElement('input') + const td1 = document.createElement('td') + const tdTrans = document.createElement('td') + td.append(div1) + div1.append(input) + div1.className = 'form-check form-switch d-flex align-items-center' + input.className = 'form-check-input' + input.type = 'checkbox' + input.name = `isEnabled[${result.id}]` + input.id = result.id + input.checked = !!result.isEnabled + td1.textContent = result.name + tdTrans.textContent = result.code + + rowEl.append(td, td1, tdTrans) + resultsListEl.appendChild(rowEl) + }) + } + } + + if (currentPagePath === '/admin/uporabniki/portal') { + ce.formAddUser = document.getElementById('form-add-user') + const userTable = document.getElementById('user-roles-table') + const tableForm = document.getElementById('form-user-roles') + userTable.addEventListener('change', enableButton) + ce.formAddUser.addEventListener('submit', addUser) + ce.formAddUser.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(tableForm, dictSideMenu) + async function addUser(event) { + event.preventDefault() + + const type = 'portal' + const payload = new URLSearchParams(new FormData(event.target)) + try { + const { data } = await axios.get(event.target.action, { + params: payload + }) + ifUserExists(data, type) + event.target.reset() + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + console.log(message) + } + } + } + + if (currentPagePath === '/admin/uporabniki/seznam') { + const resultsListEl = document.getElementById('page-results') + + const updatePager = initPagination('pagination', onPageChange) + + async function onPageChange(newPage) { + try { + const { page, numberOfAllPages, results } = await getDataForPage( + newPage + ) + removeAllChildNodes(resultsListEl) + renderResults(results) + updatePager(page, numberOfAllPages) + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response?.data) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + alert(message) + updatePager() + } + } + + async function getDataForPage(page) { + const url = `/api/v1/users/listAllUsers?p=${page}` + const { data } = await axios.get(url) + return data + } + + function renderResults(results) { + results.forEach(result => { + const rowEl = document.createElement('tr') + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') + const td4 = document.createElement('td') + const aEl = document.createElement('a') + const imgEl = document.createElement('img') + const spanEl = document.createElement('span') + td1.textContent = result.userName + td2.textContent = result.email + td3.textContent = result.status + aEl.classList.add('image-link') + aEl.type = 'link' + aEl.href = `/admin/uporabniki/${result.id}/urejanje` + imgEl.src = '/images/u_edit-alt.svg' + imgEl.alt = 'Uredi' + spanEl.className = 'normal-gray ms-1' + spanEl.textContent = 'Uredi' + td4.append(aEl) + aEl.append(imgEl, spanEl) + rowEl.append(td1, td2, td3, td4) + resultsListEl.appendChild(rowEl) + }) + } + } + + if (currentPagePath === '/admin/slovarji') { + const resultsListEl = document.getElementById('page-results') + + const updatePager = initPagination('pagination', onPageChange) + + async function onPageChange(newPage) { + try { + const { page, numberOfAllPages, results } = await getDataForPage( + newPage + ) + removeAllChildNodes(resultsListEl) + renderResults(results) + updatePager(page, numberOfAllPages) + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response?.data) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + alert(message) + updatePager() + } + } + + async function getDataForPage(page) { + const url = `/api/v1/dictionaries/listAllDictionaries?p=${page}` + const { data } = await axios.get(url) + return data + } + + function renderResults(results) { + const localeOptions = { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + } + results.forEach(result => { + const rowEl = document.createElement('tr') + const td1 = document.createElement('td') + const td2 = document.createElement('td') + const td3 = document.createElement('td') + const td4 = document.createElement('td') + const td5 = document.createElement('td') + const td6 = document.createElement('td') + const aEl = document.createElement('a') + const imgEl = document.createElement('img') + const spanEl = document.createElement('span') + td1.textContent = result.id + td2.textContent = result.name + td3.textContent = result.status + const timeCreated = new Date(result.timeCreated).toLocaleDateString( + 'sl-SL', + localeOptions + ) + td4.textContent = timeCreated + const timeModified = new Date(result.timeModified).toLocaleDateString( + 'sl-SL', + localeOptions + ) + td5.textContent = timeModified + aEl.classList.add('image-link') + aEl.type = 'link' + aEl.href = `/admin/slovarji/${result.id}/podatki` + imgEl.src = '/images/u_edit-alt.svg' + imgEl.alt = 'Uredi' + spanEl.className = 'normal-gray ms-1' + spanEl.textContent = 'Uredi' + td6.append(aEl) + aEl.append(imgEl, spanEl) + rowEl.append(td1, td2, td3, td4, td5, td6) + resultsListEl.appendChild(rowEl) + }) + } + } + + if (/\/admin\/slovarji\/\d+\/podatki/.test(currentPagePath)) { + const formEl = document.getElementById('admin-description') + const imgTrashIcon = document.querySelectorAll('.delete-author-btn') + const inputNewAuthorEl = document.getElementById('input-new-author') + const inputNewAreaEl = document.getElementById('input-new-area') + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(formEl, dictSideMenu) + formEl.addEventListener('input', enableButton) + if (imgTrashIcon !== null) { + imgTrashIcon.forEach(el => el.addEventListener('click', deleteInput)) + } + inputNewAuthorEl.addEventListener('click', () => { + createNewAuthorInput(formEl) + }) + inputNewAreaEl.addEventListener('click', () => { + createNewAreaInput(formEl) + }) + formEl.addEventListener('submit', event => { + checkform() + if (!event.target.checkValidity()) { + event.preventDefault() + } + event.target.classList.add('was-validated') + }) + } + + if (currentPagePath === '/admin/podpodrocja') { + const { offsetMain } = window.adminElements + offsetMain.addEventListener('click', handleAreasClick) + ce.inputAreaEl = document.getElementById('area-input') + ce.inputAreaEl.addEventListener('input', inputFieldsChecker) + ce.inputTranslationEl = document.getElementById('translation-input') + ce.inputTranslationEl.addEventListener('input', inputFieldsChecker) + ce.domainLabelsForm = document.getElementById('dictionary-domain-labels') + ce.domainLabelsForm.addEventListener('submit', secondaryDomainsToDb) + const formAreas = document.getElementById('dictionary-domain-labels') + formAreas.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(formAreas, dictSideMenu, secondaryDomainsToDb) + const addAreaButtons = document.getElementById('add-area') + addAreaButtons.addEventListener('click', enableButton) + const useBtn = document.getElementById('modal-use-btn') + useBtn.addEventListener('click', enableButton) + + async function secondaryDomainsToDb(event) { + const data = secondaryDomainsForChange() + event.preventDefault() + + try { + await axios.post('/api/v1/dictionaries/renovateSecondaryDomains', { + params: { payload: data } + }) + } catch (error) { + console.log(error) + } finally { + location.reload(true) + } + } + { + const resultsListEl = document.getElementById('page-results') + + const updatePager = initPagination('pagination', onPageChange) + + async function onPageChange(newPage) { + try { + const { page, numberOfAllPages, results } = await getDataForPage( + newPage + ) + removeAllChildNodes(resultsListEl) + renderResults(results) + updatePager(page, numberOfAllPages) + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response?.data) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + alert(message) + updatePager() + } + } + + async function getDataForPage(page) { + const url = `/api/v1/dictionaries/listSecondaryDomains?p=${page}` + const { data } = await axios.get(url) + return data + } + + function renderResults(results) { + results.forEach(result => { + const rowEl = document.createElement('tr') + const input = document.createElement('input') + const th = document.createElement('th') + const input2 = document.createElement('input') + const td1 = document.createElement('td') + const tdTrans = document.createElement('td') + const td2 = document.createElement('td') + const div = document.createElement('div') + const editBtn = document.createElement('button') + const deleteBtn = document.createElement('button') + const imgEditEl = document.createElement('img') + const imgDelEl = document.createElement('img') + input.value = result.id + input.type = 'hidden' + input.name = 'domainLabelId' + th.scope = 'row' + input2.className = 'form-check checkbox-table' + input2.type = 'checkbox' + input2.name = 'isVisible' + input2.disabled = true + input2.checked = !!result.isApproved + th.append(input2) + td1.className = 'tdata-area' + td1.textContent = result.nameSl + tdTrans.className = 'tdata-translation' + tdTrans.textContent = result.nameEn + td2.classList.add('buttons-group') + div.classList.add('table-buttons') + editBtn.className = 'p-0 table-button-grp me-3 edit-row-btn' + editBtn.type = 'button' + imgEditEl.src = '/images/u_edit-alt.svg' + deleteBtn.className = 'p-0 table-button-grp delete-row-btn' + deleteBtn.dataset.bsTarget = '#alert-modal' + deleteBtn.dataset.bsToggle = 'modal' + deleteBtn.type = 'button' + imgDelEl.src = '/images/red-trash-icon.svg' + td2.append(div) + div.append(editBtn, deleteBtn) + editBtn.append(imgEditEl) + deleteBtn.append(imgDelEl) + + rowEl.append(input, th, td1, tdTrans, td2) + resultsListEl.appendChild(rowEl) + }) + } + } + } + + if (/\/slovarji\/\d+\/uporabniki/.test(currentPagePath)) { + const { offsetMain } = window.adminElements + offsetMain.addEventListener('click', handleAreasClick) + ce.terminologyReviewCb = document.getElementById('terminology_review') + ce.languageReviewCb = document.getElementById('language_review') + ce.formDictUsers = document.getElementById('admin-dictionary-users') + ce.formDictUsers.addEventListener('input', enableButton) + ce.formAddUser = document.getElementById('form-add-user') + ce.formAddUser.addEventListener('input', enableButton) + ce.formAddUser.addEventListener('submit', addUser) + checkUserRightsCb() + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(ce.formDictUsers, dictSideMenu) + ce.terminologyReviewCb.addEventListener('click', () => checkUserRightsCb()) + ce.languageReviewCb.addEventListener('click', () => checkUserRightsCb()) + const adminEl = document.querySelectorAll('.administration-cb') + const arrAdminEls = Array.from(adminEl) + arrAdminEls.forEach(el => el.addEventListener('click', () => countAdmins())) + countAdmins() + const publishSwitch = document.getElementById('publish-switch') + publishSwitch.addEventListener('input', enableButton) + + async function addUser(event) { + event.preventDefault() + const type = 'rights' + const payload = new URLSearchParams(new FormData(event.target)) + try { + const { data } = await axios.get(event.target.action, { + params: payload + }) + ifUserExists(data, type) + event.target.reset() + } catch (error) { + const message = 'Prišlo je do napake.' + } + } + } + + if (/\/admin\/uporabniki\/\d+\/urejanje/.test(currentPagePath)) { + const formEditUser = document.getElementById('form-edit-user') + formEditUser.addEventListener('input', enableButton) + } + + if (/\/slovarji\/\d+\/struktura/.test(currentPagePath)) { + changePreview() + const switchForm = document.querySelector('.switch-forms') + switchForm.addEventListener('click', () => changePreview()) + const wholeForm = document.getElementById('form-dictionary-structure') + wholeForm.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(wholeForm, dictSideMenu) + $('#languages-input').on('change', enableButton) + } + + if (currentPagePath === '/admin/nastavitve/portal') { + const formAdminPortal = document.getElementById('admin-portal-settings') + formAdminPortal.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(formAdminPortal, dictSideMenu) + } + + if (currentPagePath === '/admin/nastavitve/slovarji') { + const formAdminPortal = document.getElementById('admin-settings-dict') + formAdminPortal.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(formAdminPortal, dictSideMenu) + } + + if (currentPagePath === '/admin/nastavitve/svetovalnica') { + checkConsultancyBtns() + const { offsetMain } = window.adminElements + offsetMain.addEventListener('click', handleClick) + const formAdminPortal = document.getElementById('admin-settings-consult') + formAdminPortal.addEventListener('input', enableButton) + const dictSideMenu = document.querySelector('.admin-nav-content') + unsavedData(formAdminPortal, dictSideMenu) + } + adjustOffsetBy() +} + +function adjustOffsetBy() { + const { offsetMain, fixedTopSection } = window.adminElements + const referenceHeight = fixedTopSection.offsetHeight + const offsetHeader = document.getElementsByClassName('offset-header') + const offsetHeaderPadding = document.getElementById('offset-padding') + const headerPadding = document.getElementById('header-padding') + + if (document.body.clientWidth < 1200) { + if (offsetHeaderPadding !== null) offsetMain.style.paddingTop = `0px` + } else { + for (let i = 0; i < offsetHeader.length; i++) { + offsetHeader[i].style.paddingTop = `${referenceHeight}px` + } + if (headerPadding !== null) { + const headerPaddingHeight = headerPadding.offsetHeight + offsetMain.style.paddingTop = `${headerPaddingHeight}px` + } + if (offsetHeaderPadding !== null) { + const offsetHeaderHeight = offsetHeaderPadding.offsetHeight + offsetMain.style.paddingTop = `${referenceHeight + offsetHeaderHeight}px` + } + } +} + +function createNewAuthorInput(pageForm) { + const divAuthor = document.createElement('div') + const divSubjectName = document.createElement('div') + const spanName = document.createElement('span') + const divRow = document.createElement('div') + const divColSm5 = document.createElement('div') + const inputGroup = document.createElement('div') + const inputField = document.createElement('input') + const spanInputGroup = document.createElement('span') + const imgTrashIcon = document.createElement('img') + const divColSm = document.createElement('div') + const spanNameInfoTxt = document.createElement('span') + + divAuthor.className = 'author mt-sm-4 added-field' + divSubjectName.className = 'subject-name' + spanName.className = 'smaller-gray-uppercase' + spanName.textContent = 'AVTOR' + divRow.className = 'row align-items-center' + divColSm5.className = 'col-sm-6' + inputGroup.className = 'input-group' + inputField.className = 'name-input d-inline form-control icon-trash' + inputField.name = 'author' + inputField.maxLength = '64' + spanInputGroup.className = 'input-group-text delete-author-btn' + spanInputGroup.id = 'trash-icon-btn' + spanInputGroup.addEventListener('click', deleteInput) + imgTrashIcon.className = 'delete-author p-0' + imgTrashIcon.src = '/images/red-trash-icon.svg' + imgTrashIcon.alt = 'Delete' + divColSm.className = 'col-sm' + spanNameInfoTxt.className = + 'd-md-inline d-block name-info-txt ms-xxl-3 ms-md-3 mt-3 mt-ms-0' + spanNameInfoTxt.textContent = 'Dodaten avtor.' + + divAuthor.appendChild(divSubjectName) + divSubjectName.appendChild(spanName) + divAuthor.appendChild(divRow) + divRow.appendChild(divColSm5) + divColSm5.appendChild(inputGroup) + inputGroup.appendChild(inputField) + inputGroup.appendChild(spanInputGroup) + spanInputGroup.appendChild(imgTrashIcon) + divRow.appendChild(divColSm) + divColSm.appendChild(spanNameInfoTxt) + + const addNewAuthorBtn = document.getElementById('add-new-author') + + pageForm.insertBefore(divAuthor, addNewAuthorBtn) +} + +function createNewAreaInput(pageForm) { + const divSmallNameArea = document.createElement('div') + const divSubjectName = document.createElement('div') + const spanInputNameTxtSlo = document.createElement('span') + const spanInputNameTxtEng = document.createElement('span') + const divRow = document.createElement('div') + const divRow2 = document.createElement('div') + const divColSm5 = document.createElement('div') + const divColSm52 = document.createElement('div') + const inputGroup = document.createElement('div') + const inputFieldSlo = document.createElement('input') + const inputFieldEng = document.createElement('input') + const spanDeleteAreaBtn = document.createElement('span') + const imgTrashIcon = document.createElement('img') + const divColSm = document.createElement('div') + const divColSm2 = document.createElement('div') + const divEnglishInput = document.createElement('div') + const spanNameInfoTxt = document.createElement('span') + const spanNameInfoTxtEng = document.createElement('span') + + divSmallNameArea.className = 'author mt-4 added-field' + divSubjectName.className = 'subject-name' + spanInputNameTxtSlo.className = 'smaller-gray-uppercase' + spanInputNameTxtSlo.textContent = 'NOVO PODPODROČJE (slovensko)' + spanInputNameTxtEng.className = 'smaller-gray-uppercase mt-4' + spanInputNameTxtEng.textContent = 'NOVO PODPODROČJE (angleško)' + divRow.className = 'row align-items-center' + divRow2.className = 'row align-items-center' + divEnglishInput.className = 'mt-4' + divColSm5.className = 'col-sm-6' + divColSm52.className = 'col-sm-6' + inputGroup.className = 'input-group d-flex' + inputFieldSlo.className = 'name-input d-inline form-control icon-trash w-75' + inputFieldSlo.name = 'domainSecondaryNewNameSl' + inputFieldSlo.maxLength = '64' + inputFieldEng.className = 'name-input form-control w-100' + inputFieldEng.name = 'domainSecondaryNewNameEn' + inputFieldEng.maxLength = '64' + spanDeleteAreaBtn.className = 'input-group-text delete-author-btn' + spanDeleteAreaBtn.id = 'trash-icon-btn' + spanDeleteAreaBtn.addEventListener('click', deleteInput) + imgTrashIcon.src = '/images/red-trash-icon.svg' + imgTrashIcon.alt = 'Delete' + divColSm.className = 'col-sm mt-3 mt-sm-0' + divColSm2.className = 'col-sm mt-3 mt-sm-0' + spanNameInfoTxt.className = 'd-sm-inline name-info-txt ms-xxl-3 ms-md-3' + spanNameInfoTxt.textContent = + 'Vpišite novo podpodročje. Na seznamu podpodročij bo vidno takoj po potrditvi administratorja portala.' + spanNameInfoTxtEng.className = + 'd-sm-inline name-info-txt ms-xxl-3 ms-md-3 mt-4' + spanNameInfoTxtEng.textContent = 'Novo podpodročje (angleško).' + + divSmallNameArea.appendChild(divSubjectName) + divSubjectName.appendChild(spanInputNameTxtSlo) + divSmallNameArea.appendChild(divRow) + divRow.appendChild(divColSm5) + divColSm5.appendChild(inputGroup) + inputGroup.appendChild(inputFieldSlo) + inputGroup.appendChild(spanDeleteAreaBtn) + spanDeleteAreaBtn.appendChild(imgTrashIcon) + divSmallNameArea.appendChild(divEnglishInput) + divEnglishInput.appendChild(spanInputNameTxtEng) + divRow.appendChild(divColSm) + divColSm.appendChild(spanNameInfoTxt) + divSmallNameArea.appendChild(divRow2) + divRow2.appendChild(divColSm52) + divColSm52.appendChild(inputFieldEng) + divRow2.appendChild(divColSm2) + divColSm2.appendChild(spanNameInfoTxtEng) + + const addNewSmallAreaBtn = document.getElementById('add-new-area') + + pageForm.insertBefore(divSmallNameArea, addNewSmallAreaBtn) +} + +function countAdmins() { + const allAdmins = document.querySelectorAll('.administration-cb:checked') + if (allAdmins.length === 1) { + const row = allAdmins[0].parentElement.parentElement.parentElement + row.querySelector('.delete-row').classList.add('disabled-input') + allAdmins[0].classList.add('disabled-input') + } else { + const disabledDelete = document.querySelector( + '.delete-user-btn.disabled-input' + ) + if (disabledDelete !== null) { + disabledDelete.classList.remove('disabled-input') + } + const arrAllAdmins = Array.from(allAdmins) + arrAllAdmins.forEach(el => el.classList.remove('disabled-input')) + } +} + +function handleClick({ target }) { + const deleteTask = target.closest('.delete-task') + const btnGrp = target.closest('.btn-group') + if (deleteTask) deleteField(deleteTask) + if (btnGrp) checkConsultancyBtns() +} + +function deleteField(ele) { + const element = ele.closest('.task') + const modalUseBtn = document.getElementById('modal-use-btn') + modalUseBtn.addEventListener('click', () => { + element.remove() + }) + // element.remove() +} + +function checkConsultancyBtns() { + const checked = document.querySelector( + 'input[name="consultancyType"]:checked' + ).value + const emailEl = document.getElementById('zrc-email') + const urlEl = document.getElementById('zrc-url') + if (checked === 'own') { + emailEl.classList.add('disabled-input') + urlEl.classList.add('disabled-input') + } else { + emailEl.classList.remove('disabled-input') + urlEl.classList.remove('disabled-input') + } +} + +function deleteInput({ target }) { + const element = target.closest('.added-field') + const alertModal = new bootstrap.Modal(document.getElementById('alert-modal')) + alertModal.toggle() + const modalUseBtn = document.getElementById('modal-use-btn') + modalUseBtn.addEventListener('click', () => { + element.remove() + alertModal.hide() + enableButton() + }) +} + +function enableButton() { + const disabledBtn = document.getElementById('disabled-submit-btn') + disabledBtn.disabled = false +} + +function handleAreasClick({ target }) { + const editRow = target.closest('.edit-row-btn') + const deleteRow = target.closest('.delete-row-btn') + const tableButtons = target.closest('.table-buttons') + const addAreaBtn = target.closest('#add-area') + const deleteUserRow = target.closest('.delete-user-btn') + const adminCbox = target.closest('.administration-cb') + if (adminCbox) { + if (adminCbox.checked) { + const getRow = adminCbox.parentElement.parentElement.parentElement + const editCbox = getRow.querySelector('.edit-cb') + editCbox.checked = 'true' + } + } + if (deleteUserRow) { + enableButton() + const getRow = deleteUserRow.parentElement.parentElement + const modalUseBtn = document.getElementById('modal-use-btn') + modalUseBtn.addEventListener('click', () => { + getRow.remove() + }) + } + if (deleteRow) { + const getRow = deleteRow.parentElement.parentElement.parentElement + const modalUseBtn = document.getElementById('modal-use-btn') + modalUseBtn.addEventListener('click', () => { + getRow.remove() + }) + const rowId = getRow.firstChild.value + const tempId = getRow.dataset.tempId + if (tempId) { + let arr = secondaryDomainsForChange() + arr = arr.filter(el => el.tempId !== parseInt(tempId)) + secondaryDomainsForChange(arr) + } else { + const data = { id: rowId, type: 'removeArea' } + secondaryDomainsForChange(data) + } + } + if (editRow) { + const getRow = editRow.parentElement.parentElement.parentElement + const visibilityEl = getRow.querySelector('.form-check') + visibilityEl.disabled = false + getRow.className = 'selected-row' + tableButtons.style.display = 'none' + const tDataArea = getRow.querySelector('.tdata-area') + const tDataTranslation = getRow.querySelector('.tdata-translation') + const tDataButtons = getRow.querySelector('.buttons-group') + const tDataAreaText = tDataArea.textContent + const tDataTranslationText = tDataTranslation.textContent + const tdArea = document.createElement('td') + const inputArea = document.createElement('input') + inputArea.className = 'form-control w-50' + inputArea.value = tDataAreaText + tdArea.appendChild(inputArea) + const tdTranslation = document.createElement('td') + const inputTranslation = document.createElement('input') + inputTranslation.className = 'form-control w-50' + inputTranslation.value = tDataTranslationText + tdTranslation.appendChild(inputTranslation) + // tDataArea.remove() + tDataArea.style.display = 'none' + getRow.insertBefore(tdArea, tDataTranslation) + // tDataTranslation.remove() + tDataTranslation.style.display = 'none' + getRow.insertBefore(tdTranslation, tDataButtons) + const buttonsGroup = getRow.querySelector('.buttons-group') + const newButtonGroup = document.createElement('div') + const cancelButton = document.createElement('button') + const saveButton = document.createElement('button') + cancelButton.textContent = 'Prekliči' + cancelButton.type = 'button' + cancelButton.className = 'btn btn-secondary me-2' + cancelButton.style.height = '33px' + cancelButton.style.width = '105px' + cancelButton.addEventListener('click', () => + abortEditing(newButtonGroup, tableButtons, tDataArea, tDataTranslation) + ) + saveButton.textContent = 'POTRDI' + saveButton.type = 'button' + saveButton.className = 'btn btn-primary' + saveButton.style.height = '33px' + saveButton.style.width = '105px' + saveButton.addEventListener('click', () => + saveChanges( + newButtonGroup, + inputArea, + inputTranslation, + tableButtons, + tDataArea, + tDataTranslation + ) + ) + newButtonGroup.className = 'd-flex justify-content-end me-3' + newButtonGroup.appendChild(cancelButton) + newButtonGroup.appendChild(saveButton) + buttonsGroup.insertBefore(newButtonGroup, tableButtons) + } + if (addAreaBtn) { + const areaInput = document.getElementById('area-input') + const translationInput = document.getElementById('translation-input') + const areaInputValue = areaInput.value + const translationInputValue = translationInput.value + if (areaInputValue.length && translationInputValue.length) { + const allAreasTable = document.getElementById('all-areas-table') + const row = allAreasTable.insertRow(-1) + row.dataset.tempId = tempCounter(true) + const cell1 = row.insertCell(0) + const cell2 = row.insertCell(1) + const cell3 = row.insertCell(2) + const cell4 = row.insertCell(3) + cell1.innerHTML = + '' + cell2.textContent = areaInputValue + cell2.classList.add('tdata-area') + cell3.textContent = translationInputValue + cell3.classList.add('tdata-translation') + cell4.innerHTML = + '

' + cell4.classList.add('buttons-group') + areaInput.value = '' + translationInput.value = '' + addAreaBtn.disabled = true + const data = { + tempId: tempCounter(), + nameSl: areaInputValue, + nameEn: translationInputValue, + type: 'addArea' + } + secondaryDomainsForChange(data) + } + } +} + +function saveChanges( + btnGrp, + inputArea, + inputTranslation, + oldButtons, + tDataArea, + tDataTranslation +) { + const inputAreaNewValue = inputArea.value + const inputTranslationNewValue = inputTranslation.value + btnGrp.className = 'd-none' + oldButtons.style.display = 'block' + const getRow = btnGrp.parentElement.parentElement + const tempId = getRow.dataset.tempId + getRow.classList.remove('selected-row') + inputArea.parentElement.remove() + inputTranslation.parentElement.remove() + tDataArea.style.display = 'table-cell' + tDataArea.textContent = inputAreaNewValue + tDataTranslation.style.display = 'table-cell' + tDataTranslation.textContent = inputTranslationNewValue + const visibilityEl = getRow.querySelector('.form-check') + const visibility = visibilityEl.checked + if (tempId) { + const arr = secondaryDomainsForChange() + const found = arr.find(el => el.tempId === parseInt(tempId)) + found.nameSl = inputAreaNewValue + found.nameEn = inputTranslationNewValue + } else { + const changed = { + id: getRow.firstChild.value, + nameSl: inputAreaNewValue, + nameEn: inputTranslationNewValue, + isApproved: visibility, + type: 'changeArea' + } + secondaryDomainsForChange(changed) + } + visibilityEl.disabled = true +} + +function initSecondaryDomainsForChange() { + let tempArray = [] + return function (element) { + if (Array.isArray(element)) tempArray = element + else if (element) tempArray.push(element) + return tempArray + } +} + +const secondaryDomainsForChange = initSecondaryDomainsForChange() + +function initTempCounter() { + let counter = 0 + return function (el) { + if (el) counter += 1 + return counter + } +} + +const tempCounter = initTempCounter() + +function inputFieldsChecker() { + const { inputAreaEl, inputTranslationEl } = window.adminElements + const addAreaButton = document.getElementById('add-area') + if (inputAreaEl.value.length && inputTranslationEl.value.length) { + addAreaButton.disabled = false + } else { + addAreaButton.disabled = true + } +} + +function abortEditing(btnGrp, oldButtons, areaEl, translationEl) { + btnGrp.className = 'd-none' + oldButtons.style.display = 'block' + const getRow = btnGrp.parentElement.parentElement + getRow.classList.remove('selected-row') + const getInputs = getRow.querySelectorAll('.w-50') + getInputs.forEach(el => el.parentElement.remove()) + areaEl.style.display = 'table-cell' + translationEl.style.display = 'table-cell' + const visibilityEl = getRow.querySelector('.form-check') + visibilityEl.disabled = true +} + +function mobileMoveContent() { + const adminNavMobileEl = document.getElementById('admin-nav-mobile') + const mobileRightHolder = document.getElementById('mobile-right-holder') + const secondaryButton = document.querySelector('.header-btn-secondary') + const primaryButton = document.querySelector('.header-btn') + const siteHeading = document.getElementById('site-heading') + const siteHeadingTextContent = siteHeading.textContent + const navTitle = document.getElementById('nav-title') + const headerContainerRight = document.querySelector( + '.header-container-divider-right' + ) + if (document.body.clientWidth <= 1200) { + if (secondaryButton) { + mobileRightHolder.appendChild(secondaryButton) + secondaryButton.style.height = '28px' + // secondaryButton.style.width = '99px' + secondaryButton.style.marginRight = '10px' + } + if (primaryButton) { + // if (currentPagePath === '/admin/povezave/seznam') { + // primaryButton.style.width = '160px' + // } else { + // primaryButton.style.width = '99px' + // } + mobileRightHolder.appendChild(primaryButton) + adminNavMobileEl.classList.add('align-items-center') + adminNavMobileEl.classList.add('justify-content-between') + // primaryButton.style.height = '28px' + // primaryButton.style.marginRight = '10px' + primaryButton.style.whiteSpace = 'nowrap' + } + navTitle.textContent = siteHeadingTextContent + siteHeading.style.display = 'none' + } + if (document.body.clientWidth > 1200) { + if (secondaryButton) { + headerContainerRight.appendChild(secondaryButton) + secondaryButton.style.height = '' + secondaryButton.style.width = '' + secondaryButton.style.marginRight = '' + } + if (primaryButton) { + headerContainerRight.appendChild(primaryButton) + adminNavMobileEl.classList.remove('align-items-center') + adminNavMobileEl.classList.remove('justify-content-between') + primaryButton.style.height = '' + primaryButton.style.width = '' + primaryButton.style.marginRight = '' + primaryButton.style.whiteSpace = '' + } + + if ( + currentPagePath.includes('slovarji') && + !currentPagePath.includes('admin') + ) + navTitle.textContent = 'Urejanje' + else navTitle.textContent = 'Administrator' + siteHeading.style.display = 'block' + } +} + +function changePreview() { + const switchDomainLabel = document.getElementById('domain-labels') + const switchLabel = document.getElementById('label-checkbox') + const switchDefinition = document.getElementById('definition-check-box') + const switchSynonym = document.getElementById('synonyms') + const switchLink = document.getElementById('links') + const switchForeignLang = document.getElementById('language-group') + const switchForeignTerm = document.getElementById('termin-language-subgroup') + const switchForeignDef = document.getElementById( + 'definition-language-subgroup' + ) + const switchForeignSyn = document.getElementById('synonym-language-subgroup') + const switchImage = document.getElementById('images') + const switchAudio = document.getElementById('audio') + const switchVideo = document.getElementById('video') + + const previewDomainSecondary = document.querySelector( + '.preview-domain-secondary' + ) + const selectedLabel = document.querySelector('.preview-label') + const selectedDef = document.querySelector('.preview-definition') + const selectedSynonyms = document.querySelector('.preview-synonym') + const linkedTerms = document.getElementById('linked-terms') + const foreignLanguages = document.querySelector( + '.preview-languages-container' + ) + const listForeignTerm = document.querySelector('.preview-f-term') + const listForeignDefinitions = document.querySelector( + '.preview-foreign-definition' + ) + const foreignSynonyms = document.querySelector('.preview-foreign-synonyms') + const selectedImages = document.querySelector('.preview-images') + const selectedAudio = document.querySelector('.preview-audio') + const selectedVideo = document.querySelector('.preview-video') + + if (!switchDomainLabel.checked) + previewDomainSecondary.classList.add('hide-preview') + else previewDomainSecondary.classList.remove('hide-preview') + if (!switchLabel.checked) selectedLabel.classList.add('hide-preview') + else selectedLabel.classList.remove('hide-preview') + if (!switchDefinition.checked) selectedDef.classList.add('hide-preview') + else selectedDef.classList.remove('hide-preview') + if (!switchSynonym.checked) selectedSynonyms.classList.add('hide-preview') + else selectedSynonyms.classList.remove('hide-preview') + if (!switchLink.checked) linkedTerms.classList.add('hide-preview') + else linkedTerms.classList.remove('hide-preview') + if (!switchForeignLang.checked) foreignLanguages.classList.add('hide-preview') + else foreignLanguages.classList.remove('hide-preview') + if (!switchForeignSyn.checked) foreignSynonyms.classList.add('hide-preview') + else foreignSynonyms.classList.remove('hide-preview') + if (!switchForeignTerm.checked) listForeignTerm.classList.add('hide-preview') + else listForeignTerm.classList.remove('hide-preview') + if (!switchForeignDef.checked) + listForeignDefinitions.classList.add('hide-preview') + else listForeignDefinitions.classList.remove('hide-preview') + + if (!switchImage.checked) selectedImages.classList.add('hide-preview') + else selectedImages.classList.remove('hide-preview') + if (!switchAudio.checked) selectedAudio.classList.add('hide-preview') + else selectedAudio.classList.remove('hide-preview') + if (!switchVideo.checked) selectedVideo.classList.add('hide-preview') + else selectedVideo.classList.remove('hide-preview') +} + +function checkUserRightsCb(el) { + const { terminologyReviewCb, languageReviewCb } = window.adminElements + const termRevCbs = document.querySelectorAll('.terminology-review-cb') + const langRevCbs = document.querySelectorAll('.language-review-cb') + const termRevTxt = document.getElementById('txt-term-rev') + const langRevTxt = document.getElementById('txt-lang-rev') + if (!terminologyReviewCb.checked) { + termRevTxt.classList.add('text-black-50') + termRevCbs.forEach(el => (el.checked = false)) + termRevCbs.forEach(el => el.classList.add('disabled-input')) + } else { + termRevTxt.classList.remove('text-black-50') + termRevCbs.forEach(el => el.classList.remove('disabled-input')) + } + if (!languageReviewCb.checked) { + langRevTxt.classList.add('text-black-50') + langRevCbs.forEach(el => (el.checked = false)) + langRevCbs.forEach(el => el.classList.add('disabled-input')) + } else { + langRevTxt.classList.remove('text-black-50') + langRevCbs.forEach(el => el.classList.remove('disabled-input')) + } +} + +function checkform() { + const selectionInput = $('#cerif') + .find('span') + .find('.select2-selection.select2-selection--multiple') + if ($('#select-cerif').val().length < 1) { + selectionInput.addClass('select2-validation') + selectionInput.addClass('select2-validation:focus') + $('#invalid-section').removeClass('hidden-section') + } else { + selectionInput.removeClass('select2-validation') + selectionInput.removeClass('select2-validation:focus') + $('#invalid-section').addClass('hidden-section') + } +} + +function ifUserExists(data, type) { + const userIds = document.querySelectorAll('.hidden-user-id') + const modalEl = new bootstrap.Modal(document.getElementById('response-modal')) + const modalText = document.getElementById('response-modal-text') + if (data[0] !== undefined) { + if (userIds.length) { + let bool = false + for (let i = 0; i < userIds.length; i++) { + const el = userIds[i] + if (parseInt(el.value) === data[0].id) { + bool = true + } + } + if (bool === true && data[0] !== undefined) { + modalText.textContent = `Uporabnik ${data[0].username} je že v tabeli.` + modalEl.toggle() + } else createNewUserArea(data, type) + } else createNewUserArea(data, type) + } else { + modalText.textContent = `Preverite, če ste pravilno vpisali uporabniško ime. Bodite pozorni na velike in male črke.` + modalEl.toggle() + } +} + +function createNewUserArea(data, type) { + const table = document.getElementById('user-roles-table') + const tBody = document.createElement('tbody') + const tr = document.createElement('tr') + const hiddenId = document.createElement('input') + const td = document.createElement('td') + const spanUserName = document.createElement('span') + const spanEmail = document.createElement('div') + const tdPortAdminOrAdmin = document.createElement('td') + const divPortAdminOrAdmin = document.createElement('div') + const inputPortAdminOrAdmin = document.createElement('input') + const tdDictAdmin = document.createElement('td') + const divDictAdmin = document.createElement('div') + const inputDictAdmin = document.createElement('input') + const tdConsultAdmin = document.createElement('td') + const divConsultAdmin = document.createElement('div') + const inputConsultAdmin = document.createElement('input') + const tdLanguageRev = document.createElement('td') + const divLanguageRev = document.createElement('div') + const inputLanguageRev = document.createElement('input') + const tdDeleteRow = document.createElement('td') + const imgDelete = document.createElement('img') + + if (data[0] !== undefined) { + tBody.id = 'user-data-table' + tBody.className = 'user-data pb-xl-2' + hiddenId.className = 'hidden-user-id' + hiddenId.type = 'hidden' + hiddenId.value = data[0].id + hiddenId.name = 'userId' + td.className = + 'user-information d-grid justify-content-left justify-content-xl-center' + spanUserName.className = 'user-name-last-name' + spanUserName.textContent = data[0].username + spanEmail.className = 'user-email' + spanEmail.textContent = data[0].email + tdPortAdminOrAdmin.className = 'pt-1 pb-1' + divPortAdminOrAdmin.className = + 'form-check d-flex justify-content-left justify-content-xl-center' + inputPortAdminOrAdmin.className = 'form-check-input' + inputPortAdminOrAdmin.type = 'checkbox' + tdDictAdmin.className = 'pt-1 pb-1' + divDictAdmin.className = + 'form-check d-flex justify-content-left justify-content-xl-center' + inputDictAdmin.className = 'form-check-input' + inputDictAdmin.type = 'checkbox' + tdConsultAdmin.className = 'pt-1 pb-1' + divConsultAdmin.className = + 'form-check d-flex justify-content-left justify-content-xl-center' + inputConsultAdmin.className = 'form-check-input' + inputConsultAdmin.type = 'checkbox' + + if (type === 'portal') { + tdPortAdminOrAdmin.dataset.label = 'Skrbnik portala' + inputPortAdminOrAdmin.name = `rolesPerUser['${data[0].id}'][isPortalAdmin]` + tdDictAdmin.dataset.label = 'Skrbnik slovarjev' + inputDictAdmin.name = `rolesPerUser['${data[0].id}'][isDictionariesAdmin]` + tdConsultAdmin.dataset.label = 'Skrbnik svetovalnice' + inputConsultAdmin.name = `rolesPerUser['${data[0].id}'][isConsultancyAdmin]` + } else { + tdPortAdminOrAdmin.dataset.label = 'Administrator' + inputPortAdminOrAdmin.classList.add('administration-cb') + inputPortAdminOrAdmin.name = `rightsPerUser['${data[0].id}'][isAdministration]` + tdDictAdmin.dataset.label = 'Urejanje' + inputDictAdmin.name = `rightsPerUser['${data[0].id}'][isEditing]` + inputDictAdmin.classList.add('edit-cb') + tdConsultAdmin.dataset.label = 'Strokovni pregled' + inputConsultAdmin.classList.add('terminology-review-cb') + inputConsultAdmin.name = `rightsPerUser['${data[0].id}'][isTerminologyReview]` + tdLanguageRev.className = 'pt-1 pb-1' + tdLanguageRev.dataset.label = 'Jezikovni pregled' + divLanguageRev.className = + 'form-check d-flex justify-content-left justify-content-xl-center' + inputLanguageRev.className = 'language-review-cb form-check-input' + inputLanguageRev.type = 'checkbox' + inputLanguageRev.name = `rightsPerUser['${data[0].id}'][isLanguageReview]` + } + + tdDeleteRow.className = 'delete-user-btn pt-3 delete-row' + tdDeleteRow.dataset.bsTarget = '#alert-modal' + tdDeleteRow.dataset.bsToggle = 'modal' + imgDelete.src = '/images/red-trash-icon.svg' + imgDelete.alt = 'Delete' + imgDelete.className = 'icon-trash-delete' + + tBody.appendChild(tr) + tr.appendChild(hiddenId) + tr.appendChild(td) + td.appendChild(spanUserName) + td.appendChild(spanEmail) + tr.appendChild(tdPortAdminOrAdmin) + tdPortAdminOrAdmin.appendChild(divPortAdminOrAdmin) + divPortAdminOrAdmin.appendChild(inputPortAdminOrAdmin) + tr.appendChild(tdDictAdmin) + tdDictAdmin.appendChild(divDictAdmin) + divDictAdmin.appendChild(inputDictAdmin) + tr.appendChild(tdConsultAdmin) + tdConsultAdmin.appendChild(divConsultAdmin) + divConsultAdmin.appendChild(inputConsultAdmin) + + if (type === 'rights') { + tr.appendChild(tdLanguageRev) + tdLanguageRev.appendChild(divLanguageRev) + divLanguageRev.appendChild(inputLanguageRev) + } + tr.appendChild(tdDeleteRow) + tdDeleteRow.appendChild(imgDelete) + + table.appendChild(tBody) + checkUserRightsCb() + } +} + +// Summernote + +$('.summernote').summernote({ + placeholder: 'Na kratko opišite zasnovo in namen slovarja.', + height: 300, + minheight: 150, + toolbar: [ + ['style', ['style', 'bold', 'italic', 'underline']], + ['font', ['superscript', 'subscript']], + ['link', ['linkDialogShow']], + ['para', ['ul', 'ol']], + ['table', ['table']], + ['insert', ['picture']] + ], + styleTags: ['p', 'h3', 'h4'] +}) + +// profile settings +{ + const profileForm = document.getElementById('profileForm') + + if (profileForm) { + profileForm.addEventListener('change', e => { + enableButton() + }) + + profileForm.addEventListener('submit', async e => { + e.preventDefault() + + const data = Object.fromEntries(new FormData(e.target)) + + if (data.numberOfHits) { + await handleUpdateHitsPerPage(data.numberOfHits) + } + + if (data.name && data.surname) { + await handleUpdateUsersName(data.name, data.surname) + } + + // console.log(data) + }) + } + + async function handleUpdateHitsPerPage(hitAmount) { + try { + await axios.post('/api/v1/users/hitsPerPage', { hitAmount }) + } catch (error) { + // console.log(error) + } finally { + location.reload(true) + } + } + + async function handleUpdateUsersName(name, surname) { + try { + await axios.post('/api/v1/users/nameAndSurname', { + name, + surname + }) + } catch (error) { + // console.log(error) + } finally { + location.reload(true) + } + } +} diff --git a/express/public/javascripts/collapsable-comments.js b/express/public/javascripts/collapsable-comments.js new file mode 100644 index 0000000..11fc04d --- /dev/null +++ b/express/public/javascripts/collapsable-comments.js @@ -0,0 +1,29 @@ +{ + let isVisible = false + const pager = document.querySelector('.pager') + const commentsContainer = document.querySelector('#comments-container') + const dropImage = document.querySelector('#dropImage') + const commentCount = document.querySelector('#comments-count') + + const hide = () => { + pager.className += ' d-none' + commentsContainer.className += ' d-none' + commentCount.className += ' d-none' + } + + document.getElementById('collapseComments').addEventListener('click', e => { + isVisible = !isVisible + + if (isVisible) { + pager.className = 'pager' + commentsContainer.className = 'comments-container pe-1' + dropImage.src = '/images/arrow_drop_up.svg' + commentCount.className = 'comment-count d-flex ms-auto me-4 text-p875rem' + } else { + dropImage.src = '/images/arrow_drop_down.svg' + hide() + } + }) + + hide() +} diff --git a/express/public/javascripts/comments.js b/express/public/javascripts/comments.js new file mode 100644 index 0000000..1e46558 --- /dev/null +++ b/express/public/javascripts/comments.js @@ -0,0 +1,651 @@ +// TODO Remove no-console ignore rule once things are out of rapid dev phase. +/* eslint no-console: 0 */ +/* global axios, initPagination */ +const pageURL = location.pathname + +window.addEventListener('load', () => { + initComments() +}) + +function initComments() { + const ce = {} + ce.updatePager = initPagination('pagination', onPageChange) + window.commentElements = ce + ce.commentsCountEl = document.getElementById('comments-count') + ce.commentsContainerEl = document.getElementById('comments-container') + ce.commentForm = document.getElementById('comment-form') + ce.commentReplyForm = document.getElementById('comment-reply-form') + ce.commentMessageInput = document.getElementById('comment-message-input') + ce.commentSubmitBtn = document.getElementById('comment-submit-btn') + ce.commentReplyInput = document.getElementById('comment-reply-input') + ce.commentQuoteId = document.getElementById('comment-quote-id') + ce.commentSubmitReplyBtn = document.getElementById('comment-submit-reply-btn') + ce.replyFormContainer = document.getElementById('reply-form-container') + ce.replyCircle = document.getElementById('reply-circle') + ce.commentDiv = document.querySelector('.comment-div') + + ce.commentSubmitBtn && + ce.commentSubmitBtn.addEventListener('click', submitComment) + // ce.commentMessageInput.addEventListener('keydown', messageInputClick) + ce.commentsContainerEl && + ce.commentsContainerEl.addEventListener('click', handleCommentClick) + ce.commentSubmitReplyBtn && + ce.commentSubmitReplyBtn.addEventListener('click', submitCommentReply) + ce.commentMessageInput && + ce.commentMessageInput.addEventListener('input', autoGrow) + ce.commentReplyInput && + ce.commentReplyInput.addEventListener('input', autoGrow) + // ce.commentMessageInput.addEventListener('keydown', normalizeTextAreaSize) + + window.commentSetting = {} + window.commentSetting.localeOptions = { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + } + + if (ce.commentMessageInput && ce.commentReplyInput) { + ce.commentMessageInput.originalHeight = window.getComputedStyle( + ce.commentMessageInput + ).height + ce.commentReplyInput.originalHeight = window.getComputedStyle( + ce.commentReplyInput + ).height + } + + if (/\/slovarji\/\d+\/vsebina/.test(pageURL)) { + ce.terminsList = document.getElementById('term-list') + if (ce.terminsList) { + ce.terminsList.addEventListener('click', displayComments) + } + const ctxBtns = document.getElementsByName('comments-type') + if (ctxBtns) { + const ctxBtnsArray = Array.from(ctxBtns) + ctxBtnsArray.forEach(el => el.addEventListener('click', displayComments)) + } + } + ce.commentMessageInput && ce.commentReplyInput && clearMessageInput() + displayComments() +} + +function autoGrow({ target: inputToResize }) { + if (!inputToResize.value) { + inputToResize.style.height = inputToResize.originalHeight + } else { + inputToResize.style.height = Math.min(inputToResize.scrollHeight, 95) + 'px' + } +} + +function normalizeTextAreaSize() { + const { commentMessageInput } = window.commentElements + commentMessageInput.style.height = commentMessageInput.originalHeight +} + +// function replyInputClick({ key }) { +// if (key === 'Enter') { +// const { commentSubmitReplyBtn } = window.commentElements +// commentSubmitReplyBtn.click() +// } +// } + +async function displayComments(page) { + // TODO Add error handler + const comments = await fetchComments(page) + renderComments(comments) + return comments +} + +async function fetchComments(page) { + const ctxData = getCtxTypeId() + let apiCall = '/api/v1/comments?ctx_type=' + ctxData.ctxType + if (ctxData.ctxId !== undefined) + apiCall = apiCall + '&' + 'ctx_id=' + ctxData.ctxId + if (page) apiCall = apiCall + `&p=${page}` + const res = await axios.get(apiCall) + return res.data +} + +function renderComments(comments) { + const oldComments = document.querySelectorAll('.comment') + if (oldComments.length) { + const arrayChildren = Array.from(oldComments) + arrayChildren.forEach(el => el.remove()) + } + renderCommentCount(comments.commentCount) + comments.comments.forEach(comment => appendComment(comment)) + const pagesTotalEl = document.querySelector('.pages-total') + + // TODO: Think of a better solution for buggy content pagination + pagesTotalEl.textContent = comments.numberOfAllPages +} + +function renderCommentCount(commentCount) { + const { commentsCountEl } = window.commentElements + + let displayText = `${commentCount} ` + + // TODO Let a i18n library handle the following logic. + switch (commentCount % 100) { + case 1: + displayText += 'komentar' + break + case 2: + displayText += 'komentarja' + break + case 3: + case 4: + displayText += 'komentarji' + break + + default: + displayText += 'komentarjev' + break + } + + commentsCountEl.textContent = displayText +} + +function appendComment(comment) { + const { commentsContainerEl, commentDiv } = window.commentElements + const { localeOptions } = window.commentSetting + + const { + message, + author: { firstName: authorFirstName, lastName: authorLastName }, + timeCreated, + status, + quote + } = comment + + let tstamp = new Date(timeCreated).toLocaleTimeString('sl-SL', localeOptions) + + tstamp = `• ${tstamp}` + const divText = document.createElement('div') + const divTextComment = document.createElement('div') + const divRow = document.createElement('div') + const divRowHead = document.createElement('div') + const liCommentContainer = document.createElement('li') + const divCircle = document.createElement('div') + const spanDate = document.createElement('span') + const spanName = document.createElement('span') + const spanInitials = document.createElement('span') + const divCol = document.createElement('div') + const aReply = document.createElement('button') + const imgReplyBtn = document.createElement('img') + const horizontalRowContainer = document.createElement('div') + const horizontalRow = document.createElement('hr') + + divTextComment.className = 'comment-text-2' + + divRow.className = 'row' + + divRowHead.className = 'row' + + divText.className = 'comment-text' + + liCommentContainer.className = 'comment' + liCommentContainer.dataObject = comment + + divCircle.className = 'comment-initials-container' + + spanInitials.className = 'test' + + divCol.className = 'comment-col col' + + spanName.className = 'comment-author-name' + + spanDate.className = 'comment-date' + + aReply.className = 'comment-reply-btn' + imgReplyBtn.src = '/images/fi_corner-down-left.svg' + imgReplyBtn.alt = 'Reply' + + horizontalRowContainer.className = 'horizontal-row-container container-l' + horizontalRow.className = 'comment-hr comment-line' + + const firstNameInitial = authorFirstName.slice(0, 1) + const lastNameInitial = authorLastName.slice(0, 1) + + const initialLetters = `${firstNameInitial}${lastNameInitial}` + spanInitials.textContent = initialLetters + + spanDate.textContent = tstamp + + const authorName = `${authorFirstName} ${authorLastName}` + spanName.textContent = authorName + + divTextComment.textContent = message + + if (quote) { + const { + message, + author: { firstName: authorFirstName, lastName: authorLastName }, + timeCreated + } = quote + + let tstamp = new Date(timeCreated).toLocaleTimeString( + 'sl-SL', + localeOptions + ) + + tstamp = `• ${tstamp}` + + const quoteText = document.createElement('div') + const imgQuotemarks = document.createElement('img') + const spanQuoteName = document.createElement('span') + const spanQuoteDate = document.createElement('span') + const divQuotedText = document.createElement('div') + const quotehr = document.createElement('hr') + + quoteText.className = 'comment-text-2' + + imgQuotemarks.src = '/images/quote-marks.svg' + + spanQuoteName.className = 'comment-quotename' + + spanQuoteDate.className = 'comment-quotedate' + + divQuotedText.className = 'comment-quotedtext' + + quotehr.className = 'comment-quotehr' + + spanQuoteDate.innerText = tstamp + + const authorName = `${authorFirstName} ${authorLastName}` + + spanQuoteName.textContent = authorName + + divQuotedText.textContent = message + + divText.appendChild(quoteText) + quoteText.appendChild(imgQuotemarks) + quoteText.appendChild(spanQuoteName) + quoteText.appendChild(spanQuoteDate) + quoteText.appendChild(divQuotedText) + divQuotedText.appendChild(quotehr) + } + commentsContainerEl.insertBefore(liCommentContainer, commentDiv) + liCommentContainer.appendChild(divRowHead) + divRowHead.appendChild(divCircle) + divCircle.appendChild(spanInitials) + divRowHead.appendChild(divCol) + divCol.appendChild(spanName) + divCol.appendChild(spanDate) + divCol.appendChild(aReply) + aReply.appendChild(imgReplyBtn) + liCommentContainer.appendChild(divRow) + divRow.appendChild(divText) + divText.appendChild(divTextComment) + divRow.appendChild(horizontalRowContainer) + horizontalRowContainer.appendChild(horizontalRow) + if (comment.showEye) { + const btnSeen = document.createElement('button') + const imgSeen = document.createElement('img') + + divCol.appendChild(btnSeen) + btnSeen.appendChild(imgSeen) + if (status === 'visible') { + btnSeen.className = 'comment-seen-btn me-2' + imgSeen.src = '/images/eye.svg' + imgSeen.alt = 'Viden' + } else { + btnSeen.className = 'comment-eye-off-btn me-2' + imgSeen.src = '/images/eye-off.svg' + imgSeen.alt = 'Skrit' + } + } + if (status === 'hidden') whitenCommentText(liCommentContainer) + else normalCommentColors(liCommentContainer) +} + +function submitComment() { + const { commentMessageInput } = window.commentElements + + const message = commentMessageInput.value + const ctxData = getCtxTypeId() + const ctxType = ctxData.ctxType + let ctxId = null + if (ctxData.ctxId !== undefined) ctxId = ctxData.ctxId + if (!message) { + alert('Vaš komentar je brez vsebine.') + } else { + const payload = { message, ctxType, ctxId, quoteId: null } + createComment(payload) + } + normalizeTextAreaSize() +} + +function submitCommentReply() { + const { commentReplyInput, commentQuoteId } = window.commentElements + const message = commentReplyInput.value + const ctxData = getCtxTypeId() + const ctxType = ctxData.ctxType + const quoteId = commentQuoteId.value + let ctxId = null + if (ctxData.ctxId !== undefined) ctxId = ctxData.ctxId + if (!message) { + alert('Vaš komentar je brez vsebine.') + } else { + const payload = { message, ctxType, ctxId, quoteId } + createComment(payload) + } +} + +async function createComment(comment) { + const { updatePager } = window.commentElements + try { + const res = await axios.post('/api/v1/comments', comment) + const { comments, pagesTotal } = res.data + handleCommentSubmissionSuccess(comments) + updatePager(pagesTotal, pagesTotal) + } catch (e) { + console.log(e) + handleCommentSubmissionError() + } +} + +function handleCommentSubmissionSuccess(comments) { + const { commentForm, replyFormContainer } = window.commentElements + + commentForm.classList.remove('hide') + replyFormContainer.classList.add('hide') + clearMessageInput() + const commentQuoteContent = document.getElementById('comment-quote-content') + if (commentQuoteContent) commentQuoteContent.remove() + const oldComments = document.querySelectorAll('.comment') + if (oldComments.length) { + const arrayChildren = Array.from(oldComments) + arrayChildren.forEach(el => el.remove()) + } + // renderCommentCount(comments.comments.length) + comments.forEach(comment => appendComment(comment)) +} + +function clearMessageInput() { + const { commentMessageInput, commentReplyInput } = window.commentElements + + commentMessageInput.value = '' + commentReplyInput.value = '' +} + +function handleCommentSubmissionError() { + console.error("Comment couldn't be saved. Handle appropriately") +} + +function handleCommentClick({ target }) { + const replyButtonEl = target.closest('.comment-reply-btn') + const btnSeenEl = target.closest('.comment-seen-btn') + const btnEyeOffEl = target.closest('.comment-eye-off-btn') + const commentData = target.closest('.comment')?.dataObject + let status + if (replyButtonEl) { + prepareReplyForm(commentData) + } else if (btnSeenEl) { + const commentText = target.closest('.comment') + whitenCommentText(commentText, btnSeenEl) + status = 'hidden' + commentVisibility(commentData.id, status) + } else if (btnEyeOffEl) { + const commentText = target.closest('.comment') + normalCommentColors(commentText, btnEyeOffEl) + status = 'visible' + commentVisibility(commentData.id, status) + } +} + +function prepareReplyForm(repliedCommentData) { + const { + id: quoteId, + message: quoteMessage, + author: { firstName: quoteAuthorFirstName, lastName: quoteAuthorLastName }, + timeCreated: quotetimeCreated + } = repliedCommentData + + window.scrollTo(0, document.body.scrollHeight) + const { commentForm, commentReplyForm, commentQuoteId, replyFormContainer } = + window.commentElements + const { localeOptions } = window.commentSetting + + commentQuoteId.value = quoteId + + const oldQuotePreview = document.getElementById('comment-quote-content') + if (oldQuotePreview) oldQuotePreview.remove() + + commentForm.classList.add('hide') + replyFormContainer.classList.remove('hide') + + const quotePreview = document.createElement('div') + quotePreview.id = 'comment-quote-content' + + const quoteMarksEl = document.createElement('img') + quoteMarksEl.src = '/images/quote-marks.svg' + quoteMarksEl.id = 'quote-marks' + quotePreview.appendChild(quoteMarksEl) + + const quoteAuthorFirstNameEl = document.createElement('p') + quoteAuthorFirstNameEl.className = 'comment-quote-author-fname' + quoteAuthorFirstNameEl.textContent = quoteAuthorFirstName + quotePreview.appendChild(quoteAuthorFirstNameEl) + + const quoteAuthorLastNameEl = document.createElement('p') + quoteAuthorLastNameEl.className = 'comment-quote-author-lname' + quoteAuthorLastNameEl.textContent = quoteAuthorLastName + quotePreview.appendChild(quoteAuthorLastNameEl) + + let tstamp = new Date(quotetimeCreated).toLocaleTimeString( + 'sl-SL', + localeOptions + ) + + tstamp = `• ${tstamp}` + const quotetimeCreatedEl = document.createElement('p') + quotetimeCreatedEl.className = 'comment-quote-time-created' + quotetimeCreatedEl.textContent = tstamp + quotePreview.appendChild(quotetimeCreatedEl) + + const shortenQuoteMessage = quoteMessage.substring(0, 175) + const quoteMessageEl = document.createElement('p') + quoteMessageEl.className = 'comment-quote-message' + quoteMessageEl.textContent = shortenQuoteMessage + quotePreview.appendChild(quoteMessageEl) + + const horizontalLineEl = document.createElement('hr') + horizontalLineEl.className = 'comment-reply-line' + + quotePreview.appendChild(horizontalLineEl) + + // commentReplyForm.insertBefore(quotePreview, commentReplyInput) + replyFormContainer.insertBefore(quotePreview, commentReplyForm) + + const commentReplyInputEl = document.getElementById('comment-reply-input') + commentReplyInputEl.focus() + commentReplyInputEl.select() +} + +async function commentVisibility(id, status) { + try { + await axios.post('/api/v1/comments/updateStatus', { + params: { id, status } + }) + } catch (e) { + console.log(e) + handleCommentSubmissionError() + } +} + +function whitenCommentText(selectedText, btnSeenEl) { + if (btnSeenEl) { + const imgEyeEl = btnSeenEl.lastElementChild + imgEyeEl.src = '/images/eye-off.svg' + btnSeenEl.classList.remove('comment-seen-btn') + btnSeenEl.classList.add('comment-eye-off-btn') + } + selectedText.classList.add('comment-white-text') +} + +function normalCommentColors(selectedText, btnEyeOffEl) { + if (btnEyeOffEl) { + const imgEyeEl = btnEyeOffEl.lastElementChild + imgEyeEl.src = '/images/eye.svg' + btnEyeOffEl.classList.add('comment-seen-btn') + btnEyeOffEl.classList.remove('comment-eye-off') + } + selectedText.classList.remove('comment-white-text') +} + +// function getCtxId({ target }) { +// console.log(target) +// const termBtn = target.closest('.terms-label') +// console.log(termBtn) +// if (termBtn) { +// console.log(termBtn) +// displayComments() +// } +// } + +const ctxBtns = document.getElementsByName('comments-type') +const commentsTab = document.getElementById('content-comments') +if (ctxBtns) { + const ctxBtnsArray = Array.from(ctxBtns) + ctxBtnsArray.forEach(el => el.addEventListener('click', displayComments)) +} +if (commentsTab) { + commentsTab.addEventListener('click', displayComments) +} + +function getCtxTypeId(type) { + const { terminsList } = window.commentElements + let ctxType + let ctxId + const splitURL = pageURL.split('/') + if (location.pathname !== '/') { + if (!pageURL.match('admin/komentarji')) ctxId = pageURL.match(/\d+/)[0] + if (type) ctxId = type + } + splitURL.forEach(el => { + if (el === 'slovarji') { + ctxType = 'dictionary' + } + if (el === 'admin') { + ctxType = 'portal' + } + /* "vebina" -> in case this endpoint is used anywhere in the future, + delete this legacy endpint matching otherwise */ + if (el === 'vsebina') { + const selected = checkButton('intext') + if (selected === 'internal') ctxType = 'entry_dict_int' + if (selected === 'external') ctxType = 'entry_dict_ext' + const selectedTerm = checkButton(terminsList) + ctxId = selectedTerm + } + if (el === 'termin') { + ctxType = 'entry_dict_ext' + ctxId = checkButtonModular('returnFromEntryDetail') + } + if (el === 'urejanje') { + ctxType = 'entry_consult_int' + ctxId = checkButtonModular('returnFromCosnultancyInternal') + } + }) + if (location.pathname === '/') { + ctxType = 'portal' + ctxId = null + } + + return { ctxType: ctxType, ctxId: ctxId } +} + +function checkButton(type) { + let checked + if (type === 'intext') { + checked = document.querySelector('input[name="comments-type"]:checked').id + } else { + const term = document.querySelector('.selected-term-btn') + if (term) { + const termId = term.getAttribute('data-term-id') + checked = termId + } + } + return checked +} + +async function onPageChange(newPage) { + const { updatePager } = window.commentElements + try { + const { page, numberOfAllPages } = await displayComments(newPage) + updatePager(page, numberOfAllPages) + } catch (error) { + let message = 'Prišlo je do napake.' + if (error.response?.data) { + message = error.response.data + } else if (error.request) { + message = 'Strežnik ni dosegljiv. Poskusite kasneje.' + } + alert(message) + updatePager() + } +} + +/** + * improved version of checkButton function + * + * @param {*} type + * Parameter that checks whether the selector should choose: + * -> if 'intext' -> returns internal or external comment type + * -> if namePattern = returnFrom[Dictionary | Entry | OtherName]Detail + * | -> returns context ID from URL depending on its location + * -> else -> returns the context ID of the selected TERM (also known as entry) + * (previous fn compatible) + * @param {*} selectorExternal + * Parameter that defines from which element to read the ID in case type + * isn't "intext". Please notice that the attribute for id is not id, but + * data-term-id + * @param {*} selectorInternal + * Parameter that defines where to read the string "internal" or "external" + * in case of type being "intext" + * @returns + * + * #Note to the author of the fn: Please define function such that + * one function only does one job, not nested into different logic + * based on a string. + */ +function checkButtonModular( + type, + selectorExternal = '.selected-term-btn', + selectorInternal = 'input[name="comments-type"]:checked' +) { + let checked + if (type === 'intext') { + checked = document.querySelector(selectorInternal).id + } else if (type === 'returnFromEntryDetail') { + checked = returnCommentCTXFromParsedURL(type) + } else if (type === 'returnFromCosnultancyInternal') { + checked = returnCommentCTXFromParsedURL(type) + } else { + const term = document.querySelector(selectorExternal) + if (term) { + const termId = term.getAttribute('data-term-id') + checked = termId + } + } + return checked +} + +function returnCommentCTXFromParsedURL(typeOfURL) { + let retString = 'Undefined - please check your code' + if (typeOfURL === 'returnFromEntryDetail') { + const splitStringBat = window.location.href.split('/') + retString = splitStringBat[splitStringBat.length - 1] + } else if (typeOfURL === 'returnFromDictionaryDetail') { + const splitStringBat = window.location.href.split('/') + retString = splitStringBat[splitStringBat.length - 2] + } else if (typeOfURL === 'returnFromCosnultancyInternal') { + const splitStringBat = window.location.href.split('/') + retString = splitStringBat[splitStringBat.length - 1].split('?')[0] + } + + // console.log('ID: ' + retString) + return retString +} diff --git a/express/public/javascripts/consultancy-edit.js b/express/public/javascripts/consultancy-edit.js new file mode 100644 index 0000000..188e53e --- /dev/null +++ b/express/public/javascripts/consultancy-edit.js @@ -0,0 +1,71 @@ +/* global $, axios */ + +function sumbitFormForConsultancy(e) { + const id = document.querySelector('#entry-id').value + const questionTitle = document.querySelector('#question-title').value + const domain = document.querySelector('#select-cerif').value + const question = document.querySelector('#question').value + const answer = $('#opinion').summernote('code') + + axios.put(e.target.action, { + id, + questionTitle, + domain, + question, + answer + }) + axios + .put('/api/v1/consultancy/entry', { + id, + questionTitle, + domain, + question, + answer + }) + .then(() => { + window.location.href = '/svetovanje/vprasanje/admin/v-delu' + }) +} + +{ + /* + $('#opinion').summernote({ + codeviewFilter: true, + codeviewIframeFilter: true + }) + */ + + const ef = document.querySelector('#edit-form') + + ef.addEventListener('submit', e => { + e.preventDefault() + + sumbitFormForConsultancy(e) + }) + + ef.addEventListener('change', e => { + document.querySelector('#opt1').disabled = false + }) + + $('#opinion').on('summernote.change', function (we, contents, $editable) { + document.querySelector('#opt1').disabled = false + }) + + const resizeFields = document.querySelectorAll('.explanation-field') + if (resizeFields.length) { + resizeFields.forEach(el => + el.addEventListener('input', () => autoResize(el)) + ) + } + + function autoResize(el) { + if (el.style) { + el.style.height = 42 + 'px' + el.style.height = `${el.scrollHeight}px` + } + } + + resizeFields.forEach(el => { + autoResize(el) + }) +} diff --git a/express/public/javascripts/consultancy-handle-unsaved.js b/express/public/javascripts/consultancy-handle-unsaved.js new file mode 100644 index 0000000..a24d4b3 --- /dev/null +++ b/express/public/javascripts/consultancy-handle-unsaved.js @@ -0,0 +1,6 @@ +/* global $ , unsavedData, sumbitFormForConsultancy */ + +const form = document.getElementById('edit-form') +const sideMenu = document.querySelector('.admin-nav-content') + +unsavedData(form, sideMenu, sumbitFormForConsultancy) diff --git a/express/public/javascripts/consultancy-search-mechanism.js b/express/public/javascripts/consultancy-search-mechanism.js new file mode 100644 index 0000000..9eb59d5 --- /dev/null +++ b/express/public/javascripts/consultancy-search-mechanism.js @@ -0,0 +1,67 @@ +/* global $, inputMainSearch */ + +const searchButton = document.getElementById('couns-search-btn') +const advancedSearchButton = document.getElementById('search-in-filter-modal') + +function routeConsultancy(searchString) { + let url + + if (searchString) { + url = new URL(searchString, location.protocol + '//' + location.host) + } else { + url = new URL(location) + + const sq = document.getElementById('search-query') + if (sq) { + url.searchParams.set('q', sq.value) + } + } + // const qParams = new URL(location).searchParams + + // error prone code because of clear filter + // qParams.forEach((value, key) => { + // if (key !== 'q') { + // url.searchParams.append(key, value) + // } + // }) + const pds = $('.select-domain-field') + if (pds) { + pds.val().forEach(val => { + url.searchParams.append('pd', val) + }) + } + + window.location.href = url +} + +function searchOnConsultancyBaseOrAdmin() { + const isItNotAdminURL = !location.pathname.includes('/admin/') + + if (isItNotAdminURL) { + const sq = document.getElementById('search-query') + routeConsultancy(`/svetovanje/iskanje?q=${sq ? sq.value : ''}`) + } else { + // build here URL for admin sections + routeConsultancy(null) + } +} + +function propagateFunctionalityToASearchButton(el) { + if (el) { + el.addEventListener('click', searchOnConsultancyBaseOrAdmin) + } +} + +if (inputMainSearch) { + const listenForTypingOnConsultancy = function (event) { + if (event.code === 'Enter') { + event.preventDefault() + searchOnConsultancyBaseOrAdmin() // here you invoke the function since it is not a listener + } + } + + inputMainSearch.addEventListener('keyup', listenForTypingOnConsultancy) +} + +propagateFunctionalityToASearchButton(searchButton) +propagateFunctionalityToASearchButton(advancedSearchButton) diff --git a/express/public/javascripts/consultancy.js b/express/public/javascripts/consultancy.js new file mode 100644 index 0000000..915b7e1 --- /dev/null +++ b/express/public/javascripts/consultancy.js @@ -0,0 +1,440 @@ +/* global $, handleDomainsClickForConsultancy, inputFieldsChecker, currentPagePath, axios, nthParent, tooltipListWOL, tooltipTriggerList */ + +/* +author: Miha Stele, 2022 +*/ + +/** selectedID -> ID of the selected Entry */ +let selectedID = -1 + +// consultancy FORM +let offsetMain +function adjustOffsetBy() { + offsetMain = document.querySelector('#offset-main') + const fixedTopSection = document.querySelector('#fixed-top-section') + const referenceHeight = fixedTopSection.offsetHeight + const offsetHeader = document.getElementsByClassName('offset-header') + const offsetHeaderPadding = document.getElementById('offset-padding') + // const adminNavMobile = document.getElementsByClassName('admin-nav') + const headerPadding = document.getElementById('header-padding') + + if (document.body.clientWidth < 1200) { + if (offsetHeaderPadding !== null) offsetMain.style.paddingTop = `0px` + } else { + for (let i = 0; i < offsetHeader.length; i++) { + offsetHeader[i].style.paddingTop = `${referenceHeight}px` + } + if (headerPadding !== null) { + const headerPaddingHeight = headerPadding.offsetHeight + offsetMain.style.paddingTop = `${headerPaddingHeight}px` + } + if (offsetHeaderPadding !== null) { + const offsetHeaderHeight = offsetHeaderPadding.offsetHeight + offsetMain.style.paddingTop = `${referenceHeight + offsetHeaderHeight}px` + } + } +} + +function event2SelectedId(e) { + return nthParent(e.currentTarget, 4).id.substring(3) +} + +window.addEventListener('load', () => { + adjustOffsetBy() + + const ce = {} + window.adminElements = ce + /* copy source admin.js in case of refactoring */ + + if (currentPagePath === '/svetovanje/vprasanje/admin/uporabniki') { + offsetMain.addEventListener('click', handleDomainsClickForConsultancy) + ce.name = document.getElementById('name-input') + if (ce.name) { + ce.name.addEventListener('input', inputFieldsChecker) + } + ce.inputAreaEl = document.getElementById('area-input') + if (ce.inputAreaEl) { + ce.inputAreaEl.addEventListener('input', inputFieldsChecker) + } + } +}) + +window.addEventListener('resize', () => { + adjustOffsetBy() + // mobileMoveContent() +}) + +try { + document.querySelector('#consultancy-form').addEventListener('submit', e => { + e.preventDefault() + + // window.location.replace('/svetovanje/iskanje') + }) +} catch (e) {} + +try { + const splitedHref = window.location.href.split('/') + + document.querySelectorAll('.edit-button').forEach(e => { + e.addEventListener('click', () => { + window.location.replace( + `/svetovanje/vprasanje/admin/urejanje/${nthParent(e, 4).id.slice( + 3 + )}?sentFrom=${splitedHref[splitedHref.length - 1]}` + ) + }) + }) +} catch (e) {} +// share.pug +try { + // In your Javascript (external .js resource or

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%0ANHzMjy`EJ;F0T~3_%lSYawc+3t1vFd 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%0DXb#90*&Ts6Tf}D86SI;^ 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