From 29eff70c6ebb4f4cd2afb4d57eb63314747e37e1 Mon Sep 17 00:00:00 2001 From: aurelio-aot Date: Mon, 11 May 2026 15:43:51 -0700 Subject: [PATCH 1/3] AB#29181: Make arrow white for dark accordion --- .../Pages/GrantApplications/Details-shadow-dom.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details-shadow-dom.css b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details-shadow-dom.css index 66bd099703..3bcd68c728 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details-shadow-dom.css +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details-shadow-dom.css @@ -39,6 +39,16 @@ transition: all 0.5s !important; } +/* White arrow on dark background card headers */ +.card-header.bg-primary:not(.card-body .card-header)::before, +.card-header.bg-success:not(.card-body .card-header)::before, +.card-header.bg-info:not(.card-body .card-header)::before, +.card-header.bg-warning:not(.card-body .card-header)::before, +.card-header.bg-danger:not(.card-body .card-header)::before { + border-bottom-color: white; + border-right-color: white; +} + /* Accordion body animation */ .card-body { transition: height 0.5s; From dcc46946fa065f2c2f51abe93c82377074ebdad4 Mon Sep 17 00:00:00 2001 From: aurelio-aot Date: Mon, 11 May 2026 16:18:32 -0700 Subject: [PATCH 2/3] AB#29181: Center Accordion Text and Arrow --- Submission.html | 10378 +++++++++++++ Submission_files/AnalyticsUtils.js.download | 210 + Submission_files/ApplicationAttachments.css | 31 + .../ApplicationAttachments.js.download | 112 + .../ApplicationConfigurationScript | 350 + Submission_files/ApplicationLinks.js.download | 227 + .../ApplicationLocalizationScript | 1418 ++ Submission_files/ApplicationTags.js.download | 357 + .../AssessmentResultAttachments.css | 28 + .../AssessmentResultAttachments.js.download | 102 + Submission_files/Attachments.css | 35 + Submission_files/Attachments.js.download | 144 + .../BCID_UnityGrantManagement_RGB_pos.svg | 1 + Submission_files/ChefsAttachments.css | 116 + Submission_files/ChefsAttachments.js.download | 558 + Submission_files/DateUtils.js.download | 41 + Submission_files/Default(1).css | 53 + Submission_files/Default(1).js.download | 261 + Submission_files/Default(10).css | 1 + Submission_files/Default(10).js.download | 196 + Submission_files/Default(11).css | 2 + Submission_files/Default(11).js.download | 2 + Submission_files/Default(12).css | 59 + Submission_files/Default(12).js.download | 2 + Submission_files/Default(13).css | 1 + Submission_files/Default(13).js.download | 5 + Submission_files/Default(14).css | 152 + Submission_files/Default(14).js.download | 3 + Submission_files/Default(15).css | 203 + Submission_files/Default(15).js.download | 625 + Submission_files/Default(16).css | 270 + Submission_files/Default(16).js.download | 244 + Submission_files/Default(17).css | 60 + Submission_files/Default(17).js.download | 1005 ++ Submission_files/Default(18).css | 59 + Submission_files/Default(18).js.download | 189 + Submission_files/Default(19).js.download | 999 ++ Submission_files/Default(2).css | 33 + Submission_files/Default(2).js.download | 164 + Submission_files/Default(20).js.download | 15 + Submission_files/Default(3).css | 66 + Submission_files/Default(3).js.download | 255 + Submission_files/Default(4).css | 22 + Submission_files/Default(4).js.download | 12 + Submission_files/Default(5).css | 78 + Submission_files/Default(5).js.download | 311 + Submission_files/Default(6).css | 15 + Submission_files/Default(6).js.download | 883 ++ Submission_files/Default(7).css | 22 + Submission_files/Default(7).js.download | 102 + Submission_files/Default(8).css | 17 + Submission_files/Default(8).js.download | 90 + Submission_files/Default(9).css | 29 + Submission_files/Default(9).js.download | 585 + Submission_files/Default.css | 43 + Submission_files/Default.js.download | 8 + Submission_files/Details.css | 726 + Submission_files/Details.js.download | 1264 ++ Submission_files/EditContactModal.js.download | 46 + Submission_files/EmailHistory.css | 56 + Submission_files/PaymentTags.js.download | 359 + Submission_files/ReviewList.css | 22 + Submission_files/ReviewList.js.download | 584 + Submission_files/Segoe-Fluent-Icons.ttf | Bin 0 -> 408752 bytes Submission_files/Segoe-MDL2-Assets.ttf | Bin 0 -> 283820 bytes Submission_files/ServiceProxyScript | 4489 ++++++ Submission_files/SupplierInfo.css | 58 + Submission_files/SupplierInfo.js.download | 533 + Submission_files/abp-sweetalert2.js.download | 157 + Submission_files/abp-toast.css | 142 + Submission_files/abp-toast.js.download | 207 + .../abp-utils.umd.min.js.download | 2 + Submission_files/abp.css | 56 + Submission_files/abp.jquery.js.download | 411 + Submission_files/abp.js.download | 830 ++ Submission_files/abp.luxon.js.download | 46 + Submission_files/ai-analysis.js.download | 530 + .../ai-generation-button-state.js.download | 104 + Submission_files/ai-rate-limit.js.download | 115 + Submission_files/all.css | 7913 ++++++++++ .../aspnetcore-browser-refresh.js.download | 358 + .../authentication-state-listener.js.download | 30 + ...bootstrap-datepicker.en-CA.min.js.download | 1 + Submission_files/bootstrap-datepicker.min.css | 7 + .../bootstrap-datepicker.min.js.download | 8 + Submission_files/bootstrap.bundle.js.download | 6314 ++++++++ Submission_files/bootstrap.css | 12057 ++++++++++++++++ Submission_files/browserLink | 33 + .../buttons.bootstrap5.js.download | 122 + Submission_files/buttons.bootstrap5.min.css | 1 + .../buttons.colVis.min.js.download | 5 + .../buttons.html5.min.js.download | 8 + .../colReorder.bootstrap5.min.css | 1 + .../colReorder.bootstrap5.min.js.download | 4 + Submission_files/colvisAlpha.js.download | 176 + Submission_files/content.css | 1240 ++ Submission_files/dataTables.bootstrap5.css | 611 + .../dataTables.bootstrap5.js.download | 122 + .../dataTables.bootstrap5.min.css | 5 + .../dataTables.buttons.min.js.download | 4 + .../dataTables.colReorder.min.js.download | 7 + .../dataTables.fixedHeader.js.download | 1219 ++ Submission_files/dataTables.min.js.download | 4 + .../dataTables.select.js.download | 2032 +++ .../dataTables.stateRestore.js.download | 2444 ++++ .../datatables-extensions.js.download | 569 + Submission_files/datatables-styles.css | 17 + .../date-range-picker-extensions.js.download | 799 + Submission_files/date-range-picker-styles.css | 11 + Submission_files/daterangepicker.css | 410 + Submission_files/daterangepicker.js.download | 1576 ++ .../dom-event-handlers.js.download | 238 + Submission_files/echarts.min.js.download | 45 + Submission_files/en-CA.js.download | 75 + Submission_files/filterRow.js.download | 498 + .../fixedHeader.bootstrap5.min.css | 1 + .../fixedHeader.bootstrap5.min.js.download | 4 + Submission_files/flatpickr.min.css | 13 + Submission_files/flatpickr.min.js.download | 2 + Submission_files/fluenticons.min.css | 6 + Submission_files/fluentui-icons.css | 425 + Submission_files/fonts.css | 42 + Submission_files/formio.form.css | 2023 +++ Submission_files/formio.form.min.js.download | 2 + Submission_files/global-styles.css | 93 + Submission_files/handlebars.min.js.download | 29 + Submission_files/icons.min.js.download | 1 + Submission_files/includes.min.css | 1 + Submission_files/includes.min.js.download | 3 + .../jquery-extensions.js.download | 195 + .../jquery-form-extensions.js.download | 156 + Submission_files/jquery.js.download | 10716 ++++++++++++++ ...ry.mCustomScrollbar.concat.min.js.download | 5 + Submission_files/jquery.mCustomScrollbar.css | 1267 ++ .../jquery.maskMoney.min.js.download | 9 + Submission_files/jquery.timeago.js.download | 232 + Submission_files/jquery.validate.js.download | 1703 +++ .../jquery.validate.unobtrusive.js.download | 435 + Submission_files/json-editor.css | 95 + Submission_files/json-editor.js.download | 637 + Submission_files/jszip.min.js.download | 13 + Submission_files/layout.css | 966 ++ Submission_files/layout.js.download | 129 + Submission_files/lodash.min.js.download | 140 + Submission_files/luxon.min.js.download | 1 + Submission_files/matomo.js.download | 78 + Submission_files/modal-manager.js.download | 249 + Submission_files/model.min.js.download | 1 + Submission_files/moment.min.js.download | 2 + Submission_files/plugin.min(1).js.download | 1 + Submission_files/plugin.min(2).js.download | 1 + Submission_files/plugin.min(3).js.download | 1 + Submission_files/plugin.min(4).js.download | 1 + Submission_files/plugin.min.js.download | 1 + Submission_files/pubsub.js.download | 359 + Submission_files/scrollResize.js.download | 231 + .../select.bootstrap5.js.download | 60 + Submission_files/select.bootstrap5.min.css | 1 + Submission_files/select2.min.css | 1 + Submission_files/select2.min.js.download | 2 + Submission_files/skin.css | 7084 +++++++++ .../stateRestore.dataTables.js.download | 58 + .../stateRestore.dataTables.min.css | 1 + Submission_files/string-utils.js.download | 36 + .../sweetalert2.all.min.js.download | 6 + Submission_files/table-utils.js.download | 946 ++ Submission_files/tenant-switch.js.download | 16 + Submission_files/theme.min.js.download | 1 + Submission_files/tinymce.min.js.download | 10 + Submission_files/tribute.css | 34 + Submission_files/tribute.min.js.download | 2 + Submission_files/ui-extensions.js.download | 332 + Submission_files/unity-styles.css | 912 ++ Submission_files/unity.svg | 30 + Submission_files/v4-shims.css | 2194 +++ Submission_files/widget-manager.js.download | 147 + Submission_files/zone-extensions.js.download | 471 + .../GrantApplications/Details-shadow-dom.css | 25 +- 178 files changed, 103574 insertions(+), 14 deletions(-) create mode 100644 Submission.html create mode 100644 Submission_files/AnalyticsUtils.js.download create mode 100644 Submission_files/ApplicationAttachments.css create mode 100644 Submission_files/ApplicationAttachments.js.download create mode 100644 Submission_files/ApplicationConfigurationScript create mode 100644 Submission_files/ApplicationLinks.js.download create mode 100644 Submission_files/ApplicationLocalizationScript create mode 100644 Submission_files/ApplicationTags.js.download create mode 100644 Submission_files/AssessmentResultAttachments.css create mode 100644 Submission_files/AssessmentResultAttachments.js.download create mode 100644 Submission_files/Attachments.css create mode 100644 Submission_files/Attachments.js.download create mode 100644 Submission_files/BCID_UnityGrantManagement_RGB_pos.svg create mode 100644 Submission_files/ChefsAttachments.css create mode 100644 Submission_files/ChefsAttachments.js.download create mode 100644 Submission_files/DateUtils.js.download create mode 100644 Submission_files/Default(1).css create mode 100644 Submission_files/Default(1).js.download create mode 100644 Submission_files/Default(10).css create mode 100644 Submission_files/Default(10).js.download create mode 100644 Submission_files/Default(11).css create mode 100644 Submission_files/Default(11).js.download create mode 100644 Submission_files/Default(12).css create mode 100644 Submission_files/Default(12).js.download create mode 100644 Submission_files/Default(13).css create mode 100644 Submission_files/Default(13).js.download create mode 100644 Submission_files/Default(14).css create mode 100644 Submission_files/Default(14).js.download create mode 100644 Submission_files/Default(15).css create mode 100644 Submission_files/Default(15).js.download create mode 100644 Submission_files/Default(16).css create mode 100644 Submission_files/Default(16).js.download create mode 100644 Submission_files/Default(17).css create mode 100644 Submission_files/Default(17).js.download create mode 100644 Submission_files/Default(18).css create mode 100644 Submission_files/Default(18).js.download create mode 100644 Submission_files/Default(19).js.download create mode 100644 Submission_files/Default(2).css create mode 100644 Submission_files/Default(2).js.download create mode 100644 Submission_files/Default(20).js.download create mode 100644 Submission_files/Default(3).css create mode 100644 Submission_files/Default(3).js.download create mode 100644 Submission_files/Default(4).css create mode 100644 Submission_files/Default(4).js.download create mode 100644 Submission_files/Default(5).css create mode 100644 Submission_files/Default(5).js.download create mode 100644 Submission_files/Default(6).css create mode 100644 Submission_files/Default(6).js.download create mode 100644 Submission_files/Default(7).css create mode 100644 Submission_files/Default(7).js.download create mode 100644 Submission_files/Default(8).css create mode 100644 Submission_files/Default(8).js.download create mode 100644 Submission_files/Default(9).css create mode 100644 Submission_files/Default(9).js.download create mode 100644 Submission_files/Default.css create mode 100644 Submission_files/Default.js.download create mode 100644 Submission_files/Details.css create mode 100644 Submission_files/Details.js.download create mode 100644 Submission_files/EditContactModal.js.download create mode 100644 Submission_files/EmailHistory.css create mode 100644 Submission_files/PaymentTags.js.download create mode 100644 Submission_files/ReviewList.css create mode 100644 Submission_files/ReviewList.js.download create mode 100644 Submission_files/Segoe-Fluent-Icons.ttf create mode 100644 Submission_files/Segoe-MDL2-Assets.ttf create mode 100644 Submission_files/ServiceProxyScript create mode 100644 Submission_files/SupplierInfo.css create mode 100644 Submission_files/SupplierInfo.js.download create mode 100644 Submission_files/abp-sweetalert2.js.download create mode 100644 Submission_files/abp-toast.css create mode 100644 Submission_files/abp-toast.js.download create mode 100644 Submission_files/abp-utils.umd.min.js.download create mode 100644 Submission_files/abp.css create mode 100644 Submission_files/abp.jquery.js.download create mode 100644 Submission_files/abp.js.download create mode 100644 Submission_files/abp.luxon.js.download create mode 100644 Submission_files/ai-analysis.js.download create mode 100644 Submission_files/ai-generation-button-state.js.download create mode 100644 Submission_files/ai-rate-limit.js.download create mode 100644 Submission_files/all.css create mode 100644 Submission_files/aspnetcore-browser-refresh.js.download create mode 100644 Submission_files/authentication-state-listener.js.download create mode 100644 Submission_files/bootstrap-datepicker.en-CA.min.js.download create mode 100644 Submission_files/bootstrap-datepicker.min.css create mode 100644 Submission_files/bootstrap-datepicker.min.js.download create mode 100644 Submission_files/bootstrap.bundle.js.download create mode 100644 Submission_files/bootstrap.css create mode 100644 Submission_files/browserLink create mode 100644 Submission_files/buttons.bootstrap5.js.download create mode 100644 Submission_files/buttons.bootstrap5.min.css create mode 100644 Submission_files/buttons.colVis.min.js.download create mode 100644 Submission_files/buttons.html5.min.js.download create mode 100644 Submission_files/colReorder.bootstrap5.min.css create mode 100644 Submission_files/colReorder.bootstrap5.min.js.download create mode 100644 Submission_files/colvisAlpha.js.download create mode 100644 Submission_files/content.css create mode 100644 Submission_files/dataTables.bootstrap5.css create mode 100644 Submission_files/dataTables.bootstrap5.js.download create mode 100644 Submission_files/dataTables.bootstrap5.min.css create mode 100644 Submission_files/dataTables.buttons.min.js.download create mode 100644 Submission_files/dataTables.colReorder.min.js.download create mode 100644 Submission_files/dataTables.fixedHeader.js.download create mode 100644 Submission_files/dataTables.min.js.download create mode 100644 Submission_files/dataTables.select.js.download create mode 100644 Submission_files/dataTables.stateRestore.js.download create mode 100644 Submission_files/datatables-extensions.js.download create mode 100644 Submission_files/datatables-styles.css create mode 100644 Submission_files/date-range-picker-extensions.js.download create mode 100644 Submission_files/date-range-picker-styles.css create mode 100644 Submission_files/daterangepicker.css create mode 100644 Submission_files/daterangepicker.js.download create mode 100644 Submission_files/dom-event-handlers.js.download create mode 100644 Submission_files/echarts.min.js.download create mode 100644 Submission_files/en-CA.js.download create mode 100644 Submission_files/filterRow.js.download create mode 100644 Submission_files/fixedHeader.bootstrap5.min.css create mode 100644 Submission_files/fixedHeader.bootstrap5.min.js.download create mode 100644 Submission_files/flatpickr.min.css create mode 100644 Submission_files/flatpickr.min.js.download create mode 100644 Submission_files/fluenticons.min.css create mode 100644 Submission_files/fluentui-icons.css create mode 100644 Submission_files/fonts.css create mode 100644 Submission_files/formio.form.css create mode 100644 Submission_files/formio.form.min.js.download create mode 100644 Submission_files/global-styles.css create mode 100644 Submission_files/handlebars.min.js.download create mode 100644 Submission_files/icons.min.js.download create mode 100644 Submission_files/includes.min.css create mode 100644 Submission_files/includes.min.js.download create mode 100644 Submission_files/jquery-extensions.js.download create mode 100644 Submission_files/jquery-form-extensions.js.download create mode 100644 Submission_files/jquery.js.download create mode 100644 Submission_files/jquery.mCustomScrollbar.concat.min.js.download create mode 100644 Submission_files/jquery.mCustomScrollbar.css create mode 100644 Submission_files/jquery.maskMoney.min.js.download create mode 100644 Submission_files/jquery.timeago.js.download create mode 100644 Submission_files/jquery.validate.js.download create mode 100644 Submission_files/jquery.validate.unobtrusive.js.download create mode 100644 Submission_files/json-editor.css create mode 100644 Submission_files/json-editor.js.download create mode 100644 Submission_files/jszip.min.js.download create mode 100644 Submission_files/layout.css create mode 100644 Submission_files/layout.js.download create mode 100644 Submission_files/lodash.min.js.download create mode 100644 Submission_files/luxon.min.js.download create mode 100644 Submission_files/matomo.js.download create mode 100644 Submission_files/modal-manager.js.download create mode 100644 Submission_files/model.min.js.download create mode 100644 Submission_files/moment.min.js.download create mode 100644 Submission_files/plugin.min(1).js.download create mode 100644 Submission_files/plugin.min(2).js.download create mode 100644 Submission_files/plugin.min(3).js.download create mode 100644 Submission_files/plugin.min(4).js.download create mode 100644 Submission_files/plugin.min.js.download create mode 100644 Submission_files/pubsub.js.download create mode 100644 Submission_files/scrollResize.js.download create mode 100644 Submission_files/select.bootstrap5.js.download create mode 100644 Submission_files/select.bootstrap5.min.css create mode 100644 Submission_files/select2.min.css create mode 100644 Submission_files/select2.min.js.download create mode 100644 Submission_files/skin.css create mode 100644 Submission_files/stateRestore.dataTables.js.download create mode 100644 Submission_files/stateRestore.dataTables.min.css create mode 100644 Submission_files/string-utils.js.download create mode 100644 Submission_files/sweetalert2.all.min.js.download create mode 100644 Submission_files/table-utils.js.download create mode 100644 Submission_files/tenant-switch.js.download create mode 100644 Submission_files/theme.min.js.download create mode 100644 Submission_files/tinymce.min.js.download create mode 100644 Submission_files/tribute.css create mode 100644 Submission_files/tribute.min.js.download create mode 100644 Submission_files/ui-extensions.js.download create mode 100644 Submission_files/unity-styles.css create mode 100644 Submission_files/unity.svg create mode 100644 Submission_files/v4-shims.css create mode 100644 Submission_files/widget-manager.js.download create mode 100644 Submission_files/zone-extensions.js.download diff --git a/Submission.html b/Submission.html new file mode 100644 index 0000000000..ad093a891a --- /dev/null +++ b/Submission.html @@ -0,0 +1,10378 @@ + + + + + + + + + + + Grants | Unity Grant Manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ UGM 0.0.0+25511915f56325dafd27b0c08d1b88ce8e4e9ce0 +
+
+ + + + + + + + +
+ +
+
+ + + + + + +
+
+ + + + + + +
+
+
+ +
+
+
+
+ + + + + +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+ + +
+ +
+ + +
+ +
+
+ +
+
+
Application Status
+
+
+ Approved +
+
+
+
+
+ +
+
+
Application Tags
+
+
+ +
+
+
+
+
+ + + + + +
+
Unity Application ID
+
BC-ABPP-FY2526-claims-00005
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ + +
+ +
+
+ +
+ ABPP 2025 - Fall Claim for Payment +
+
+ +
+ 2026-03-27 +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ $0.00 +
+
+ +
+ $0.00 +
+
+ +
+ +
+
+
+
+
Assessment Summary
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ Approved +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ 0 +
+
+ +
+ +
+
+ +
+ $0.00 +
+
+ +
+ $3,000.00 +
+
+
+ + + + +
+
+
+ +
+ +
+
Emails
+
+
+ +
+ + + + + + + + + + + +
+
+ +
+
+ +
+
+
Email History
+
+
+ +
+
+
+
+
Comments
+
+
+ +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+
+ +
+
+
+
Internal Uploads by Program
+
+
+ +
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+
+
Submission Attachments
+
+
+ + + +
+
+
+
+ +
+
+
+ + + +
+
+
+ +
+
+
+

Application Status History

+
+
+
+ + +
+
+
+
+ +
+
+
+
+ Status changed + to + Submitted +
+
+ +
+
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + SunMonTueWedThuFriSat + +
123456789101112131415161718192021222324252627282930311234567891011
\ No newline at end of file diff --git a/Submission_files/AnalyticsUtils.js.download b/Submission_files/AnalyticsUtils.js.download new file mode 100644 index 0000000000..bc86ff95b8 --- /dev/null +++ b/Submission_files/AnalyticsUtils.js.download @@ -0,0 +1,210 @@ +/** + * Analytics utility functions for Grant Manager application + */ +const AnalyticsUtils = (function () { + 'use strict'; + + const DIMENSION_TENANT_NAME = 1; + const DIMENSION_USER_NAME = 2; + + /** + * Safely gets the current tenant name from ABP. + * + * @returns {string|null} Tenant name or null if unavailable. + */ + function getTenantName() { + return globalThis.abp?.currentTenant?.name ?? null; + } + + /** + * Safely gets the current authenticated user ID from ABP. + * + * @returns {string|null} User ID or null if unavailable. + */ + function getUserId() { + return globalThis.abp?.currentUser?.id ? String(globalThis.abp.currentUser.id) : null; + } + + /** + * Safely builds the current user's full name from ABP. + * + * @returns {string|null} Full user name or null if unavailable. + */ + function getUserName() { + const firstName = globalThis.abp?.currentUser?.name ?? ''; + + const lastName = globalThis.abp && + abp.currentUser && + ( + abp.currentUser.surname || + abp.currentUser.surName || + '' + ); + + const fullName = `${firstName} ${lastName}`.trim(); + + return fullName || null; + } + + /** + * Applies common custom dimensions for tenant and user. + * + * @param {Array} trackerQueue - Matomo tracker queue. + */ + function applyCustomDimensions(trackerQueue) { + const tenantName = getTenantName(); + const userName = getUserName(); + + if (tenantName) { + trackerQueue.push([ + 'setCustomDimension', + DIMENSION_TENANT_NAME, + tenantName + ]); + } else { + console.warn( + '[Analytics] Tenant name unavailable. Custom Dimension 1 not set.' + ); + } + + if (userName) { + trackerQueue.push([ + 'setCustomDimension', + DIMENSION_USER_NAME, + userName + ]); + } else { + console.warn( + '[Analytics] User name unavailable. Custom Dimension 2 not set.' + ); + } + } + + /** + * Loads the Matomo tracking script asynchronously. + * + * @param {string} url - Base Matomo URL. + */ + function loadMatomoScript(url) { + const script = document.createElement('script'); + + script.async = true; + script.src = `${url}/matomo.js`; + + script.onerror = function () { + console.error( + '[Analytics] Failed to load matomo.js from:', + script.src + ); + }; + + document.head.appendChild(script); + } + + /** + * Initialises Matomo analytics tracking. + * Disables cookies (GDPR), sets user identity, + * applies custom dimensions, tracks initial page view, + * and enables link tracking. + * + * @param {string} url - Base Matomo URL (no trailing slash). + * @param {string|number} siteId - Matomo site ID. + */ + function initMatomo(url, siteId) { + console.debug( + '[Analytics] initMatomo called — url:', + url, + '| siteId:', + siteId + ); + + if (!url || !siteId) { + console.warn( + '[Analytics] initMatomo aborted: url or siteId is missing.' + ); + return; + } + + const trackerQueue = globalThis._paq = globalThis._paq || []; + + trackerQueue.push( + ['disableCookies'], + ['setTrackerUrl', `${url}/matomo.php`], + ['setSiteId', String(siteId)] + ); + + const userId = getUserId(); + + if (userId) { + trackerQueue.push(['setUserId', userId]); + } + + applyCustomDimensions(trackerQueue); + + /** + * Track initial page view after dimensions are set. + */ + trackerQueue.push( + ['trackPageView'], + ['enableLinkTracking'] + ); + + loadMatomoScript(url); + } + + /** + * Tracks a virtual page view for AJAX-driven navigation + * without a full page reload. + * + * Re-applies dimensions for Action-scoped dimensions. + * + * @param {string} [url] - Virtual URL. + * @param {string} [title] - Virtual page title. + */ + function trackVirtualPageView(url, title) { + const trackerQueue = globalThis._paq; + + if (!trackerQueue) { + return; + } + + applyCustomDimensions(trackerQueue); + + trackerQueue.push( + ['setCustomUrl', url || globalThis.location.href], + ['setDocumentTitle', title || document.title], + ['trackPageView'] + ); + } + + /** + * Tracks internal site search. + * + * @param {string} keyword - Search term entered by the user. + * @param {string|false} [category] - Optional search category. + * @param {number|false} [resultCount] - Optional result count. + */ + function trackSearch(keyword, category, resultCount) { + const trackerQueue = globalThis._paq; + + if (!trackerQueue || !keyword) { + return; + } + + trackerQueue.push([ + 'trackSiteSearch', + keyword, + typeof category === 'string' ? category : false, + typeof resultCount === 'number' ? resultCount : false + ]); + } + + /** + * Public API + */ + return { + initMatomo, + trackVirtualPageView, + trackSearch + }; +})(); \ No newline at end of file diff --git a/Submission_files/ApplicationAttachments.css b/Submission_files/ApplicationAttachments.css new file mode 100644 index 0000000000..0ec7a9efaa --- /dev/null +++ b/Submission_files/ApplicationAttachments.css @@ -0,0 +1,31 @@ +/* Updated for DataTables v2 - ensure proper width handling with scrollX */ +#ApplicationAttachmentsTable_wrapper .dt-scroll-body { + overflow: visible !important; +} + +/* Ensure table wrapper uses full width */ +#ApplicationAttachmentsTable_wrapper { + width: 100%; +} + +/* Ensure scroll container properly sizes */ +#ApplicationAttachmentsTable_wrapper .dt-scroll { + overflow: visible; +} + +/* Ensure inner scroll elements take full width */ +#ApplicationAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner, +#ApplicationAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner table { + width: 100% !important; +} + +#ApplicationAttachmentsTable_wrapper .dt-scroll-body table { + width: 100% !important; +} + +/*27121 Bug Fix*/ +@media (max-height: 768px) { + .dt-scroll-body { + max-height: inherit !important; + } +} \ No newline at end of file diff --git a/Submission_files/ApplicationAttachments.js.download b/Submission_files/ApplicationAttachments.js.download new file mode 100644 index 0000000000..eb0a0e8c8b --- /dev/null +++ b/Submission_files/ApplicationAttachments.js.download @@ -0,0 +1,112 @@ +// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js +$(function () { + const l = abp.localization.getResource('GrantManager'); + const nullPlaceholder = '—'; + + let inputAction = function (requestData, dataTableSettings) { + const urlParams = new URL(window.location.toLocaleString()).searchParams; + const applicationId = urlParams.get('ApplicationId'); + return { + attachmentType: 'APPLICATION', + attachedResourceId: applicationId + }; + }; + + let responseCallback = function (result) { + if (result) { + setTimeout(function () { + PubSub.publish('update_application_attachment_count', { files: result.length }); + }, 10); + } + + return { + data: result + }; + }; + + const dataTable = $('#ApplicationAttachmentsTable').DataTable( + abp.libs.datatables.normalizeConfiguration({ + serverSide: false, + order: [[2, 'asc']], + searching: true, + paging: false, + select: false, + info: false, + scrollX: true, + ajax: abp.libs.datatables.createAjax( + unity.grantManager.attachments.attachment.getAttachments, inputAction, responseCallback + ), + columnDefs: [ + { + title: '', + width: '40px', + className: 'text-center', + render: function (data) { + return ''; + }, + orderable: false + }, + { + title: l('AssessmentResultAttachments:DocumentName'), + data: 'fileName', + className: 'data-table-header text-break', + width: '30%', + }, + { + title: 'Label', + data: 'displayName', + className: 'data-table-header text-break', + width: '20%', + render: function (data) { + return data ?? nullPlaceholder; + } + }, + { + title: l('AssessmentResultAttachments:UploadedDate'), + data: 'time', + className: 'data-table-header', + width: '140px', + render: function (data, type) { + if (type === 'display' || type === 'filter') { + return new Date(data).toDateString(); + } + return data; + }, + }, + { + title: l('AssessmentResultAttachments:AttachedBy'), + data: 'attachedBy', + className: 'data-table-header', + width: '25%', + }, + { + title: '', + data: 's3ObjectKey', + width: '80px', + className: 'text-center', + render: function (data, type, full, meta) { + return generateAttachmentButtonContent(data, type, full, meta, 'Application'); + }, + orderable: false + } + ], + externalFilterButtonId: 'btn-toggle-filter-uploads', + }) + ); + + initializeFilterRowPlugin(dataTable, 'btn-toggle-filter-uploads'); + + dataTable.on('click', 'tbody tr', function (e) { + e.currentTarget.classList.toggle('selected'); + }); + + PubSub.subscribe( + 'refresh_application_attachment_list', + (msg, data) => { + dataTable.ajax.reload(); + } + ); + $('#attachments-tab').one('click', function () { + dataTable.columns.adjust(); + }); +}); diff --git a/Submission_files/ApplicationConfigurationScript b/Submission_files/ApplicationConfigurationScript new file mode 100644 index 0000000000..136584556e --- /dev/null +++ b/Submission_files/ApplicationConfigurationScript @@ -0,0 +1,350 @@ +(function(){ + +$.extend(true, abp, { + "localization": { + "values": {}, + "resources": {}, + "languages": [ + { + "cultureName": "en", + "uiCultureName": "en", + "displayName": "en", + "twoLetterISOLanguageName": "en" + } + ], + "currentCulture": { + "displayName": "English (Canada)", + "englishName": "English (Canada)", + "threeLetterIsoLanguageName": "eng", + "twoLetterIsoLanguageName": "en", + "isRightToLeft": false, + "cultureName": "en-CA", + "name": "en-CA", + "nativeName": "English (Canada)", + "dateTimeFormat": { + "calendarAlgorithmType": "SolarCalendar", + "dateTimeFormatLong": "dddd, MMMM d, yyyy", + "shortDatePattern": "yyyy-MM-dd", + "fullDateTimePattern": "dddd, MMMM d, yyyy h:mm:ss tt", + "dateSeparator": "-", + "shortTimePattern": "h:mm tt", + "longTimePattern": "h:mm:ss tt" + } + }, + "defaultResourceName": "GrantManager", + "languagesMap": { + "bootstrap-datepicker": [ + { + "name": "zh-Hans", + "value": "zh-CN" + }, + { + "name": "zh-Hant", + "value": "zh-TW" + } + ], + "moment": [ + { + "name": "zh-Hans", + "value": "zh-cn" + }, + { + "name": "zh-Hant", + "value": "zh-tw" + }, + { + "name": "de-DE", + "value": "de" + } + ] + }, + "languageFilesMap": { + "bootstrap-datepicker": [ + { + "name": "zh-Hans", + "value": "zh-CN" + }, + { + "name": "zh-Hant", + "value": "zh-TW" + } + ], + "moment": [ + { + "name": "zh-Hans", + "value": "zh-cn" + }, + { + "name": "zh-Hant", + "value": "zh-tw" + }, + { + "name": "de-DE", + "value": "de" + } + ], + "jquery.timeago": [ + { + "name": "zh-Hans", + "value": "zh-CN" + }, + { + "name": "zh-Hant", + "value": "zh-TW" + } + ], + "jquery-validation": [ + { + "name": "zh-Hans", + "value": "zh" + }, + { + "name": "zh-Hant", + "value": "zh_TW" + } + ] + } + }, + "auth": { + "grantedPolicies": {} + }, + "setting": { + "values": { + "Abp.Localization.DefaultLanguage": "en-CA", + "Abp.Timing.TimeZone": "", + "Abp.Identity.Password.RequiredLength": "6", + "Abp.Identity.Password.RequiredUniqueChars": "1", + "Abp.Identity.Password.RequireNonAlphanumeric": "True", + "Abp.Identity.Password.RequireLowercase": "True", + "Abp.Identity.Password.RequireUppercase": "True", + "Abp.Identity.Password.RequireDigit": "True", + "Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "False", + "Abp.Identity.Password.PasswordChangePeriodDays": "0", + "Abp.Identity.Password.EnablePreventPasswordReuse": "False", + "Abp.Identity.Password.PreventPasswordReuseCount": "6", + "Abp.Identity.Lockout.AllowedForNewUsers": "True", + "Abp.Identity.Lockout.LockoutDuration": "300", + "Abp.Identity.Lockout.MaxFailedAccessAttempts": "5", + "Abp.Identity.SignIn.RequireConfirmedEmail": "False", + "Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "True", + "Abp.Identity.SignIn.RequireEmailVerificationToRegister": "False", + "Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "False", + "Abp.Identity.User.IsUserNameUpdateEnabled": "True", + "Abp.Identity.User.IsEmailUpdateEnabled": "True", + "Abp.Identity.OrganizationUnit.MaxUserMembershipCount": "2147483647", + "GrantManager.Notifications.Mailing.DefaultFromAddress": "NoReply.Unity@gov.bc.ca", + "GrantManager.Notifications.Mailing.EmailMaxRetryAttempts": "3", + "GrantManager.Locality.SectorFilter": null, + "GrantManager.UI.Tabs.Submission": null, + "GrantManager.UI.Tabs.Assessment": null, + "GrantManager.UI.Tabs.Project": null, + "GrantManager.UI.Tabs.Applicant": null, + "GrantManager.UI.Tabs.Payments": null, + "GrantManager.UI.Tabs.FundingAgreement": null, + "GrantManager.BackgroundJobs.IntakeResync_NumDaysToCheck": null, + "GrantManager.BackgroundJobs.IntakeResync_Expression": null, + "GrantManager.BackgroundJobs.CasPaymentsReconciliation_ProducerExpression": null, + "GrantManager.BackgroundJobs.CasFinancialNotificationSummary_ProducerExpression": null, + "GrantManager.BackgroundJobs.DataHealthCheckMonitor_Expression": null, + "GrantManager.BackgroundJobs.ApplicantTenantMapReconciliation_Expression": null + } + }, + "currentUser": { + "isAuthenticated": false, + "id": null, + "tenantId": null, + "impersonatorUserId": null, + "impersonatorTenantId": null, + "impersonatorUserName": null, + "impersonatorTenantName": null, + "userName": null, + "name": null, + "surName": null, + "email": null, + "emailVerified": false, + "phoneNumber": null, + "phoneNumberVerified": false, + "roles": [], + "sessionId": null + }, + "features": { + "values": { + "SettingManagement.Enable": "true", + "SettingManagement.AllowChangingEmailSettings": "false", + "Unity.Payments": "false", + "Unity.Notifications": "false", + "Unity.Flex": "false", + "Unity.Reporting": "false", + "Unity.AIReporting": "false", + "Unity.AI.AttachmentSummaries": "false", + "Unity.AI.ApplicationAnalysis": "false", + "Unity.AI.Scoring": "false", + "Unity.Analytics": "false" + } + }, + "globalFeatures": { + "enabledFeatures": [] + }, + "multiTenancy": { + "isEnabled": true, + "userSharingStrategy": 0 + }, + "currentTenant": { + "id": null, + "name": null, + "isAvailable": false + }, + "timing": { + "timeZone": { + "iana": { + "timeZoneName": null + }, + "windows": { + "timeZoneId": null + } + } + }, + "clock": { + "kind": "Utc" + }, + "objectExtensions": { + "modules": { + "Identity": { + "entities": { + "User": { + "properties": { + "OidcSub": { + "type": "System.String", + "typeSimple": "string", + "displayName": null, + "api": { + "onGet": { + "isAvailable": true + }, + "onCreate": { + "isAvailable": true + }, + "onUpdate": { + "isAvailable": true + } + }, + "ui": { + "onTable": { + "isVisible": true + }, + "onCreateForm": { + "isVisible": true + }, + "onEditForm": { + "isVisible": true + }, + "lookup": { + "url": null, + "resultListPropertyName": null, + "displayPropertyName": null, + "valuePropertyName": null, + "filterParamName": null + } + }, + "policy": { + "globalFeatures": { + "features": [], + "requiresAll": false + }, + "features": { + "features": [], + "requiresAll": false + }, + "permissions": { + "permissionNames": [], + "requiresAll": false + } + }, + "attributes": [ + { + "typeSimple": "readOnly", + "config": { + "isReadOnly": true + } + } + ], + "configuration": { + "AllowUserToEdit": false + }, + "defaultValue": null + }, + "DisplayName": { + "type": "System.String", + "typeSimple": "string", + "displayName": null, + "api": { + "onGet": { + "isAvailable": true + }, + "onCreate": { + "isAvailable": true + }, + "onUpdate": { + "isAvailable": true + } + }, + "ui": { + "onTable": { + "isVisible": true + }, + "onCreateForm": { + "isVisible": true + }, + "onEditForm": { + "isVisible": true + }, + "lookup": { + "url": null, + "resultListPropertyName": null, + "displayPropertyName": null, + "valuePropertyName": null, + "filterParamName": null + } + }, + "policy": { + "globalFeatures": { + "features": [], + "requiresAll": false + }, + "features": { + "features": [], + "requiresAll": false + }, + "permissions": { + "permissionNames": [], + "requiresAll": false + } + }, + "attributes": [ + { + "typeSimple": "readOnly", + "config": { + "isReadOnly": true + } + } + ], + "configuration": { + "AllowUserToEdit": false + }, + "defaultValue": null + } + }, + "configuration": {} + } + }, + "configuration": {} + } + }, + "enums": {} + }, + "extraProperties": {} +}) + +abp.event.trigger('abp.configurationInitialized'); + +})(); \ No newline at end of file diff --git a/Submission_files/ApplicationLinks.js.download b/Submission_files/ApplicationLinks.js.download new file mode 100644 index 0000000000..73a5ad2eda --- /dev/null +++ b/Submission_files/ApplicationLinks.js.download @@ -0,0 +1,227 @@ +$(function () { + + let suggestionsArray = []; + + + // Plugin Constructor + let LinksInput = function (opts) { + this.options = Object.assign(LinksInput.defaults, opts); + this.init(); + } + // Initialize the plugin + LinksInput.prototype.init = function (opts) { + this.options = opts ? Object.assign(this.options, opts) : this.options; + + if (this.initialized) + this.destroy(); + this.orignal_input = document.getElementById(this.options.selector); + + if (!this.orignal_input) { + console.error("links-input couldn't find an element with the specified ID"); + return this; + } + + this.arr = []; + + this.wrapper = document.createElement('div'); + this.input = document.createElement('input'); + init(this); + initEvents(this); + + this.initialized = true; + return this; + } + + + // Add Tags + LinksInput.prototype.addLink = function (linkData) { + let defaultClass = 'tags-common'; + let linkText, linkClass; + + if (typeof linkData === 'string') { + linkText = linkData; + linkClass = defaultClass; + + } else { + linkText = linkData.text || ''; + linkClass = linkData.class || defaultClass; + + } + + if (this.anyErrors(linkText)) + return; + + this.arr.push(linkText); + + let linkInput = this; + + let link = document.createElement('span'); + link.className = this.options.linkClass + ' ' + linkClass; + link.innerText = linkText; + + let closeIcon = document.createElement('a'); + closeIcon.innerHTML = '×'; + + // delete the link when icon is clicked + closeIcon.addEventListener('click', function (e) { + e.preventDefault(); + let link = this.parentNode; + + for (let i = 0; i < linkInput.wrapper.childNodes.length; i++) { + if (linkInput.wrapper.childNodes[i] == link) + linkInput.deleteLink(link, i); + } + }) + + link.appendChild(closeIcon); + this.wrapper.insertBefore(link, this.input); + this.orignal_input.value = JSON.stringify(this.arr); + + return this; + } + + // Delete Tags + LinksInput.prototype.deleteLink = function (link, i) { + link.remove(); + this.arr.splice(i, 1); + this.orignal_input.value = JSON.stringify(this.arr); + return this; + } + + // Make sure input string have no error with the plugin + LinksInput.prototype.anyErrors = function (string) { + if (!this.options.duplicate && this.arr.indexOf(string) != -1) { + console.log('duplicate found " ' + string + ' " ') + return true; + } + + return false; + } + + // Add links programmatically + LinksInput.prototype.addData = function (array) { + let plugin = this; + + array.forEach(function (string) { + plugin.addLink(string); + }) + return this; + } + + // Get the Input String + LinksInput.prototype.getInputString = function () { + return this.arr.join(','); + } + LinksInput.prototype.setSuggestions = function (sugArray) { + suggestionsArray = sugArray; + } + + + // destroy the plugin + LinksInput.prototype.destroy = function () { + this.orignal_input.removeAttribute('hidden'); + + delete this.orignal_input; + let self = this; + + Object.keys(this).forEach(function (key) { + if (self[key] instanceof HTMLElement) + self[key].remove(); + + if (key != 'options') + delete self[key]; + }); + + this.initialized = false; + } + + // Private function to initialize the link input plugin + function init(links) { + links.wrapper.append(links.input); + links.wrapper.classList.add(links.options.wrapperClass); + links.orignal_input.setAttribute('hidden', 'true'); + links.orignal_input.parentNode.insertBefore(links.wrapper, links.orignal_input); + links.input.addEventListener('input', function () { + const inputValue = links.input.value.trim().toLowerCase(); + + // Show suggestions only after the first character entry + if (inputValue.length > 0) { + const suggestions = suggestionsArray.filter(link => link.toLowerCase().includes(inputValue)); + + // Display suggestions below the input element + if (suggestions.length) { + displaySuggestions(links, suggestions); + } else { + removeSuggestions(links); + } + + } else { + // Remove suggestions if input is empty + removeSuggestions(links); + } + }); + } + + // Function to display auto-completion suggestions + function displaySuggestions(links, suggestions) { + // Remove previous suggestions + removeSuggestions(links); + + // Create suggestion container + const suggestionContainer = document.createElement('div'); + suggestionContainer.classList.add('links-suggestion-container'); + const suggestionTitleElement = document.createElement('div'); + suggestionTitleElement.className = 'links-suggestion-title'; + suggestionTitleElement.innerText = 'ALL APPLICATIONS'; + suggestionContainer.appendChild(suggestionTitleElement); + + // Add suggestions to the container + suggestions.forEach(suggestion => { + const suggestionElement = document.createElement('div'); + suggestionElement.className = 'links-suggestion-element'; + suggestionElement.innerText = suggestion; + + // Add click event to add suggestion as a new link + suggestionElement.addEventListener('click', function () { + links.addLink(suggestion); + removeSuggestions(links); + links.input.value = ""; + }); + + suggestionContainer.appendChild(suggestionElement); + }); + + // Append the suggestion container below the input + links.wrapper.appendChild(suggestionContainer); + } + + // Function to remove auto-completion suggestions + function removeSuggestions(links) { + const suggestionContainer = links.wrapper.querySelector('.links-suggestion-container'); + if (suggestionContainer) { + suggestionContainer.remove(); + } + } + + // initialize the Events + function initEvents(links) { + links.wrapper.addEventListener('click', function () { + links.input.focus(); + }); + } + + // Set All the Default Values + LinksInput.defaults = { + selector: '', + wrapperClass: 'tags-input-wrapper', + linkClass: 'tag', + max: null, + duplicate: false + } + + window.LinksInput = LinksInput; + + +}); + + diff --git a/Submission_files/ApplicationLocalizationScript b/Submission_files/ApplicationLocalizationScript new file mode 100644 index 0000000000..0ded0602b4 --- /dev/null +++ b/Submission_files/ApplicationLocalizationScript @@ -0,0 +1,1418 @@ +(function(){ + +$.extend(true, abp.localization, { + "resources": { + "Default": { + "texts": {}, + "baseResources": [] + }, + "AbpLocalization": { + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "Default language", + "Description:Abp.Localization.DefaultLanguage": "The default language of the application." + }, + "baseResources": [] + }, + "AbpValidation": { + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.", + "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", + "{0} is not valid.": "{0} is not valid.", + "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", + "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", + "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", + "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", + "The field {0} must match the regular expression '{1}'.": "The field {0} does not match the requested format.", + "The {0} field is required.": "The {0} field is required.", + "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", + "The field {0} is invalid.": "The field {0} is invalid.", + "The value '{0}' is invalid.": "The value '{0}' is invalid.", + "The field {0} must be a number.": "The field {0} must be a number.", + "The field must be a number.": "The field must be a number.", + "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", + "ThisFieldIsNotValid.": "This field is not valid.", + "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthOf{0}": "This field must be at most '{0}' characters long.", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be at least '{0}' characters long.", + "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", + "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", + "ThisFieldMustBeGreaterThanOrEqual{0}": "This field must be greater than or equal to {0}.", + "ThisFieldMustBeLessOrEqual{0}": "This field must be less than or equal to {0}.", + "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", + "ThisFieldIsRequired.": "This field is required.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be at most '{0}' characters long.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be at least {1} and at most {0} characters long.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", + "ThisFieldIsInvalid.": "This field is invalid." + }, + "baseResources": [] + }, + "AbpAuditLogging": { + "texts": { + "Permission:AuditLogging": "Audit logging", + "Permission:AuditLogs": "Audit logs", + "Menu:AuditLogging": "Audit logs", + "AuditLogs": "Audit logs", + "HttpStatus": "HTTP status", + "HttpMethod": "HTTP method", + "HttpMethodFilter": "HTTP method filter", + "HttpRequest": "HTTP Request", + "User": "User", + "UserNameFilter": "User filter", + "HasException": "Has exception", + "IpAddress": "IP address", + "Time": "Time", + "Date": "Date", + "Duration": "Duration", + "Detail": "Detail", + "Overall": "Overall", + "Actions": "Actions", + "ClientIpAddress": "Client IP Address", + "ClientName": "Client Name", + "BrowserInfo": "Browser Info", + "Url": "URL", + "UserName": "User name", + "TenantImpersonator": "Tenant Impersonator", + "UserImpersonator": "User Impersonator", + "UrlFilter": "URL filter", + "Exceptions": "Exceptions", + "Comments": "Comments", + "HttpStatusCode": "HTTP status code", + "HttpStatusCodeFilter": "HTTP status code filter", + "ServiceName": "Service", + "MethodName": "Method", + "CorrelationId": "Correlation Id", + "ApplicationName": "Application name", + "ExecutionDuration": "Duration", + "ExtraProperties": "Extra properties", + "MaxDuration": "Max. duration", + "MinDuration": "Min. duration", + "MinMaxDuration": "Duration (Min. - Max.)", + "{0}Milliseconds": "{0} milliseconds", + "ExecutionTime": "Time", + "Parameters": "Parameters", + "EntityTypeFullName": "Entity Type Full Name", + "Entity": "Entity", + "ChangeType": "Change type", + "ChangeTime": "Time", + "NewValue": "New value", + "OriginalValue": "Old value", + "PropertyName": "Property name", + "PropertyTypeFullName": "Property Type Full Name", + "Yes": "Yes", + "No": "No", + "Changes": "Changes", + "AverageExecutionDurationInLogsPerDay": "Average execution duration", + "AverageExecutionDurationInMilliseconds": "Average execution duration in milliseconds", + "ErrorRateInLogs": "Error rate in logs", + "Success": "Success", + "Fault": "Fault", + "NoChanges": "No change(s)", + "EntityChanges": "Entity changes", + "EntityId": "Entity Id", + "EntityChangeStartTime": "Min change date", + "EntityChangeEndTime": "Max change date", + "EntityHistory": "Entity history", + "DaysAgoTitle": "{0} {1}.", + "DaysAgoWithUserTitle": "{0} {1} by {2}.", + "MinutesAgo": "{0} minutes ago", + "HoursAgo": "{0} hours ago", + "DaysAgo": "{0} days ago", + "Created": "Created", + "Updated": "Updated", + "Deleted": "Deleted", + "ChangeHistory": "Change history", + "FullChangeHistory": "Full change history", + "ChangeDetails": "Change details", + "DurationMs": "Duration (ms)", + "StartDate": "Start date", + "EndDate": "End date", + "Feature:AuditLoggingGroup": "Audit logging", + "Feature:AuditLoggingEnable": "Enable audit logging page", + "Feature:AuditLoggingEnableDescription": "Enable audit logging page in the application.", + "Feature:AuditLoggingSettingManagementEnable": "Enable audit log setting management", + "Feature:AuditLoggingSettingManagementEnableDescription": "Enable the configuration of the audit log setting management within the application.", + "InvalidAuditLogDeletionSettings": "Invalid audit log deletion settings. If deletion is enable, the period should be greater than 0 days.", + "AuditLogSettingsGeneral": "General", + "AuditLogSettingsGlobal": "Global", + "DisplayName:IsPeriodicDeleterEnabled": "Enable clean up service system wide", + "Description:IsPeriodicDeleterEnabled": "If this option is disabled the periodic deleter won't work. Audit logs won't be deleted automatically.", + "DisplayName:GlobalIsExpiredDeleterEnabled": "Enable clean up service for all tenants and host", + "Description:GlobalIsExpiredDeleterEnabled": "If this option is enabled all the tenants and the host expired items will be deleted automatically unless it has a specific setting.", + "DisplayName:IsExpiredDeleterEnabled": "Enable clean up service", + "Description:IsExpiredDeleterEnabled": "If this option is enabled the expired items will be deleted automatically.", + "DisplayName:ExpiredDeleterPeriod": "Expired item deletion period", + "Description:ExpiredDeleterPeriod": "Set the number of days after which expired items will be automatically deleted.", + "ExpiredDeleterPeriodUnit": "day(s)", + "AuditLogsBeforeXWillBeDeleted": "Audit logs before {0} will be deleted.", + "TenantId": "Tenant Id", + "Permission:Export": "Export audit logs", + "ExportToExcel": "Export to Excel", + "Exporting": "Exporting", + "ExportCompleted": "Export completed successfully", + "ExportFailed": "Export failed", + "ThereWereNoRecordsToExport": "There were no records to export.", + "ExportJobQueued": "Export job has been queued for {0} records. You will receive an email when the export is completed.", + "ExportReady": "Export completed for {0} records and is ready for download.", + "FileName": "File name", + "TotalRecords": "Total records", + "ExcelFileAttachedMessage": "The Excel file is attached to this email.", + "EntityChangeExportCompletedSubject": "Entity change export completed", + "AuditLogExportCompletedSubject": "Audit log export completed", + "DownloadLinkExplanation": "You can download the file using the link below until {0} (UTC)", + "DownloadNow": "Download now", + "TryAgainMessage": "Please try again. If the problem persists, please contact support." + }, + "baseResources": [ + "AbpValidation" + ] + }, + "AbpTiming": { + "texts": { + "DisplayName:Abp.Timing.Timezone": "Timezone", + "Description:Abp.Timing.Timezone": "Application time zone" + }, + "baseResources": [] + }, + "AbpFeatureManagement": { + "texts": { + "Features": "Features", + "NoFeatureFoundMessage": "There isn't any available feature.", + "ManageHostFeatures": "Manage host features", + "ManageHostFeaturesText": "You can manage the host side features by clicking the following button.", + "Permission:FeatureManagement": "Feature management", + "Permission:FeatureManagement.ManageHostFeatures": "Manage host features", + "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0} feature value is not valid!", + "Menu:FeatureManagement": "Feature management", + "ResetToDefault": "Reset to default", + "ResetedToDefault": "Reseted to default", + "AreYouSure": "Are you sure?", + "AreYouSureToResetToDefault": "Are you sure to reset to default?" + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "AbpMultiTenancy": { + "texts": { + "TenantNotFoundMessage": "Tenant not found!", + "TenantNotFoundDetails": "There is no tenant with the tenant id or name: {0}", + "TenantNotActiveMessage": "Tenant is not active!", + "TenantNotActiveDetails": "The tenant is not active with the tenant id or name: {0}" + }, + "baseResources": [] + }, + "AbpFeature": { + "texts": { + "Volo.Feature:010001": "Feature is not enabled: {FeatureName}", + "Volo.Feature:010002": "Required features are not enabled. All of these features must be enabled: {FeatureNames}", + "Volo.Feature:010003": "Required features are not enabled. At least one of these features must be enabled: {FeatureNames}" + }, + "baseResources": [] + }, + "AbpIdentity": { + "texts": { + "Menu:IdentityManagement": "Identity management", + "Users": "Users", + "NewUser": "New user", + "UserName": "User name", + "Surname": "Surname", + "EmailAddress": "Email address", + "PhoneNumber": "Phone number", + "UserInformations": "User Information", + "DisplayName:IsDefault": "Default", + "DisplayName:IsStatic": "Static", + "DisplayName:IsPublic": "Public", + "Roles": "Roles", + "Password": "Password", + "PersonalInfo": "My profile", + "PersonalSettings": "Personal settings", + "UserDeletionConfirmationMessage": "User '{0}' will be deleted. Do you confirm that?", + "RoleDeletionConfirmationMessage": "Role '{0}' will be deleted. Do you confirm that?", + "DisplayName:RoleName": "Role name", + "DisplayName:UserName": "User name", + "DisplayName:Name": "Name", + "DisplayName:Surname": "Surname", + "DisplayName:Password": "Password", + "DisplayName:Email": "Email address", + "DisplayName:PhoneNumber": "Phone number", + "DisplayName:TwoFactorEnabled": "Two factor verification", + "DisplayName:IsActive": "Active", + "DisplayName:LockoutEnabled": "Account lockout", + "Description:LockoutEnabled": "Lock account after failed login attempts", + "NewRole": "New role", + "RoleName": "Role name", + "CreationTime": "Creation time", + "Permissions": "Permissions", + "DisplayName:CurrentPassword": "Current password", + "DisplayName:NewPassword": "New password", + "DisplayName:NewPasswordConfirm": "Confirm new password", + "PasswordChangedMessage": "Your password has been changed successfully.", + "PersonalSettingsSavedMessage": "Your personal settings has been saved successfully.", + "Volo.Abp.Identity:DefaultError": "An unknown failure has occurred.", + "Volo.Abp.Identity:ConcurrencyFailure": "Optimistic concurrency check has been failed. The entity you're working on has modified by another user. Please discard your changes and try again.", + "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' is already taken.", + "Volo.Abp.Identity:DuplicateRoleName": "Role name '{0}' is already taken.", + "Volo.Abp.Identity:DuplicateUserName": "Username '{0}' is already taken.", + "Volo.Abp.Identity:InvalidEmail": "Email '{0}' is invalid.", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "The provided PasswordHasherCompatibilityMode is invalid.", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "The iteration count must be a positive integer.", + "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", + "Volo.Abp.Identity:InvalidToken": "Invalid token.", + "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid.", + "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", + "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", + "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", + "Volo.Abp.Identity:PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z').", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character.", + "Volo.Abp.Identity:PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z').", + "Volo.Abp.Identity:PasswordTooShort": "Passwords must be at least {0} characters.", + "Volo.Abp.Identity:PasswordRequiresUniqueChars": "Passwords must use at least {0} different characters.", + "Volo.Abp.Identity:PasswordInHistory": "Passwords must not match your last {0} passwords.", + "Volo.Abp.Identity:RoleNotFound": "Role {0} does not exist.", + "Volo.Abp.Identity:UserAlreadyHasPassword": "User already has a password set.", + "Volo.Abp.Identity:UserAlreadyInRole": "User already in role '{0}'.", + "Volo.Abp.Identity:UserLockedOut": "User is locked out.", + "Volo.Abp.Identity:UserLockoutNotEnabled": "Lockout is not enabled for this user.", + "Volo.Abp.Identity:UserNameNotFound": "User {0} does not exist.", + "Volo.Abp.Identity:UserNotInRole": "User is not in role '{0}'.", + "Volo.Abp.Identity:PasswordConfirmationFailed": "Password does not match the confirm password.", + "Volo.Abp.Identity:NullSecurityStamp": "User security stamp cannot be null.", + "Volo.Abp.Identity:RecoveryCodeRedemptionFailed": "Recovery code redemption failed.", + "Volo.Abp.Identity:010001": "You can not delete your own account!", + "Volo.Abp.Identity:010002": "Can not set more than {MaxUserMembershipCount} organization unit for a user!", + "Volo.Abp.Identity:010003": "Can not change password of an externally logged in user!", + "Volo.Abp.Identity:010004": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.", + "Volo.Abp.Identity:010005": "Static roles can not be renamed.", + "Volo.Abp.Identity:010006": "Static roles can not be deleted.", + "Volo.Abp.Identity:010007": "You can't change your two factor setting.", + "Volo.Abp.Identity:010008": "It's not allowed to change two factor setting.", + "Volo.Abp.Identity:010009": "You can not delegate yourself.", + "Volo.Abp.Identity:010021": "Name exist: '{0}'.", + "Volo.Abp.Identity:010022": "Can not update a static ClaimType.", + "Volo.Abp.Identity:010023": "Can not delete a static ClaimType.", + "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximum allowed organization unit membership count for a user", + "ThisUserIsNotActiveMessage": "This user is not active.", + "Permission:IdentityManagement": "Identity management", + "Permission:RoleManagement": "Role management", + "Permission:Create": "Create", + "Permission:Edit": "Edit", + "Permission:Delete": "Delete", + "Permission:ChangePermissions": "Change permissions", + "Permission:ManageRoles": "Manage roles", + "Permission:UserManagement": "User management", + "Permission:UserLookup": "User lookup", + "DisplayName:Abp.Identity.Password.RequiredLength": "Required length", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Required unique characters number", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Required non-alphanumeric character", + "DisplayName:Abp.Identity.Password.RequireLowercase": "Required lower case character", + "DisplayName:Abp.Identity.Password.RequireUppercase": "Required upper case character", + "DisplayName:Abp.Identity.Password.RequireDigit": "Required digit", + "DisplayName:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "Force users to periodically change password", + "DisplayName:Abp.Identity.Password.PasswordChangePeriodDays": "Password change period(days)", + "DisplayName:Abp.Identity.Password.EnablePreventPasswordReuse": "Enable prevent password reuse", + "DisplayName:Abp.Identity.Password.PreventPasswordReuseCount": "Prevent password reuse count", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "Enabled for new users", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "Lockout duration(seconds)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Max failed access attempts", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "Enforce email verification to sign in", + "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Allow users to confirm their phone number", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Enforce phone number verification to sign in", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "Allow users to change their usernames", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "Allow users to change their email addresses", + "Description:Abp.Identity.Password.RequiredLength": "The minimum length a password must be.", + "Description:Abp.Identity.Password.RequiredUniqueChars": "The minimum number of unique characters which a password must contain.", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "If passwords must contain a non-alphanumeric character.", + "Description:Abp.Identity.Password.RequireLowercase": "If passwords must contain a lower case ASCII character.", + "Description:Abp.Identity.Password.RequireUppercase": "If passwords must contain a upper case ASCII character.", + "Description:Abp.Identity.Password.RequireDigit": "If passwords must contain a digit.", + "Description:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "Whether users are forced to periodically change their password.", + "Description:Abp.Identity.Password.PasswordChangePeriodDays": "The number of days a user's password is valid for.", + "Description:Abp.Identity.Password.EnablePreventPasswordReuse": "Whether to prevent users from reusing their previous passwords.", + "Description:Abp.Identity.Password.PreventPasswordReuseCount": "The number of previous passwords that cannot be reused.", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "Whether a new user can be locked out.", + "Description:Abp.Identity.Lockout.LockoutDuration": "The duration a user is locked out for when a lockout occurs.", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "The number of failed access attempts allowed before a user is locked out, assuming lock out is enabled.", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "Users can create accounts but cannot sign in until they verify their email address.", + "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Users can verify their phone numbers. SMS integration required.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Users can create accounts but cannot sign in until they verify their phone numbers.", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Whether the username can be updated by the user.", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Whether the email can be updated by the user.", + "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Enforce email verification to register", + "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "User accounts will not be created unless they verify their email addresses.", + "Details": "Details", + "CreatedBy": "Created by", + "ModifiedBy": "Modified by", + "ModificationTime": "Modification time", + "PasswordUpdateTime": "Password update time", + "LockoutEndTime": "Lockout end time", + "FailedAccessCount": "Failed access count", + "UserResourcePermissionProviderKeyLookupService": "User", + "RoleResourcePermissionProviderKeyLookupService": "Role" + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "AbpOpenIddict": { + "texts": { + "TheOpenIDConnectRequestCannotBeRetrieved": "The OpenID Connect request cannot be retrieved.", + "TheUserDetailsCannotBbeRetrieved": "The user details cannot be retrieved.", + "TheApplicationDetailsCannotBeFound": "The application details cannot be found.", + "DetailsConcerningTheCallingClientApplicationCannotBeFound": "Details concerning the calling client application cannot be found.", + "TheSpecifiedGrantTypeIsNotImplemented": "The specified grant type {0} is not implemented.", + "Authorization": "Authorization", + "DoYouWantToGrantAccessToYourData": "Do you want to grant {0} access to your data?", + "ScopesRequested": "Scopes requested", + "Accept": "Accept", + "Deny": "Deny", + "ApplicationResourcePermissionProviderKeyLookupService": "Client" + }, + "baseResources": [ + "AbpValidation" + ] + }, + "AbpPermissionManagement": { + "texts": { + "Permissions": "Permissions", + "OnlyProviderPermissons": "Only this provider", + "All": "All", + "SelectAllInAllTabs": "Grant all permissions", + "SelectAllInThisTab": "Select all", + "SaveWithoutAnyPermissionsWarningMessage": "Are you sure you want to save without any permissions?", + "PermissionGroup": "Permission Group", + "Filter": "Filter", + "ResourcePermissions": "Permissions", + "ResourcePermissionTarget": "Target", + "ResourcePermissionPermissions": "Permissions", + "AddResourcePermission": "Add permission", + "ResourcePermissionDeletionConfirmationMessage": "Are you sure you want to delete all permissions?", + "UpdateResourcePermission": "Update permission", + "GrantAllResourcePermissions": "Grant all", + "NoResourceProviderKeyLookupServiceFound": "There is no provider key lookup service was found", + "NoResourcePermissionFound": "There is no permission defined.", + "UpdatePermission": "Update permission", + "NoPermissionsAssigned": "No permissions assigned", + "SelectProvider": "Select provider", + "SearchProviderKey": "Search provider key", + "Provider": "Provider", + "ErrorLoadingPermissions": "Error loading permissions", + "PleaseSelectProviderAndPermissions": "Please select provider and permissions" + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "AbpSettingManagement": { + "texts": { + "Settings": "Settings", + "SavedSuccessfully": "Saved successfully", + "Permission:SettingManagement": "Setting management", + "Permission:Emailing": "Emailing", + "Permission:EmailingTest": "Emailing test", + "Permission:TimeZone": "Time zone", + "SendTestEmail": "Send test email", + "SenderEmailAddress": "Sender email address", + "TargetEmailAddress": "Target email address", + "Subject": "Subject", + "Body": "Body", + "TestEmailSubject": "Test email {0}", + "TestEmailBody": "Test email body message here", + "SentSuccessfully": "Sent successfully", + "MailSendingFailed": "Mail sending failed, please check your email configuration and try again.", + "Send": "Send", + "Menu:Settings": "Settings", + "Menu:Emailing": "Emailing", + "Menu:TimeZone": "Time Zone", + "DisplayName:Timezone": "Time zone", + "TimezoneHelpText": "This feature allows you to set a default time zone for your server, while users can select their own. If a user's time zone differs from the server's, all times will adjust accordingly. For example, with the server set to Europe/London(00:00) and a user in Europe/Paris(+01:00), times will be adjusted by 1 hour for that user. Selecting 'Default Timezone' will automatically use the server's or browser's time zone.", + "DefaultTimeZone": "Default time zone", + "SmtpHost": "Host", + "SmtpPort": "Port", + "SmtpUserName": "User name", + "SmtpPassword": "Password", + "SmtpDomain": "Domain", + "SmtpEnableSsl": "Enable ssl", + "SmtpUseDefaultCredentials": "Use default credentials", + "DefaultFromAddress": "Default from address", + "DefaultFromDisplayName": "Default from display name", + "Feature:SettingManagementGroup": "Setting management", + "Feature:SettingManagementEnable": "Enable setting management", + "Feature:SettingManagementEnableDescription": "Enable setting management system in the application.", + "Feature:AllowChangingEmailSettings": "Allow changing email settings", + "Feature:AllowChangingEmailSettingsDescription": "Allow changing email settings.", + "SmtpPasswordPlaceholder": "Enter a value to update password" + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "AbpTenantManagement": { + "texts": { + "Volo.Abp.TenantManagement:DuplicateTenantName": "Tenant name already exist: {Name}", + "Menu:TenantManagement": "Tenant management", + "Tenants": "Tenants", + "NewTenant": "New tenant", + "TenantName": "Tenant name", + "DisplayName:TenantName": "Tenant Name", + "TenantDeletionConfirmationMessage": "Tenant '{0}' will be deleted. Do you confirm that?", + "ConnectionStrings": "Connection Strings", + "DisplayName:DefaultConnectionString": "Default Connection String", + "DisplayName:UseSharedDatabase": "Use the Shared Database", + "Permission:TenantManagement": "Tenant management", + "Permission:Create": "Create", + "Permission:Edit": "Edit", + "Permission:Delete": "Delete", + "Permission:ManageConnectionStrings": "Manage connection strings", + "Permission:ManageFeatures": "Features", + "DisplayName:AdminEmailAddress": "Admin Email Address", + "DisplayName:AdminPassword": "Admin Password" + }, + "baseResources": [ + "AbpValidation", + "AbpFeatureManagement", + "AbpUi" + ] + }, + "Notifications": { + "texts": { + "MyAccount": "My account", + "SamplePageMessage": "A sample page for the Notifications module", + "Permission:NotificationsPermissions.Settings": "Configure Notifications", + "Setting:Notifications": "Notifications", + "Setting:Notifications.Mailing.DefaultFromAddress.DisplayName": "From Address", + "Setting:Notifications.Mailing.DefaultFromAddress.Description": "The default From sender address", + "Permission:Notifications": "Notifications", + "Permission:Notifications.Email": "Email", + "Permission:Notifications.Email.Send": "Send Email" + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "Flex": { + "texts": { + "MyAccount": "My account", + "SamplePageMessage": "A sample page for the Flex module", + "Scoresheet:Configuration:ScoresheetModal.Title": "Title", + "Scoresheet:Configuration:SectionModal.Name": "Name", + "Scoresheet:Configuration:QuestionModal.Name": "Name", + "Scoresheet:Configuration:QuestionModal.Label": "Question", + "Scoresheet:Configuration:QuestionModal.Description": "Description", + "Scoresheet:Configuration:QuestionModal.QuestionType": "Question Type", + "Scoresheet:Configuration:AddScoresheetButtonText": "ADD SCORESHEET", + "Scoresheet:Configuration:AddQuestionButtonText": "ADD QUESTION", + "Scoresheet:Configuration:AddSectionButtonText": "ADD SECTION", + "Scoresheet:Configuration:EditScoresheetButtonText": "EDIT SCORESHEET", + "Scoresheet:Configuration:CloneScoresheetButtonText": "CLONE SCORESHEET", + "Scoresheet:Configuration:PublishScoresheetButtonText": "PUBLISH SCORESHEET", + "Scoresheet:Configuration:ExportScoresheetButtonText": "EXPORT SCORESHEET", + "Scoresheet:Configuration:SaveChangesButtonText": "SAVE CHANGES", + "Scoresheet:Configuration:DiscardChangesButtonText": "DISCARD CHANGES", + "Worksheet:Configuration:SaveChangesButtonText": "SAVE CHANGES", + "Worksheet:Configuration:DiscardChangesButtonText": "DISCARD CHANGES", + "Worksheet:Configuration:EditWorksheetButtonText": "Edit", + "Worksheet:Configuration:AddCustomFieldButtonText": "Add Field", + "Worksheet:Configuration:AddSectionButtonText": "ADD SECTION", + "Worksheet:Configuration:AddWorksheetButtonText": "ADD", + "Worksheet:Configuration:LinkWorksheetButtonText": "Link", + "Worksheet:Configuration:CloneWorksheetButtonText": "Clone", + "Worksheet:Configuration:PublishWorksheetButtonText": "Publish", + "Worksheet:Configuration:DeleteWorksheetButtonText": "Delete", + "Worksheet:Configuration:AddCheckboxOptionText": "Add Option", + "Worksheet:Configuration:ExportWorksheetButtonText": "Export", + "Worksheet:Configuration:AddSelectListOptionText": "Add Option", + "Worksheet:Configuration:AddColumnOptionText": "Add Column", + "DataGrids:DynamicColumnsHeader": "Dynamic Columns", + "DataGrids:CustomColumnsHeader": "Custom Columns", + "DataGrids:PredefinedColumn": "Predefined column", + "Permission:Flex.Worksheets": "Configure Worksheet", + "Permission:Flex.Worksheets.Delete": "Delete Worksheet" + }, + "baseResources": [ + "AbpValidation" + ] + }, + "Payments": { + "texts": { + "Payments": "Payments", + "WelcomeToPayments": "Welcome to Payments Module", + "Unity.Payments:Errors:ThresholdExceeded": "There are payments in this batch that require a third level of approval. Please remove them from this batch and add to another for the appropriate level of approval", + "Unity.Payments:Errors:ZeroPayment": "Cannot submit a payment request for $0.00", + "Unity.Payments:Errors:MissingSupplierNumber": "Cannot submit a payment request without a supplier number", + "Unity.Payments:Errors:ConfigurationExists": "Configuration already exitst", + "Unity.Payments:Errors:ConfigurationDoesNotExist": "Configuration does not exits", + "Unity.Payments:Errors:InvalidAccountCodingFiled": "Invalid account coding field {field} : {length}", + "Unity.Payments:Errors:L2ApproverRestriction": "You cannot approve one or more selected payments as you have already approved them as an L1 Approver.", + "Setting:Payments.ThresholdAmount.DisplayName": "Payment threshold amount", + "Setting:Payments.ThresholdAmount.Description": "Payment threshold that triggers additional approvals and checks", + "ApplicationPaymentRequest:Title": "Request Payment", + "ApplicationPaymentRequest:Amount": "Amount", + "ApplicationPaymentRequest:Description": "Description", + "ApplicationPaymentRequest:SiteName": "Site Name", + "ApplicationPaymentRequest:InvoiceNumber": "Invoice #", + "ApplicationPaymentRequest:SiteNumber": "Site #", + "ApplicationPaymentRequest:SubmitButtonText": "Submit Payment Requests", + "ApplicationPaymentRequest:CancelButtonText": "Cancel", + "ApplicationPaymentRequest:BatchNumberName": "Batch #", + "ApplicationPaymentRequest:NumberPayment": "Number of Payments", + "ApplicationPaymentRequest:TotalAmount": "Total Amount", + "ApplicationPaymentRequest:AccountCodingOverride": "Account Coding Override", + "ApplicationPaymentRequest:AccountCodingOverrideWarning": "An overridden account code is being used for this payment request.", + "ApplicationPaymentRequest:BatchNote": "Note", + "ApplicationPaymentRequest:Validations:RemainingAmountExceeded": "Cannot add a payment that exceeds the remaining amount of ", + "ApplicationPaymentRequest:Validations:L2ApproverRestriction": "You cannot approve this payment as you have already approved it as an L1 Approver.", + "ApplicationPaymentRequest:Validations:L2ApproverRestrictionBatch": "Highlighted payments were already approved with L1 permission. L1 and L2 approvers must be different individuals", + "ApplicationPaymentTable:BatchNumber": "Batch Number", + "ApplicationPaymentTable:TotalAmount": "Total Amount", + "ApplicationPaymentTable:Status": "Status", + "ApplicationPaymentTable:RequestedOn": "Requested On", + "ApplicationPaymentListTable:SubmissionConfirmationCode": "Submission #", + "ApplicationPaymentListTable:PaymentRequesterName": "Payment Requester", + "ApplicationPaymentListTable:L1ApproverName": "L1 Approver", + "ApplicationPaymentListTable:L2ApproverName": "L2 Approver", + "ApplicationPaymentListTable:L3ApproverName": "L3 Approver", + "ApplicationPaymentListTable:L1ApprovalDate": "L1 Approval Date", + "ApplicationPaymentListTable:L2ApprovalDate": "L2 Approval Date", + "ApplicationPaymentListTable:L3ApprovalDate": "L3 Approval Date", + "ApplicationPaymentListTable:BatchName": "Batch #", + "ApplicationPaymentListTable:PaymentID": "Payment ID", + "ApplicationPaymentListTable:ApplicantName": "Applicant Name", + "ApplicationPaymentListTable:SupplierNumber": "Supplier Number", + "ApplicationPaymentListTable:SiteNumber": "Site Number", + "ApplicationPaymentListTable:ContractNumber": "Contract Number", + "ApplicationPaymentListTable:InvoiceNumber": "Invoice Number", + "ApplicationPaymentListTable:PayGroup": "Pay Group", + "ApplicationPaymentListTable:Amount": "Amount", + "ApplicationPaymentListTable:Status": "Status", + "ApplicationPaymentListTable:Description": "Description", + "ApplicationPaymentListTable:RequestedOn": "Requested On", + "ApplicationPaymentListTable:UpdatedOn": "Updated On", + "ApplicationPaymentListTable:PaidOn": "Paid On", + "ApplicationPaymentListTable:CASResponse": "CAS Response", + "ApplicationPaymentListTable:InvoiceStatus": "Invoice Status", + "ApplicationPaymentListTable:PaymentStatus": "CAS Payment Status", + "ApplicationPaymentListTable:Note": "Note", + "ApplicationPaymentListTable:FsbApNotified": "FSB-AP Notified", + "ApplicantInfoView:SupplierInfoTitle": "Supplier Info", + "ApplicantInfoView:ApplicantInfo:SupplierNumber": "Supplier #", + "ApplicantInfoView:ApplicantInfo.SiteInfo:SiteNumber": "Site #", + "ApplicantInfoView:ApplicantInfo.SiteInfo:PayGroup": "Pay Group", + "ApplicantInfoView:ApplicantInfo.SiteInfo:MailingAddress": "Mailing Address", + "ApplicantInfoView:ApplicantInfo.SiteInfo:AddSiteButtonText": "ADD SITE", + "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine1": "Address Line 1", + "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine2": "Address Line 2", + "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine3": "Address Line 3", + "ApplicantInfoView:ApplicantInfo.SiteInfo:City": "City", + "ApplicantInfoView:ApplicantInfo.SiteInfo:Province": "Province", + "ApplicantInfoView:ApplicantInfo.SiteInfo:PostalCode": "Postal Code", + "ApplicantInfoView:ApplicantInfo.Search": "Search In BC Registries (Registered Socities Only)", + "PaymentInfoView:PaymentInfoTitle": "Payment Summary", + "PaymentInfoView:PaymentInfo.RequestedAmount": "Requested Amount", + "PaymentInfoView:PaymentInfo.RecommendedAmount": "Recommended Amount", + "PaymentInfoView:PaymentInfo.ApprovedAmount": "Approved Amount", + "PaymentInfoView:PaymentInfo.TotalPendingAmounts": "Total Pending Amounts", + "PaymentInfoView:PaymentInfo.TotalPaid": "Total Paid", + "PaymentInfoView:PaymentInfo.RemainingAmount": "Remaining Amount", + "PaymentInfoView:PaymentInfoTableTitle": "Payment List", + "PaymentInfoView:ApplicationPaymentListTable.PaymentID": "Payment ID", + "PaymentInfoView:ApplicationPaymentListTable.Amount": "Amount", + "PaymentInfoView:ApplicationPaymentListTable.Status": "Status", + "PaymentInfoView:ApplicationPaymentListTable.Description": "Description", + "PaymentInfoView:ApplicationPaymentListTable.MailingAddress": "Mailing Address", + "PaymentInfoView:ApplicationPaymentListTable.MaskedBankAccount": "Bank Account", + "PaymentInfoView:ApplicationPaymentListTable.SiteNumber": "Site Number", + "PaymentInfoView:ApplicationPaymentListTable.SupplierNumber": "Supplier Number", + "PaymentInfoView:ApplicationPaymentListTable.SupplierName": "Supplier Name", + "PaymentInfoView:ApplicationPaymentListTable.RequestedOn": "Requested On", + "PaymentInfoView:ApplicationPaymentListTable.UpdatedOn": "Updated On", + "PaymentInfoView:ApplicationPaymentListTable.PaidOn": "Paid On", + "PaymentInfoView:ApplicationPaymentListTable.CASResponse": "CAS Response", + "ApplicationPaymentStatusRequest:ApproveTitle": "Approve Payments", + "ApplicationPaymentStatusRequest:DeclineTitle": "Decline Payments", + "ApplicationPaymentStatusRequest:Id": "Payment Id", + "ApplicationPaymentStatusRequest:Amount": "Amount", + "ApplicationPaymentStatusRequest:Description": "Description", + "ApplicationPaymentStatusRequest:CancelButtonText": "Cancel", + "ApplicationPaymentStatusRequest:ApproveButtonText": "Approve Payments", + "ApplicationPaymentStatusRequest:DeclineButtonText": "Decline Payments", + "ApplicationPaymentStatusRequest:L1ApproveOrDeclineTitle": "Approve/Decline L1 Payment Requests", + "ApplicationPaymentStatusRequest:L2ApproveOrDeclineTitle": "Approve/Decline L2 Payment Requests", + "ApplicationPaymentStatusRequest:L3ApproveOrDeclineTitle": "Approve/Decline L3 Payment Requests", + "Permission:Payments": "Payments", + "Permission:Payments.Default": "Payments", + "Permission:Payments.L1ApproveOrDecline": "Approve/Decline L1 Payments", + "Permission:Payments.L2ApproveOrDecline": "Approve/Decline L2 Payments", + "Permission:Payments.L3ApproveOrDecline": "Approve/Decline L3 Payments", + "Permission:Payments.RequestPayment": "Request Payment", + "Permission:Payments.AccountCodingOverride": "Override Account Coding", + "Permission:Payments.EditFormPaymentConfiguration": "Edit Form Payment Configuration", + "Enum:PaymentRequestStatus.L1Pending": "L1 Pending", + "Enum:PaymentRequestStatus.L1Approved": "L1 Approved", + "Enum:PaymentRequestStatus.L1Declined": "L1 Declined", + "Enum:PaymentRequestStatus.L2Pending": "L2 Pending", + "Enum:PaymentRequestStatus.L2Approved": "L2 Approved", + "Enum:PaymentRequestStatus.L2Declined": "L2 Declined", + "Enum:PaymentRequestStatus.L3Pending": "L3 Pending", + "Enum:PaymentRequestStatus.L3Approved": "L3 Approved", + "Enum:PaymentRequestStatus.L3Declined": "L3 Declined", + "Enum:PaymentRequestStatus.Submitted": "Submitted to CAS", + "Enum:PaymentRequestStatus.FSB": "Sent to Accounts Payable", + "Enum:PaymentRequestStatus.Validated": "Validated", + "Enum:PaymentRequestStatus.NotValidated": "Not Validated", + "Enum:PaymentRequestStatus.Paid": "Paid", + "Enum:PaymentRequestStatus.Failed": "Payment Failed", + "Enum:PaymentRequestStatus.PaymentFailed": "Payment Failed", + "Unity.GrantManager.ApplicationManagement.Payment": "Payment Info", + "Unity.GrantManager.ApplicationManagement.Payment.Summary": "Payment Summary", + "Unity.GrantManager.ApplicationManagement.Payment.Supplier": "Supplier Info", + "Unity.GrantManager.ApplicationManagement.Payment.Supplier.Update": "Edit Supplier Info", + "Unity.GrantManager.ApplicationManagement.Payment.PaymentList": "Payment List", + "Unity.Payments.Tags.Create": "Assign Tag to Payments", + "Unity.Payments.Tags.Delete": "Remove Tag from Payments" + }, + "baseResources": [ + "AbpValidation" + ] + }, + "Reporting": { + "texts": { + "Permission:Reporting": "Reporting", + "Permission:Reporting.Configuration.Default": "Reporting Configurations - Default (View)", + "Permission:Reporting.Configuration.Update": "Update Reporting Configurations", + "Permission:Reporting.Configuration.Delete": "Delete Reporting Configurations", + "Setting:GrantManager.Reporting.ViewRole.DisplayName": "[DEPRECATED] Global View Role", + "Setting:GrantManager.Reporting.ViewRole.Description": "[DEPRECATED] This global setting is deprecated. Use tenant-specific view role configuration instead.", + "Setting:GrantManager.Reporting.TenantViewRole.DisplayName": "Tenant View Role", + "Setting:GrantManager.Reporting.TenantViewRole.Description": "The database role to assign to generated reporting views for this specific tenant" + }, + "baseResources": [ + "AbpValidation" + ] + }, + "GrantManager": { + "texts": { + "Menu:Home": "Home", + "Menu:Dashboard": "Dashboard", + "Menu:GrantPrograms": "Grant Programs", + "Menu:GrantTracker": "Grant Tracker", + "Menu:Applications": "Applications", + "Menu:Payments": "Payments", + "Menu:Scoring": "Scoring", + "Menu:Reporting": "Reporting", + "Menu:Welcome": "Welcome", + "Menu:Roles": "Roles", + "Menu:Users": "Users", + "Menu:Intakes": "Intakes", + "Menu:ApplicationForms": "Forms", + "Menu:TenantManagement": "Tenants", + "Menu:EndpointManagement": "Endpoints", + "Menu:Applicants": "Applicants", + "Menu:ConfigurationManagement": "Configuration Management", + "Welcome": "Welcome", + "LongWelcomeMessage": "Welcome to Unity Grant Manager", + "Enum:GrantProgramType.0": "Undefined", + "Enum:GrantProgramType.1": "Agriculture", + "Enum:GrantProgramType.2": "Arts, Culture and Sport", + "Enum:GrantProgramType.3": "Business", + "Enum:GrantProgramType.4": "Environment", + "Enum:GrantProgramType.5": "Research", + "Enum:GrantProgramType.6": "Jobs & Training", + "Common:Command:Edit": "Edit", + "Common:Command:Create": "Create", + "Common:Command:Update": "Update", + "Common:StartDate": "Start Date", + "Common:EndDate": "End Date", + "Common:Name": "Name", + "Common:Description": "Description", + "Common:Command:Search": "Search", + "Common:Command:Import": "Import", + "Common:Command:Select": "Select", + "GrantPrograms": "Grant Programs", + "GrantProgram": "Grant Program", + "GrantProgramType": "Sector", + "ProgramName": "Program Name", + "PublishDate": "Published", + "CreateDate": "Created", + "Sector": "Sector", + "GrantProgram_Create": "New Grant Program", + "GrantProgram_Update": "Edit Grant Program", + "Enum:GrantApplicationStatus.0": "Active", + "Enum:GrantApplicationStatus.1": "Scoring", + "Enum:GrantApplicationStatus.2": "Awaiting", + "Enum:GrantApplicationStatus.3": "On Hold", + "Enum:GrantApplicationStatus.4": "Approved", + "Enum:GrantApplicationStatus.5": "Assessing", + "Enum:GrantApplicationStatus.6": "Declined", + "ProjectName": "Project Name", + "ReferenceNo": "Reference No", + "EligibleAmount": "Eligible Amount", + "RequestedAmount": "Requested Amount", + "Assignee": "Assignee", + "Probability": "Probability", + "GrantApplicationStatus": "Status", + "ProposalDate": "Proposal Date", + "SubmissionDate": "Submission Date", + "GrantApplications": "Grant Applications", + "Applicants": "Applicants", + "Multiple": "Multiple", + "ApplicationList:OpenButton": "Open", + "ApplicationList:AssignButton": "Assign", + "ApplicationList:ApproveButton": "Approve", + "ApplicationList:StatusButton": "Status", + "ApplicationList:ApprovedButton": "Approved", + "ApplicationList:NotApprovedButton": "Not approved", + "ApplicationList:CopyLinkButton": "Copy link", + "ApplicationList:DownloadButton": "Download", + "ApplicationList:AddReviewButton": "Add Review", + "ApplicationList:FilterButton": "Filter", + "ApplicationList:SortButton": "Sort", + "ApplicationList:InfoButton": "Info", + "ApplicationList:StartAssessmentButton": "Start Assessment", + "ApplicationList:CompleteAssessmentButton": "Complete Assessment", + "ApplicationList:TagButton": "Tags", + "ApplicationList:ResyncSubmissionAttachmentsButton": "Resync", + "ApplicationList:ManageTagButton": "Manage Tags", + "ReviewerList:AssessorName": "Assessor Name", + "ReviewerList:StartDate": "Start Date", + "ReviewerList:EndDate": "End Date", + "ReviewerList:Status": "Status", + "ReviewerList:Recommended": "Recommendation", + "ReviewerList:FinancialAnalysis": "Financial Analysis", + "ReviewerList:EconomicImpact": "Economic Impact", + "ReviewerList:InclusiveGrowth": "Inclusive Growth", + "ReviewerList:CleanGrowth": "Clean Growth", + "ReviewerList:Subtotal": "Subtotal", + "ReviewerList:CloneAssessment": "Clone Assessment", + "AssessmentResultAttachments:Id": "#", + "AssessmentResultAttachments:DocumentName": "Document Name", + "AssessmentResultAttachments:UploadedDate": "Date", + "AssessmentResultAttachments:AttachedBy": "Attached by", + "ChefsAttachments:Title": "Submission Attachments", + "ChefsAttachments:Filter": "Filter", + "ChefsAttachments:Download": "Download", + "ChefsAttachments:GenerateSummaries": "Generate AI Summaries", + "ChefsAttachments:GenerateSummary": "Generate Summary", + "ChefsAttachments:HideAISummaries": "Hide AI Summaries", + "ChefsAttachments:ShowAISummaries": "Show AI Summaries", + "ChefsAttachments:HideSummaries": "Hide Summaries", + "ChefsAttachments:ShowSummaries": "Show Summaries", + "ChefsAttachments:NoSummariesAvailable": "No summaries available", + "Enum:AssessmentState.IN_PROGRESS": "In Progress", + "Enum:AssessmentState.IN_REVIEW": "Under Review by Team Lead", + "Enum:AssessmentState.COMPLETED": "Completed", + "Enum:AssessmentAction.Create": "Create Assessment", + "Enum:AssessmentAction.SendBack": "Send Back", + "Enum:AssessmentAction.Complete": "Complete Assessment", + "Permission:GrantManagerManagement": "Grant Manager Management", + "Permission:GrantManagerManagement.Default": "Default", + "Permission:GrantApplicationManagement": "Grant Application Management", + "Permission:GrantApplicationManagement.Dashboard.Default": "Dashboard", + "Permission:GrantApplicationManagement.Dashboard.ViewDashboard": "View Dashboard", + "Permission:GrantApplicationManagement.Dashboard.ApplicationStatusCount": "View Submissions by Status", + "Permission:GrantApplicationManagement.Dashboard.EconomicRegionCount": "View Submissions by Economic Region", + "Permission:GrantApplicationManagement.Dashboard.ApplicationTagsCount": "View Application Tags Overview", + "Permission:GrantApplicationManagement.Dashboard.ApplicationAssigneeCount": "View Application Assignee Overview", + "Permission:GrantApplicationManagement.Dashboard.RequestedAmountPerSubsector": "View Total Funding Requested per Sub-Sector", + "Permission:GrantApplicationManagement.Dashboard.RequestApprovedCount": "View Requested vs. Approved Funding", + "Permission:GrantApplicationManagement.Applications.Default": "Applications", + "Permission:GrantApplicationManagement.Applicants.Default": "Applicants", + "Permission:GrantApplicationManagement.Applicants.Edit": "Edit Applicant", + "Permission:GrantApplicationManagement.Applicants.ViewList": "View Applicant List", + "Permission:GrantApplicationManagement.Applicants.AssignApplicant": "Assign Applicant to an Application", + "Permission:GrantApplicationManagement.Applicants.ApplicantInfo": "Applicant Info", + "Permission:GrantApplicationManagement.Applicants.ApplicantInfo.EditRedStop": "Edit Red-Stop", + "Permission:GrantApplicationManagement.Assignments.Default": "Assignment", + "Permission:GrantApplicationManagement.Assignments.AssignInitial": "Initial Assignment", + "Permission:GrantApplicationManagement.Reviews.Default": "Reviews", + "Permission:GrantApplicationManagement.Reviews.StartInitial": "Start Initial Review", + "Permission:GrantApplicationManagement.Reviews.CompleteInitial": "Complete Initial Review", + "Permission:GrantApplicationManagement.Assessments.Default": "Assessments", + "Permission:GrantApplicationManagement.Assessments.Start": "Start Assessment", + "Permission:GrantApplicationManagement.Assessments.Complete": "Complete Assessment", + "Permission:GrantApplicationManagement.Approvals.Default": "Approvals", + "Permission:GrantApplicationManagement.Approvals.Complete": "Complete Approval", + "Permission:GrantApplicationManagement.Approvals.DeferAfterApproval": "Defer After Approval", + "Permission:GrantApplicationManagement.Comments.Default": "Comments", + "Permission:GrantApplicationManagement.Comments.Add": "Add Application Comment", + "Permission:GrantApplicationManagement.Organizations.Default": "Organizations", + "Permission:GrantApplicationManagement.Organizations.ManageProfiles": "Manage Organization Profiles", + "Permission:GrantManagerManagement.Intakes.Default": "Manage Intakes", + "Permission:GrantManagerManagement.ApplicationForms.Default": "Manage Forms", + "Permission:GrantApplicationManagement.Approvals.BulkApplicationApproval": "Bulk Application Approval", + "Permission:GrantApplicationManagement.AIReporting.Default": "AI Reporting", + "ApplicationForms": "Forms", + "ApplicationForms:Description": "Description", + "ApplicationForms:ChefsFormId": "CHEFS Form Id", + "ApplicationForms:SubmissionHeaderMapping": "Mapping", + "ApplicationForms:ChefsFormVersionGuid": "CHEFS Form Version", + "ApplicationForms:ChefsCriteriaFormId": "CHEFS Criteria Form Id", + "ApplicationForms:ChefsFormApiKey": "CHEFS Form Api Key", + "ApplicationForms:Category": "Category", + "ApplicationForms:FormApiToken": "API Token", + "ApplicationForms:Mapping": "Mapping", + "ApplicationForms:APIConfiguration": "API Configuration", + "ApplicationForms:DownloadAPIConfiguration": "Download API Configuration", + "ApplicationForms:UpdateAPIToken": "Update API Token", + "ApplicationForms:Payable": "Payable", + "ApplicationForms:RenderFormIoToHtml": "Render FormIO to HTML", + "ApplicationForms:ConfigureWorksheets": "Configure Worksheets", + "ApplicationForms.Configuration.Notes:BypassAssessmentWorkflow": "Enabling this feature will bypass the Assessment workflow when you approve submissions associated with this form.", + "ApplicationForms.Configuration.Notes:SelectedApplicantElectoralAddress": "The selected address type will determine which submitted applicant address is used to extract the electoral district.", + "ApplicationForms.Configuration.Warnings:ApplicantElectoralAddressTypeChange": "Changing the address type will only affect new submissions. Existing applications will retain the electoral district extracted from their original address type.", + "Intakes": "Intakes", + "Unity.GrantManager.ApplicationManagement.Review.Approval": "Approval", + "Unity.GrantManager.ApplicationManagement.Review.Approval.Update": "Edit Approval Fields", + "Unity.GrantManager.ApplicationManagement.Review.Approval.Update.UpdateFinalStateFields": "Edit Approval fields after approval", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults": "Application Assessment Results", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults.Update": "Edit Application Assessment Result", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults.Update.UpdateFinalStateFields": "Edit Application Assessment Result after approval", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList": "Assessment List", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Create": "Create Assessment", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Update.SendBack": "Send Back Assessment", + "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Update.Complete": "Complete Assessment", + "Unity.GrantManager.ApplicationManagement.Review.Worksheet": "Review and Assessment Worksheet", + "Unity.GrantManager.ApplicationManagement.Review.Worksheet.Update": "Edit Review and Assessment Worksheet", + "Unity.GrantManager.ApplicationManagement.Review": "Review and Assessment", + "Unity.GrantManager.ApplicationManagement.Review.Results": "Application Assessment Results", + "Unity.GrantManager.ApplicationManagement.Review.Results.Update": "Edit Application Assessment Results", + "Unity.GrantManager.ApplicationManagement.Review.ReviewList": "Assessment List", + "Unity.GrantManager.ApplicationManagement.Project": "Project Info", + "Unity.GrantManager.ApplicationManagement.Project.Summary": "Project Summary", + "Unity.GrantManager.ApplicationManagement.Project.Summary.Update": "Edit Project Summary", + "Unity.GrantManager.ApplicationManagement.Project.Summary.Update.UpdateFinalStateFields": "Edit Project Summary after approval", + "Unity.GrantManager.ApplicationManagement.Project.Location": "Project Location", + "Unity.GrantManager.ApplicationManagement.Project.Location.Update": "Edit Project Location", + "Unity.GrantManager.ApplicationManagement.Project.Location.Update.UpdateFinalStateFields": "Edit Project Location after approval", + "Unity.GrantManager.ApplicationManagement.Applicant": "Applicant Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Summary": "Applicant Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Summary.Update": "Edit Applicant Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Contact": "Contact Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Contact.Create": "Create Contact Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Contact.Update": "Edit Contact Info", + "Unity.GrantManager.ApplicationManagement.Applicant.Authority": "Signing Authority", + "Unity.GrantManager.ApplicationManagement.Applicant.Authority.Update": "Edit Signing Authority", + "Unity.GrantManager.ApplicationManagement.Applicant.Location": "Address", + "Unity.GrantManager.ApplicationManagement.Applicant.Location.Update": "Edit Address", + "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact": "Additional Contact(s)", + "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact.Create": "Add Additional Contact(s)", + "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact.Update": "Edit Additional Contact(s)", + "Unity.GrantManager.ApplicationManagement.Funding": "Funding", + "Unity.GrantManager.ApplicationManagement.Funding.Agreement": "Funding Agreement", + "Unity.GrantManager.ApplicationManagement.Funding.Agreement.Update": "Edit Funding Agreement", + "Unity.GrantManager.ApplicationManagement.Payment": "Payment Info", + "Unity.GrantManager.ApplicationManagement.Payment.Summary": "Payment Summary", + "Unity.GrantManager.ApplicationManagement.Payment.Supplier": "Supplier Info", + "Unity.GrantManager.ApplicationManagement.Payment.Supplier.Update": "Edit Supplier Info", + "Unity.GrantManager.ApplicationManagement.Payment.PaymentList": "Payment List", + "Permission:GrantApplicationManagement.ProjectInfo": "Project Info", + "Permission:GrantApplicationManagement.ProjectInfo.Update": "Project Info Update", + "Permission:GrantApplicationManagement.ProjectInfo.Update.UpdateFinalStateFields": "Edit Project Info Fields After Approval", + "Unity.GrantManager.SettingManagement.Tags": "Manage Tags", + "Unity.GrantManager.SettingManagement.Tags.Create": "Create Tag", + "Unity.GrantManager.SettingManagement.Tags.Update": "Edit Tag", + "Unity.GrantManager.SettingManagement.Tags.Delete": "Delete Tag", + "Permission:Tags": "Tags", + "Unity.Applications.Tags.Create": "Assign Tag to Applications", + "Unity.Applications.Tags.Delete": "Remove Tag from Applications", + "GrantManager:AssessmentUserAssignmentAlreadyExists": "Business Exception: You cannot create two assessments on an application for the same user.", + "GrantManager:CantCreateAssessmentForFinalStateApplication": "Business Exception: You cannot create an assessment for an application in final state.", + "GrantManager:PayableFormRequiresHierarchy": "Please select a form hierarchy before saving a payable form.", + "GrantManager:ChildFormRequiresParentForm": "Please select a parent form when the form hierarchy is set to Child.", + "GrantManager:ChildFormCannotReferenceSelf": "A form cannot reference itself as the parent.", + "GrantManager:CannotModifyAiAssessment": "AI assessments are read-only.", + "GrantManager:CannotCloneNonAiAssessment": "Only AI assessments can be cloned.", + "AssessmentResultsView:ApprovalTitle": "Approval", + "AssessmentResultsView:AssessmentResultsTitle": "Application Assessment Results", + "AssessmentResultsView:AssessmentResultsForm.ProjectSummary": "Project Summary", + "AssessmentResultsView:AssessmentResultsForm.RequestedAmount": "Requested Amount", + "AssessmentResultsView:AssessmentResultsForm.TotalProjectBudget": "Total Project Budget", + "AssessmentResultsView:AssessmentResultsForm.RecommendedAmount": "Recommended Amount", + "AssessmentResultsView:AssessmentResultsForm.ApprovedAmount": "Approved Amount", + "AssessmentResultsView:AssessmentResultsForm.LikelihoodOfFunding": "Likelihood of Funding", + "AssessmentResultsView:AssessmentResultsForm.DueDiligenceStatus": "Due Diligence Status", + "AssessmentResultsView:AssessmentResultsForm.SubStatus": "Sub-Status", + "AssessmentResultsView:AssessmentResultsForm.DeclineRational": "Decline Rationale", + "AssessmentResultsView:AssessmentResultsForm.Notes": "Notes", + "AssessmentResultsView:AssessmentResultsForm.TotalScore": "Total Score", + "AssessmentResultsView:AssessmentResultsForm.AssessmentResult": "Assessment Result", + "AssessmentResultsView:AssessmentResultsForm.FinalDecisionDate": "Decision Date", + "AssessmentResultsView:AssessmentResultsForm.DueDate": "Due Date", + "AssessmentResultsView:AssessmentResultsForm.NotificationDate": "Notification Date", + "AssessmentResultsView:AssessmentResultsForm.RiskRanking": "Risk Ranking", + "GrantApplication:ActionButtonName": "Status Actions", + "GrantApplication:ActionButton.RedStopWarning": "This application is from an applicant with a Red-Stop. Status actions are not permitted.", + "Enum:GrantApplicationAction.Open": "Open", + "Enum:GrantApplicationAction.Submit": "Submit", + "Enum:GrantApplicationAction.Internal_Assign": "Assign", + "Enum:GrantApplicationAction.StartReview": "Start Review", + "Enum:GrantApplicationAction.CompleteReview": "Complete Review", + "Enum:GrantApplicationAction.StartAssessment": "Start Assessment", + "Enum:GrantApplicationAction.CompleteAssessment": "Complete Assessment", + "Enum:GrantApplicationAction.Close": "Close", + "Enum:GrantApplicationAction.Withdraw": "Withdraw", + "Enum:GrantApplicationAction.Approve": "Approve", + "Enum:GrantApplicationAction.Deny": "Decline", + "Enum:GrantApplicationAction.Defer": "Defer", + "Enum:GrantApplicationAction.OnHold": "On Hold", + "Enum:GrantApplicationAction.Message.Open": "Open", + "Enum:GrantApplicationAction.Message.Submit": "Submitted", + "Enum:GrantApplicationAction.Message.Internal_Assign": "Assigned", + "Enum:GrantApplicationAction.Message.StartReview": "Under Initial Review", + "Enum:GrantApplicationAction.Message.CompleteReview": "The Initial Review is completed!", + "Enum:GrantApplicationAction.Message.StartAssessment": "Under Assessment", + "Enum:GrantApplicationAction.Message.CompleteAssessment": "The Assessment is completed!", + "Enum:GrantApplicationAction.Message.Close": "The Application is closed!", + "Enum:GrantApplicationAction.Message.Withdraw": "The Application is withdrawn!", + "Enum:GrantApplicationAction.Message.Approve": "Approved", + "Enum:GrantApplicationAction.Message.Deny": "Declined", + "Enum:GrantApplicationAction.Message.Defer": "Deferred", + "Enum:GrantApplicationAction.Message.OnHold": "On-Hold", + "Setting:GrantManager.Locality.SectorFilter.DisplayName": "SectorFilter", + "Setting:GrantManager.Locality.SectorFilter.Description": "Filter for the sector and subsector dropdown list of each tenant", + "Permission:UnitySettingManagementPermissions.BackgroundJobs": "Background Jobs", + "Permission:UnitySettingManagementPermissions.UserInterface": "Application Tabs", + "Permission:UnitySettingManagementPermissions.ConfigurePayments": "Configure Payments", + "Setting:GrantManager.UI.PageTitle": "Application Tabs Configuration", + "Setting:GrantManager.UI.Tabs.Applicant.Description": "Toggle visibility of the Applicant Info tab for the tenant", + "Setting:GrantManager.UI.Tabs.Applicant.DisplayName": "Applicant Info", + "Setting:GrantManager.UI.Tabs.Assessment.Description": "Toggle visibility of the Review & Assessment tab for the tenant", + "Setting:GrantManager.UI.Tabs.Assessment.DisplayName": "Review & Assessment", + "Setting:GrantManager.UI.Tabs.FundingAgreement.Description": "Toggle visibility of the Funding Agreement tab for the tenant", + "Setting:GrantManager.UI.Tabs.FundingAgreement.DisplayName": "Funding Agreement", + "Setting:GrantManager.UI.Tabs.Payments.Description": "Toggle visibility of the Payment Info tab for the tenant", + "Setting:GrantManager.UI.Tabs.Payments.DisplayName": "Payment Info", + "Setting:GrantManager.UI.Tabs.Project.Description": "Toggle visibility of the Project Info tab for the tenant", + "Setting:GrantManager.UI.Tabs.Project.DisplayName": "Project Info", + "Setting:GrantManager.UI.Tabs.Submission.Description": "Toggle visibility of the Submission tab for the tenant", + "Setting:GrantManager.UI.Tabs.Submission.DisplayName": "Submission", + "Setting:GrantManager.UI.Tabs.Assessment.AssessmentResults.DisplayName": "Application Assessment Results", + "Setting:GrantManager.UI.Tabs.Assessment.AssessmentApproval.DisplayName": "Approval", + "Setting:GrantManager.UI.Tabs.Assessment.ReviewList.DisplayName": "Assessment List", + "Setting:GrantManager.UI.Tabs.Project.ProjectInfo.DisplayName": "Project Summary", + "Setting:GrantManager.UI.Tabs.Applicant.ApplicantInfo.DisplayName": "Applicant Info", + "Setting:GrantManager.UI.Tabs.Applicant.ContactInfo.DisplayName": "Contact Info", + "Setting:GrantManager.UI.Tabs.Applicant.SigningAuthority.DisplayName": "Signing Authority", + "Setting:GrantManager.UI.Tabs.Applicant.PhysicalAddress.DisplayName": "Physical Address", + "Setting:GrantManager.UI.Tabs.FundingAgreement.FundingAgreementInfo.DisplayName": "Contract Info", + "Setting:GrantManager.UI.Tabs.Payments.PaymentInfo.DisplayName": "Payment Summary", + "Setting:GrantManager.UI.Tabs.Payments.PaymentList.DisplayName": "Payment List", + "Setting:GrantManager.UI.Tabs.Project.ProjectLocation.DisplayName": "Project Location", + "Summary:ApplicationSummaryTitle": "Submission", + "Summary:AssessmentSummaryTitle": "Assessment Summary", + "Summary:ContactsTitle": "Additional Contact(s)", + "Summary:Application.Category": "Category", + "Summary:Application.EconomicRegion": "Economic Region", + "Summary:Application.RegionalDistrict": "Regional District", + "Summary:Application.SubmissionDate": "Submission Date", + "Summary:Application.OrganizationName": "Registered Organization Name", + "Summary:Application.OrganizationNumber": "Registered Organization Number", + "Summary:Application.BusinessNumber": "Business Number", + "Summary:Application.NonRegOrgName": "Non-Registered Organization Name", + "Summary:Application.City": "City", + "Summary:Application.Community": "Community", + "Summary:Application.RequestedAmount": "Requested Amount", + "Summary:Application.ProjectBudget": "Total Project Budget", + "Summary:Application.Sector": "Sector", + "Summary:Application.Owner": "Owner", + "Summary:Application.UnityApplicationId": "Unity Application ID", + "Summary:Application.Assignees": "Assignees", + "Summary:Assessment.Status": "Status", + "Summary:Assessment.LikelihoodOfFunding": "Likelihood Of Funding", + "Summary:Assessment.AssessmentStartDate": "Assessment Start Date", + "Summary:Assessment.FinalDecisionDate": "Decision Date", + "Summary:Assessment.TotalScore": "Total Score", + "Summary:Assessment.AssessmentResult": "Assessment Result", + "Summary:Assessment.RecommendedAmount": "Recommended Amount", + "Summary:Assessment.ApprovedAmount": "Approved Amount", + "Summary:Assessment.Batch": "Batch #", + "Summary:ApplicationTags": "Application Tags", + "Unity.GrantManager.ApplicationManagement.Project.Summary:DisplayName": "Project Summary", + "ProjectInfoView:ProjectInfo.ProjectName": "Project Name", + "ProjectInfoView:ProjectInfo.ProjectSummary": "Project Summary", + "ProjectInfoView:ProjectInfo.ProjectStartDate": "Project Start Date", + "ProjectInfoView:ProjectInfo.ProjectEndDate": "Project End Date", + "ProjectInfoView:ProjectInfo.RequestedAmount": "Requested Amount", + "ProjectInfoView:ProjectInfo.TotalProjectBudget": "Total Project Budget", + "ProjectInfoView:ProjectInfo.PercentageTotalProjectBudget": "% of Total Project Budget", + "ProjectInfoView:ProjectInfo.ProjectFundingTotal": "Projected Funding Total", + "ProjectInfoView:ProjectInfo.Sector": "Sector", + "ProjectInfoView:ProjectInfo.SubSector": "Sub Sector", + "ProjectInfoView:ProjectInfo.Community": "Community", + "ProjectInfoView:ProjectInfo.EconomicRegion": "Economic Region", + "ProjectInfoView:ProjectInfo.ElectoralDistrict": "Project Electoral District", + "ProjectInfoView:ProjectInfo.CommunityPopulation": "Community Population", + "ProjectInfoView:ProjectInfo.Place": "Place", + "ProjectInfoView:ProjectInfo.Acquisition": "Acquisition", + "ProjectInfoView:ProjectInfo.Forestry": "Forestry/Non-Forestry", + "ProjectInfoView:ProjectInfo.ForestryFocus": "Forestry Focus", + "ProjectInfoView:ProjectInfo.CensusSubdivision": "Census Subdivision", + "ProjectInfoView:ProjectInfo.RegionalDistrict": "Regional District", + "Unity.GrantManager.ApplicationManagement.Project.Location:DisplayName": "Project Location", + "ProjectInfoView:ProjectInfoContactInfo": "Contact Info", + "ProjectInfoView:ProjectInfo.ContactFullName": "Contact Full Name", + "ProjectInfoView:ProjectInfo.ContactTitle": "Contact Title", + "ProjectInfoView:ProjectInfo.ContactEmail": "Contact Email", + "ProjectInfoView:ProjectInfo.ContactBusinessPhone": "Contact Business Phone", + "ProjectInfoView:ProjectInfo.ContactCellPhone": "Contact Cell Phone", + "ApplicantInfoView:ApplicantInfoContactInfo": "Contact Info", + "ApplicantInfoView:SigningAuthorityTitle": "Signing Authority", + "ApplicantInfoView:PhysicalAddress": "Physical Address", + "ApplicantInfoView:MailingAddress": "Mailing Address", + "ApplicantInfoView:ApplicantInfo.ContactFullName": "Full Name", + "ApplicantInfoView:ApplicantInfo.ContactTitle": "Title", + "ApplicantInfoView:ApplicantInfo.ContactEmail": "Email", + "ApplicantInfoView:ApplicantInfo.ContactBusinessPhone": "Business Phone", + "ApplicantInfoView:ApplicantInfo.ContactCellPhone": "Cell Phone", + "ApplicantInfoView:ApplicantInfo SigningAuthorityInfo": " Signing Authority", + "ApplicantInfoView:ApplicantInfo.SigningAuthorityFullName": "Full Name", + "ApplicantInfoView:ApplicantInfo.SigningAuthorityTitle": "Title", + "ApplicantInfoView:ApplicantInfo.SigningAuthorityEmail": "Email", + "ApplicantInfoView:ApplicantInfo.SigningAuthorityBusinessPhone": "Business Phone", + "ApplicantInfoView:ApplicantInfo.SigningAuthorityCellPhone": "Phone", + "ApplicantInfoView:ApplicantInfo.OrgName": "Registered Organization Name", + "ApplicantInfoView:ApplicantInfo.OrgNumber": "Registered Organization Number", + "ApplicantInfoView:ApplicantInfo.BusinessNumber": "Business Number", + "ApplicantInfoView:ApplicantInfo.OrgBookStatus": "Org book status ", + "ApplicantInfoView:ApplicantInfo.OrganizationType": "Organization Type", + "ApplicantInfoView:ApplicantInfo.OrganizationSize": "Organization Size", + "ApplicantInfoView:ApplicantInfo.UnityApplicant": "Applicant Id", + "ApplicantInfoView:ApplicantInfo.FiscalMonth": "Fiscal Year End Month", + "ApplicantInfoView:ApplicantInfo.FiscalDay": "Fiscal Year End Day", + "ApplicantInfoView:ApplicantInfo.IndigenousOrgInd": "Indigenous", + "ApplicantInfoView:ApplicantInfo.Sector": "Sector", + "ApplicantInfoView:ApplicantInfo.SubSector": "Sub-sector", + "ApplicantInfoView:ApplicantInfo.RedStop": "Red-Stop", + "ApplicantInfoView:ApplicantInfo.ApplicantInfoTitle": "Applicant Info", + "ApplicantInfoView:ApplicantInfo.SectorSubSectorIndustryDesc": "Other Sector/Sub/Industry Description", + "ApplicantInfoView:ApplicantInfo.Street": "Street", + "ApplicantInfoView:ApplicantInfo.Street2": "Street 2", + "ApplicantInfoView:ApplicantInfo.Unit": "Unit", + "ApplicantInfoView:ApplicantInfo.City": "City", + "ApplicantInfoView:ApplicantInfo.Province": "Province", + "ApplicantInfoView:ApplicantInfo.PostalCode": "Postal Code", + "ApplicantInfoView:ApplicantInfo.NonRegOrgName": "Non-Registered Organization Name", + "ApplicantInfoView:ApplicantInfo.OrgBookSearchPlaceholder": "Start typing to search for your registered organization name", + "ApplicantInfoView:ApplicantInfo.OrgBookSearch": "Search in BC Registries", + "ApplicantInfoView:ElectoralDistrict": "Electoral District", + "ApplicantInfoView:ApplicantElectoralDistrict": "Applicant Electoral District", + "ApplicantInfoView:Notes.ElectoralDistrict": "The electoral district is identified based on the {0}", + "ApplicantInfoView:ApplicantInfo.ApplicantLookUp": "Applicant Look up", + "ApplicantInfoView:ApplicantInfo.ApplicantLookUpPlaceholder": "Start typing applicant name or number to search for applicant...", + "ApplicantInfoView:ApplicantInfo.PrincipalRecord": "Principal Record", + "ApplicantInfoView:ApplicantInfo.Principal": "Use as a Principal", + "ApplicantInfoView:ApplicantInfo.ApplicantName": "Applicant Name", + "FundingAgreementInfoView:FundingAgreementInfoTitle": "Funding Agreement", + "FundingAgreementInfoView:FundingAgreementInfoContract": "Contract", + "FundingAgreementInfoView:FundingAgreementInfo.ContractNumber": "Contract #", + "FundingAgreementInfoView:FundingAgreementInfo.ContractExecutionDate": "Execution Date", + "UnityIdentity:ImportUser": "Import User", + "UnityIdentity:FirstName": "First Name", + "UnityIdentity:LastName": "Last Name", + "UnityIdentity:Import": "Import", + "ApplicationDetails:Comments.Modified": "Modified:", + "ApplicationDetails:Comments.Created": "Created:", + "ApplicationContact:AddTitle": "Add New Contact", + "ApplicationContact:EditTitle": "Edit Contact", + "ApplicationContact:Type": "Type", + "ApplicationContact:FullName": "Full Name", + "ApplicationContact:Title": "Title", + "ApplicationContact:Email": "Email", + "ApplicationContact:MobilePhone": "Mobile Phone Number", + "ApplicationContact:WorkPhone": "Work Phone Number", + "ApplicationContact:Delete": "Delete This Contact", + "ApplicantContact:SetAsPrimary": "Set as Primary", + "ApplicantContact:PrimaryHint": "This contact is currently primary because it was auto-selected by most recent timestamp. Saving with Set as Primary checked will explicitly set it as primary.", + "ApplicantContacts:ApplicantNotFound": "Applicant information not found.", + "ApplicantContacts:PrimaryContact": "Primary Contact", + "ApplicantContacts:NoPrimaryContact": "No primary contact on record.", + "ApplicantContacts:ContactsTitle": "Contacts", + "ApplicantContacts:PrimaryExplicitTooltip": "Primary contact", + "ApplicantContacts:PrimaryInferredTooltip": "Primary contact (auto-selected by most recent timestamp; not explicitly set).", + "ApplicantContacts:SourceInfoApplication": "Sourced from the Application submission. Managed on the Application Details form and cannot be edited here.", + "ApplicantContacts:SourceInfoApplicantAgent": "Sourced from the Applicant Agent on the CHEFS submission. Captured at intake and cannot be edited here.", + "ApplicantContacts:SourceInfoGeneric": "Sourced from {0} and cannot be edited here.", + "ApplicantContacts:View": "View", + "ApplicantContacts:ContactSaved": "Contact saved.", + "ApplicantContacts:ContactSetPrimary": "Contact set as primary.", + "ApplicantContacts:ServiceUnavailable": "Applicant contact service is not available.", + "ApplicantContacts:SetPrimaryFailed": "Failed to set contact as primary.", + "ApplicantContacts:ColumnName": "Name", + "ApplicantContacts:ColumnPhone": "Phone (Work)", + "ApplicantContacts:ColumnSubmission": "Submission #", + "ApplicationBatchApprovalRequest:Title": "Approve Applications", + "ApplicationBatchApprovalRequest:SubmitButtonText": "Approve", + "ApplicationBatchApprovalRequest:CancelButtonText": "Cancel", + "ApplicationBatchApprovalRequest:MaxCountExceeded": "You have exceeded the maximum number of items for bulk approval. Please reduce the number to {0} or fewer", + "ApplicationBatchApprovalRequest:DecisionDateDefaulted": "Decision Date has been defaulted", + "ApplicationBatchApprovalRequest:ApprovedAmountDefaulted": "Approved Amount has been defaulted", + "ApplicationBatchApprovalRequest:InvalidStatus": "The assessment for the selected item is not in the Assessment Completed state", + "ApplicationBatchApprovalRequest:InvalidPermissions": "Invalid permissions", + "ApplicationBatchApprovalRequest:InvalidApprovedAmount": "Invalid Approved Amount, it must be greater than 0.00", + "ApplicationBatchApprovalRequest:InvalidRecommendedAmount": "Invalid Recommended Amount, it must be greater than 0.00", + "ApplicationLinks:Category": "Category", + "ApplicationLinks:ID": "ID", + "ApplicationLinks:Status": "Status", + "ApplicationLinks:LinkType": "Link Type", + "ApplicantPortalSettings:Title": "Applicant Portal Configuration", + "ApplicantPortalSettings:ManageStatuses": "Manage Statuses", + "ApplicantPortalSettings:PortalStatusHeading": "Applicant Portal Status", + "ApplicantPortalSettings:InternalStatus": "Internal Status", + "ApplicantPortalSettings:PortalStatusLabel": "Portal Status Label", + "ApplicantPortalSettings:SaveChanges": "Save Changes", + "ApplicantPortalSettings:ResetChanges": "Reset", + "ApplicantPortalSettings:NoChanges": "No changes to save.", + "ApplicantPortalSettings:ChangesReset": "Changes have been reset to original values.", + "ApplicantPortalSettings:SaveSuccess": "Portal status labels updated successfully.", + "ApplicantPortalSettings:SaveError": "An error occurred while saving portal status labels.", + "ApplicantPortalSettings:ValidationRequired": "Portal status label cannot be empty." + }, + "baseResources": [ + "AbpValidation", + "AbpUi" + ] + }, + "AbpDddApplicationContracts": { + "texts": { + "MaxResultCountExceededExceptionMessage": "{0} can not be more than {1}! Increase {2}.{3} on the server side to allow more results." + }, + "baseResources": [] + }, + "AbpAuthorization": { + "texts": { + "Volo.Authorization:010001": "Authorization failed! Given policy has not granted.", + "Volo.Authorization:010002": "Authorization failed! Given policy has not granted: {PolicyName}", + "Volo.Authorization:010003": "Authorization failed! Given policy has not granted for given resource: {ResourceName}", + "Volo.Authorization:010004": "Authorization failed! Given requirement has not granted for given resource: {ResourceName}", + "Volo.Authorization:010005": "Authorization failed! Given requirements has not granted for given resource: {ResourceName}" + }, + "baseResources": [] + }, + "AbpExceptionHandling": { + "texts": { + "InternalServerErrorMessage": "An internal error occurred during your request!", + "ValidationErrorMessage": "Your request is not valid!", + "ValidationNarrativeErrorMessageTitle": "The following errors were detected during validation.", + "DefaultErrorMessage": "An error has occurred!", + "DefaultErrorMessageDetail": "Error detail not sent by the server.", + "DefaultErrorMessage401": "You are not authenticated!", + "DefaultErrorMessage401Detail": "You should sign in to perform this operation.", + "DefaultErrorMessage403": "You are not authorized!", + "DefaultErrorMessage403Detail": "You are not allowed to perform this operation!", + "DefaultErrorMessage404": "Resource not found!", + "DefaultErrorMessage404Detail": "The resource requested could not be found on the server!", + "EntityNotFoundErrorMessage": "There is no entity {0} with id = {1}!", + "EntityNotFoundErrorMessageWithoutId": "There is no entity {0}!", + "AbpDbConcurrencyErrorMessage": "The data you have submitted has already been changed by another user. Discard your changes and try again.", + "Error": "Error", + "UnhandledException": "Unhandled exception!", + "Authorizing": "Authorizing…", + "401Message": "Unauthorized", + "403Message": "Forbidden", + "404Message": "Page not found", + "500Message": "Internal Server Error", + "403MessageDetail": "You are not authorized to perform this operation!", + "404MessageDetail": "Sorry, there's nothing at this address.", + "Unauthorized": "Unauthorized", + "invalid_token": "Invalid token", + "SessionExpired": "Your session has expired. Please login again to continue in the application." + }, + "baseResources": [] + }, + "AbpUi": { + "texts": { + "Languages": "Languages", + "AreYouSure": "Are you sure?", + "Cancel": "Cancel", + "Clear": "Clear", + "Yes": "Yes", + "No": "No", + "Ok": "Ok", + "Close": "Close", + "Save": "Save", + "SavingWithThreeDot": "Saving...", + "Actions": "Actions", + "Delete": "Delete", + "CreatedSuccessfully": "Created successfully", + "SavedSuccessfully": "Saved successfully", + "DeletedSuccessfully": "Deleted successfully", + "Edit": "Edit", + "Refresh": "Refresh", + "Language": "Language", + "LoadMore": "Load more", + "ProcessingWithThreeDot": "Processing...", + "LoadingWithThreeDot": "Loading...", + "Welcome": "Welcome", + "Login": "Login", + "Register": "Register", + "Logout": "Log out", + "Submit": "Submit", + "Back": "Back", + "PagerSearch": "Search", + "PagerNext": "Next", + "PagerPrevious": "Previous", + "PagerFirst": "First", + "PagerLast": "Last", + "PagerInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + "PagerInfo{0}{1}{2}": "Showing {0} to {1} of {2} entries", + "PagerInfoEmpty": "Showing 0 to 0 of 0 entries", + "PagerInfoFiltered": "(filtered from _MAX_ total entries)", + "NoDataAvailableInDatatable": "No data available", + "ErrorLoadingDatatable": "An error occurred during the request. Check the message for details.", + "Total": "total", + "Selected": "selected", + "PagerShowMenuEntries": "Show _MENU_ entries", + "DatatableActionDropdownDefaultText": "Actions", + "ChangePassword": "Change password", + "PersonalInfo": "My profile", + "AreYouSureYouWantToCancelEditingWarningMessage": "You have unsaved changes.", + "GoHomePage": "Go to the homepage", + "GoBack": "Go back", + "Search": "Search", + "ItemWillBeDeletedMessageWithFormat": "{0} will be deleted!", + "ItemWillBeDeletedMessage": "This item will be deleted!", + "ManageYourAccount": "Manage your account", + "OthersGroup": "Other", + "Today": "Today", + "Apply": "Apply", + "InternetConnectionInfo": "The operation could not be performed. Your internet connection is not available at the moment.", + "CopiedToTheClipboard": "Copied to the clipboard", + "AddNew": "Add new", + "ProfilePicture": "Profile picture", + "Theme": "Theme", + "NotAssigned": "Not Assigned", + "EntityActionsDisabledTooltip": "You do not have permission to perform any action.", + "ResourcePermissions": "Permissions" + }, + "baseResources": [ + "AbpExceptionHandling" + ] + }, + "AbpUiNavigation": { + "texts": { + "Menu:Administration": "Administration" + }, + "baseResources": [] + }, + "AbpGlobalFeature": { + "texts": { + "Volo.GlobalFeature:010001": "The '{ServiceName}' service needs to enable '{GlobalFeatureName}' feature." + }, + "baseResources": [] + }, + "AbpEmailing": { + "texts": { + "DisplayName:Abp.Mailing.DefaultFromAddress": "Default from address", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Default from display name", + "DisplayName:Abp.Mailing.Smtp.Host": "Host", + "DisplayName:Abp.Mailing.Smtp.Port": "Port", + "DisplayName:Abp.Mailing.Smtp.UserName": "User name", + "DisplayName:Abp.Mailing.Smtp.Password": "Password", + "DisplayName:Abp.Mailing.Smtp.Domain": "Domain", + "DisplayName:Abp.Mailing.Smtp.EnableSsl": "Enable SSL", + "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Use default credentials", + "Description:Abp.Mailing.DefaultFromAddress": "The default from address", + "Description:Abp.Mailing.DefaultFromDisplayName": "The default from display name", + "Description:Abp.Mailing.Smtp.Host": "The name or IP address of the host used for SMTP transactions.", + "Description:Abp.Mailing.Smtp.Port": "The port used for SMTP transactions.", + "Description:Abp.Mailing.Smtp.UserName": "User name associated with the credentials.", + "Description:Abp.Mailing.Smtp.Password": "The password for the user name associated with the credentials.", + "Description:Abp.Mailing.Smtp.Domain": "The domain or computer name that verifies the credentials.", + "Description:Abp.Mailing.Smtp.EnableSsl": "Whether the SmtpClient uses Secure Sockets Layer (SSL) to encrypt the connection.", + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Whether the DefaultCredentials are sent with requests.", + "TextTemplate:StandardEmailTemplates.Layout": "Default email layout template", + "TextTemplate:StandardEmailTemplates.Message": "Simple message template for emails" + }, + "baseResources": [] + }, + "AI": { + "texts": { + "Permission:AI": "AI", + "Permission:AI.Reporting": "AI Reporting", + "Permission:AI.ViewApplicationAnalysis": "View AI Application Analysis", + "Permission:AI.ViewAttachmentSummary": "View AI Attachment Summary", + "Permission:AI.ViewScoringResult": "View AI Scoring Result", + "Permission:AI.GenerateApplicationAnalysis": "Generate AI Application Analysis", + "Permission:AI.GenerateAttachmentSummaries": "Generate AI Attachment Summaries", + "Permission:AI.GenerateScoring": "Generate AI Scoring", + "Permission:AI.ConfigureAI": "AI Configuration", + "Permission:AI.Prompts": "AI Prompt Management", + "Permission:AI.Prompts.Create": "Create Prompts", + "Permission:AI.Prompts.Update": "Edit Prompts", + "Permission:AI.Prompts.Delete": "Delete Prompts", + "Menu:AIReporting": "AI Reporting", + "Setting:AI.AutomaticGenerationEnabled": "Automatically Generate AI Analysis", + "Setting:AI.ManualGenerationEnabled": "Manually Initiate AI Analysis", + "AI:AttachmentSummariesDisabled": "AI attachment summaries are not enabled.", + "AI:ApplicationAnalysisDisabled": "AI application analysis is not enabled.", + "AI:ScoringDisabled": "AI scoring is not enabled.", + "AI:GenerateAllDisabled": "AI generation is not enabled.", + "AIPrompts": "AI Prompts", + "AIPrompt": "AI Prompt", + "AIPromptVersion": "Prompt Version", + "AIPromptVersions": "Prompt Versions", + "PromptType": "Type", + "PromptName": "Name", + "PromptDescription": "Description", + "PromptIsActive": "Active", + "VersionNumber": "Version Number", + "SystemPrompt": "System Prompt", + "UserPromptTemplate": "User Prompt Template", + "DeveloperNotes": "Developer Notes", + "TargetModel": "Target Model", + "TargetProvider": "Target Provider", + "Temperature": "Temperature", + "MaxTokens": "Max Tokens", + "IsPublished": "Published", + "IsDeprecated": "Deprecated" + }, + "baseResources": [ + "AbpValidation" + ] + }, + "AbpUiMultiTenancy": { + "texts": { + "GivenTenantIsNotExist": "Given tenant doesn't exist: {0}", + "GivenTenantIsNotAvailable": "Given tenant isn't available: {0}", + "Tenant": "Tenant", + "Switch": "switch", + "Name": "Name", + "SwitchTenantHint": "Leave the name field blank to switch to the host side.", + "SwitchTenant": "Switch tenant", + "NotSelected": "Not selected" + }, + "baseResources": [] + } + }, + "currentCulture": { + "displayName": "English (Canada)", + "englishName": "English (Canada)", + "threeLetterIsoLanguageName": "eng", + "twoLetterIsoLanguageName": "en", + "isRightToLeft": false, + "cultureName": "en-CA", + "name": "en-CA", + "nativeName": "English (Canada)", + "dateTimeFormat": { + "calendarAlgorithmType": "SolarCalendar", + "dateTimeFormatLong": "dddd, MMMM d, yyyy", + "shortDatePattern": "yyyy-MM-dd", + "fullDateTimePattern": "dddd, MMMM d, yyyy h:mm:ss tt", + "dateSeparator": "-", + "shortTimePattern": "h:mm tt", + "longTimePattern": "h:mm:ss tt" + } + } +}) + +})(); \ No newline at end of file diff --git a/Submission_files/ApplicationTags.js.download b/Submission_files/ApplicationTags.js.download new file mode 100644 index 0000000000..1d537c4793 --- /dev/null +++ b/Submission_files/ApplicationTags.js.download @@ -0,0 +1,357 @@ +$(function () { + + let suggestionsArray = []; + + let TagsInput = function (opts) { + this.options = Object.assign(TagsInput.defaults, opts); + this.init(); + } + + TagsInput.prototype.init = function (opts) { + this.options = opts ? Object.assign(this.options, opts) : this.options; + + if (this.initialized) + this.destroy(); + this.orignal_input = document.getElementById(this.options.selector); + + if (!this.orignal_input) { + console.error("tags-input couldn't find an element with the specified ID"); + return this; + } + + this.arr = []; + + this.wrapper = document.createElement('div'); + this.input = document.createElement('input'); + this.input.id = "tags-input-control"; + init(this); + initEvents(this); + + // Disable the input if user doesn't have create permission + if (!abp.auth.isGranted('Unity.Applications.Tags.Create')) { + this.input.disabled = true; + this.input.type = "hidden"; + this.wrapper.classList.add('tags-input-disabled'); + } + + this.initialized = true; + return this; + } + + TagsInput.prototype.addTag = function (tagData) { + let defaultClass = 'tags-common'; + let id, tagText, tagClass; + + id = tagData.id; + tagText = tagData.name || ''; + tagClass = tagData.class || defaultClass; + + if (this.anyErrors(tagText)) + return; + + this.arr.push({ Id: id, Name: tagText }); + + let tagInput = this; + + let tag = document.createElement('span'); + tag.className = this.options.tagClass + ' ' + tagClass; + tag.innerText = tagText; + + if (abp.auth.isGranted('Unity.Applications.Tags.Delete')) { + let closeIcon = document.createElement('a'); + closeIcon.innerHTML = '×'; + + closeIcon.addEventListener('click', function (e) { + e.preventDefault(); + let tag = this.parentNode; + + let tagIndex = Array.from(tagInput.wrapper.childNodes).indexOf(tag); + if (tagIndex !== -1) { + tagInput.deleteTag(tag, tagIndex); + } + }) + + tag.appendChild(closeIcon); + } + + this.wrapper.insertBefore(tag, this.input); + this.orignal_input.value = JSON.stringify(this.arr); + updateSelectedTagsInput(this.arr); + + return this; + } + + TagsInput.prototype.deleteTag = function (tag, i) { + let self = this; + + if (this.arr[i] && this.arr[i].Name === 'Uncommon Tags') { + abp.message.confirm('Are you sure you want to delete all the uncommon tags?') + .then(function (confirmed) { + if (confirmed) { + tag.remove(); + self.arr.splice(i, 1); + self.orignal_input.value = JSON.stringify(self.arr); + updateSelectedTagsInput(self.arr); + + // Expand input if no tags remain + if (self.arr.length === 0) { + self.input.classList.add('expanded'); + } + + return self; + } + }); + } else { + tag.remove(); + this.arr.splice(i, 1); + this.orignal_input.value = JSON.stringify(this.arr); + updateSelectedTagsInput(this.arr); + + // Expand input if no tags remain + if (this.arr.length === 0) { + this.input.classList.add('expanded'); + } + + return this; + } + } + + TagsInput.prototype.anyErrors = function (string) { + if (this.options.max != null && this.arr.length >= this.options.max) { + console.log('max tags limit reached'); + return true; + } + + if ( + !this.options.duplicate && + this.arr.some(tag => tag.name === string) + ) { + console.log('duplicate found "' + string + '"'); + return true; + } + + return false; + } + + TagsInput.prototype.addData = function (array) { + let plugin = this; + + array.forEach(function (string) { + plugin.addTag(string); + }) + return this; + } + + TagsInput.prototype.getInputString = function () { + return this.arr.join(','); + } + + TagsInput.prototype.setSuggestions = function (sugArray) { + suggestionsArray = sugArray; + } + + TagsInput.prototype.destroy = function () { + this.orignal_input.removeAttribute('hidden'); + + delete this.orignal_input; + let self = this; + + Object.keys(this).forEach(function (key) { + if (self[key] instanceof HTMLElement) + self[key].remove(); + + if (key != 'options') + delete self[key]; + }); + + this.initialized = false; + } + + function init(tags) { + // Create and append the add tag button + tags.addButton = document.createElement('button'); + tags.addButton.type = 'button'; + tags.addButton.className = 'tags-add-button'; + tags.addButton.innerHTML = '+'; + tags.addButton.title = 'Add a tag'; + + // Disable button if user doesn't have create permission + if (!abp.auth.isGranted('Unity.Applications.Tags.Create')) { + tags.addButton.disabled = true; + tags.addButton.style.display = 'none'; + } + + tags.wrapper.append(tags.input); + tags.wrapper.append(tags.addButton); + tags.wrapper.classList.add(tags.options.wrapperClass); + tags.orignal_input.setAttribute('hidden', 'true'); + tags.orignal_input.parentNode.insertBefore(tags.wrapper, tags.orignal_input); + tags.input.setAttribute('placeholder', 'Add a tag...'); + + tags.input.addEventListener('input', function () { + const inputValue = tags.input.value.trim().toLowerCase(); + + if (inputValue.length === 1) { + // Filter by first character only + const suggestions = suggestionsArray.filter(tag => + tag.name.toLowerCase().startsWith(inputValue)); + + if (suggestions.length) { + displaySuggestions(tags, suggestions, true); + } else { + removeSuggestions(tags); + } + } else if (inputValue.length > 1) { + // Filter by checking if input appears anywhere in tag name + const suggestions = suggestionsArray.filter(tag => + (tag.name.toLowerCase()).includes(inputValue)); + + if (suggestions.length) { + displaySuggestions(tags, suggestions, true); + } else { + removeSuggestions(tags); + } + } else { + removeSuggestions(tags); + } + }); + + // Expand input on focus + tags.input.addEventListener('focus', function () { + tags.input.classList.add('expanded'); + }); + } + + function displaySuggestions(tags, suggestions, isFiltered) { + + removeSuggestions(tags); + + const suggestionContainer = document.createElement('div'); + suggestionContainer.classList.add('tags-suggestion-container'); + const suggestionTitleElement = document.createElement('div'); + suggestionTitleElement.className = 'tags-suggestion-title'; + suggestionTitleElement.innerText = isFiltered ? 'FILTERED TAGS' : 'ALL TAGS'; + suggestionContainer.appendChild(suggestionTitleElement); + suggestions.forEach(suggestion => { + const suggestionElement = document.createElement('div'); + suggestionElement.className = 'tags-suggestion-element'; + suggestionElement.innerText = typeof suggestion === 'string' ? suggestion : suggestion.name; + suggestionElement.addEventListener('click', function () { + tags.addTag(suggestion); + removeSuggestions(tags); + tags.input.value = ""; + tags.wrapper.focus(); + }); + + suggestionContainer.appendChild(suggestionElement); + }); + + tags.wrapper.appendChild(suggestionContainer); + } + + function removeSuggestions(tags) { + const suggestionContainer = tags.wrapper.querySelector('.tags-suggestion-container'); + if (suggestionContainer) { + suggestionContainer.remove(); + } + } + + function initEvents(tags) { + // Capture keystrokes anywhere in the wrapper and focus input + let tagApplicationsModalElem = $("#tagApplicationsModal")[0]; + if (tagApplicationsModalElem) { + tagApplicationsModalElem.addEventListener('keydown', function (e) { + // Skip if input is already focused or if it's a special key + if (document.activeElement === tags.input) { + return; + } + + // Check if it's a printable character + const isPrintableKey = e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey; + if (isPrintableKey && abp.auth.isGranted('Unity.Applications.Tags.Create')) { + // Expand and focus the input + tags.input.classList.add('expanded'); + tags.input.focus(); + } + }); + } + + + // Add button click event - show all tags + if (tags.addButton) { + tags.addButton.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + // Toggle suggestions display + const existingSuggestions = tags.wrapper.querySelector('.tags-suggestion-container'); + if (existingSuggestions) { + removeSuggestions(tags); + } else { + // Expand input and show all suggestions sorted alphabetically + tags.input.classList.add('expanded'); + const sortedSuggestions = [...suggestionsArray].sort((a, b) => + a.name.localeCompare(b.name) + ); + displaySuggestions(tags, sortedSuggestions, false); + // Focus the input field so user can type to filter + tags.input.focus(); + } + }); + } + + tags.input.addEventListener('focusout', function () { + $('#assignTagsModelSaveBtn').click(function () { + trimAndAddTag(tags); + }) + }); + + tags.input.addEventListener('keydown', function (e) { + if (~[9, 13, 188, 32].indexOf(e.keyCode)) { + e.preventDefault(); + trimAndAddTag(tags); + removeSuggestions(tags); + + } + }); + } + + function trimAndAddTag(tags) { + let str = tags.input.value.trim(); + if (!str) { + tags.input.value = ""; + return; + } + + const matched = suggestionsArray.find(s => + s.name.toLowerCase() === str.toLowerCase() + ); + + if (matched) { + tags.addTag(typeof matched === 'string' ? { name: matched } : matched); + } else { + abp.message.warn('Please select a tag from the suggestions.'); + } + + tags.input.value = ""; + } + + function updateSelectedTagsInput(tagsArray) { + let jsonValue = JSON.stringify(tagsArray); + $('#SelectedTagsJson').val(jsonValue); + } + + TagsInput.prototype.getTags = function () { + return this.arr.slice(); + } + + TagsInput.defaults = { + selector: '', + wrapperClass: 'tags-input-wrapper', + tagClass: 'tag', + max: null, + duplicate: false + } + + window.TagsInput = TagsInput; +}); diff --git a/Submission_files/AssessmentResultAttachments.css b/Submission_files/AssessmentResultAttachments.css new file mode 100644 index 0000000000..3ada131167 --- /dev/null +++ b/Submission_files/AssessmentResultAttachments.css @@ -0,0 +1,28 @@ +.assessment-attachment-table th:first-child, .assessment-attachment-table td:first-child { + text-align: center; +} + +/* Updated for DataTables v2 - ensure proper width handling with scrollX */ +#AssessmentResultAttachmentsTable_wrapper .dt-scroll-body { + overflow: visible !important; +} + +/* Ensure table wrapper uses full width */ +#AssessmentResultAttachmentsTable_wrapper { + width: 100%; +} + +/* Ensure scroll container allows dropdowns to overflow */ +#AssessmentResultAttachmentsTable_wrapper .dt-scroll { + overflow: visible; +} + +/* Ensure inner scroll elements take full width */ +#AssessmentResultAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner, +#AssessmentResultAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner table { + width: 100% !important; +} + +#AssessmentResultAttachmentsTable_wrapper .dt-scroll-body table { + width: 100% !important; +} \ No newline at end of file diff --git a/Submission_files/AssessmentResultAttachments.js.download b/Submission_files/AssessmentResultAttachments.js.download new file mode 100644 index 0000000000..912120f93a --- /dev/null +++ b/Submission_files/AssessmentResultAttachments.js.download @@ -0,0 +1,102 @@ +// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js +$(function () { + const l = abp.localization.getResource('GrantManager'); + const nullPlaceholder = '—'; + + let inputAction = function (requestData, dataTableSettings) { + let assessmentId = decodeURIComponent($("#AssessmentId").val()); + return { + attachmentType: 'ASSESSMENT', + attachedResourceId: assessmentId ?? "00000000-0000-0000-0000-000000000000" + }; + }; + + let responseCallback = function (result) { + return { + data: result + }; + }; + + const dataTable = $('#AssessmentResultAttachmentsTable').DataTable( + abp.libs.datatables.normalizeConfiguration({ + serverSide: false, + order: [[2, 'asc']], + searching: true, + externalFilterButtonId: 'btn-toggle-filter-assessment-attachments', + paging: false, + select: false, + info: false, + scrollX: true, + ajax: abp.libs.datatables.createAjax( + unity.grantManager.attachments.attachment.getAttachments, inputAction, responseCallback + ), + columnDefs: [ + { + title: '', + width: '40px', + className: 'text-center', + render: function (data) { + return ''; + }, + orderable: false + }, + { + title: l('AssessmentResultAttachments:DocumentName'), + data: 'fileName', + className: 'data-table-header text-break', + width: '30%', + }, + { + title: 'Label', + data: 'displayName', + className: 'data-table-header text-break', + width: '20%', + render: function (data) { + return data ?? nullPlaceholder; + } + }, + { + title: l('AssessmentResultAttachments:UploadedDate'), + data: 'time', + className: 'data-table-header', + width: '140px', + render: function (data, type) { + if (type === 'display' || type === 'filter') { + return new Date(data).toDateString(); + } + return data; + }, + }, + { + title: l('AssessmentResultAttachments:AttachedBy'), + data: 'attachedBy', + className: 'data-table-header', + width: '25%', + }, + { + title: '', + data: 's3ObjectKey', + width: '80px', + className: 'text-center', + render: function (data, type, full, meta) { + return generateAttachmentButtonContent(data, type, full, meta, 'Assessment'); + }, + orderable: false + } + ], + }) + ); + + dataTable.on('click', 'tbody tr', function (e) { + e.currentTarget.classList.toggle('selected'); + }); + + initializeFilterRowPlugin(dataTable, 'btn-toggle-filter-assessment-attachments'); + + PubSub.subscribe( + 'refresh_assessment_attachment_list', + (msg, data) => { + dataTable.ajax.reload(); + } + ); +}); diff --git a/Submission_files/Attachments.css b/Submission_files/Attachments.css new file mode 100644 index 0000000000..6fd1ac7e88 --- /dev/null +++ b/Submission_files/Attachments.css @@ -0,0 +1,35 @@ +.attachments-table .dropdown-content { + display: none; + position: fixed; + right: 0; + margin-right: 20px; + background-color: #f9f9f9; + min-width: 250px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1039; + --bs-btn-active-color: var(--bc-colors-white-primary-500); + --bs-btn-active-bg: var(--bc-colors-blue-primary-500); +} + + .attachments-table .dropdown-content a { + text-decoration: none; + display: block; + } + + .attachments-table .dropdown-content a:hover { + background-color: #f1f1f1; + } + +.attachments-table .dropdown:hover .dropdown-content { + display: block; +} + +.attachments-table .fullwidth { + width: 100%; + display: block; + text-align: left; +} + +.spinner-loading { + color: #9f9d9c; +} diff --git a/Submission_files/Attachments.js.download b/Submission_files/Attachments.js.download new file mode 100644 index 0000000000..7e9c4e7134 --- /dev/null +++ b/Submission_files/Attachments.js.download @@ -0,0 +1,144 @@ +function escapeHtmlAttribute(value) { + return String(value ?? '') + .replaceAll('&', '&') + .replaceAll('"', '"') + .replaceAll("'", ''') + .replaceAll('<', '<') + .replaceAll('>', '>'); +} + +function generateAttachmentButtonContent(data, type, full, meta, attachmentType) { + let ownerId = getAttachmentOwnerId(attachmentType); + let downloadUrl = `/api/app/attachment/${attachmentType}/${encodeURIComponent(ownerId)}/download/${encodeURIComponent(full.fileName)}`; + let isCreator = abp.currentUser.id == full.creatorId; + let escapedAttachmentType = escapeHtmlAttribute(attachmentType); + let escapedOwnerId = escapeHtmlAttribute(ownerId); + let escapedFileName = escapeHtmlAttribute(full.fileName); + let escapedDisplayName = escapeHtmlAttribute(full.displayName || full.fileName); + let html = ` + + `; + + return html; +} + +function previewAttachment(attachmentType, ownerId, fileName, displayName) { + let previewModal = new abp.ModalManager({ + viewUrl: '../Attachments/PreviewAttachmentModal' + }); + previewModal.open({ + attachmentType: attachmentType, + ownerId: ownerId, + fileName: fileName, + displayName: displayName + }); +} + +$(document).on('click', '.js-preview-attachment', function () { + previewAttachment( + $(this).attr('data-attachment-type'), + $(this).attr('data-owner-id'), + $(this).attr('data-file-name'), + $(this).attr('data-display-name') + ); +}); + +function getAttachmentOwnerId(attachmentType) { + switch (attachmentType) { + case 'Assessment': + return decodeURIComponent($("#AssessmentId").val()); + case 'Application': + return decodeURIComponent($("#DetailsViewApplicationId").val()); + case 'Applicant': + return decodeURIComponent($("#DetailsViewApplicantId").val()); + default: + return null; + } +} + +function deleteAttachment(attachmentType, s3ObjectKey, fileName) { + let deleteAttachmentModal = new abp.ModalManager({ + viewUrl: '../Attachments/DeleteAttachmentModal' + }); + + deleteAttachmentModal.onResult(function () { + abp.notify.success( + 'Attachment is successfully deleted.', + 'Delete Attachment' + ); + + refreshAttachmentWidget(attachmentType); + }); + + deleteAttachmentModal.open({ + s3ObjectKey: s3ObjectKey, + fileName: fileName, + attachmentType: attachmentType, + attachmentTypeId: getAttachmentOwnerId(attachmentType), + }); +} + +function updateAttachmentMetadata(attachmentType, attachmentId) { + let updateAttachmentModal = new abp.ModalManager({ + viewUrl: '../Attachments/UpdateAttachmentModal' + }); + updateAttachmentModal.onResult(function () { + abp.notify.success( + 'Attachment is successfully updated.', + 'Update Attachment' + ); + refreshAttachmentWidget(attachmentType); + }); + updateAttachmentModal.open({ + attachmentType: attachmentType, + attachmentId: attachmentId + }); +} + +$(document).on('mouseenter', '.attachments-table .dropdown', function () { + const rect = this.getBoundingClientRect(); + const $content = $(this).find('.dropdown-content'); + $content.css({ visibility: 'hidden', display: 'block', top: '', bottom: '' }); + const dropdownHeight = $content.outerHeight(); + $content.css({ visibility: '', display: '' }); + if (rect.bottom + dropdownHeight > window.innerHeight) { + $content.css({ bottom: (window.innerHeight - rect.top) + 'px', top: '' }); + } else { + $content.css({ top: rect.bottom + 'px', bottom: '' }); + } +}); + +function refreshAttachmentWidget(attachmentType) { + switch (attachmentType) { + case 'Assessment': + PubSub.publish('refresh_assessment_attachment_list'); break; + case 'Application': + PubSub.publish('refresh_application_attachment_list'); break; + case 'Applicant': + PubSub.publish('refresh_applicant_attachment_list'); break; + case 'CHEFS': + PubSub.publish('refresh_chefs_attachment_list'); break; + default: break; + } +} + diff --git a/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg b/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg new file mode 100644 index 0000000000..98e7013ba9 --- /dev/null +++ b/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Submission_files/ChefsAttachments.css b/Submission_files/ChefsAttachments.css new file mode 100644 index 0000000000..cb02550ca9 --- /dev/null +++ b/Submission_files/ChefsAttachments.css @@ -0,0 +1,116 @@ +#ChefsAttachmentsTable a { + text-decoration: none; + --bs-btn-active-color: var(--bc-colors-white-primary-500); + --bs-btn-active-bg: var(--bc-colors-blue-primary-500); +} + +.attachments__title-button-split { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: stretch; + gap: 8px; + margin-bottom: 8px; +} + +.submission-title-and-actions { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 8px; + flex-wrap: nowrap; +} + +.sorting_disabled:before, +.sorting_disabled:after { + content: '' !important; +} + +.submission-title { + display: flex; + align-items: center; + height: 36px; + padding-top: 0; + flex: 0 0 auto; +} + +.submission-button-section { + display: flex; + flex: 1 1 auto; + flex-wrap: nowrap; + align-items: center; + align-content: center; + justify-content: flex-end; + gap: 6px; + min-width: 0; + overflow-x: auto; + overflow-y: hidden; +} + +.submission-button-section--top { + justify-content: flex-end; +} + +.submission-button-section--bottom { + justify-content: flex-end; +} + +.submission-button-section .btn { + flex: 0 0 auto; + height: 36px; + display: inline-flex; + align-items: center; + justify-content: center; + line-height: 1; + white-space: nowrap; +} + +.submission-button-section .btn + .btn { + margin-left: 0; +} + +.submission-button-section .button-content { + display: inline-flex; + align-items: center; + gap: 0.5rem; + white-space: nowrap; +} + +#ChefsAttachmentsTable_paginate { + display: block !important; + padding-top: 35px; +} + +/* AI Summary Row Styles */ +.ai-summary-row { + border-left: 4px solid var(--bc-colors-blue-primary); + background: #faf9f8; + padding: 10px 15px; +} + +#ChefsAttachmentsTable td.ai-summary-cell { + padding: 0; +} + +#ChefsAttachmentsTable .ai-summary-content { + color: #292929; + padding: 8px 12px; +} + +#ChefsAttachmentsTable .ai-summary-content strong { + color: var(--bc-colors-blue-primary); + font-weight: 600; + font-size: 13px; +} + +#ChefsAttachmentsTable .ai-summary-content p { + margin-bottom: 0; + color: #495057; + white-space: pre-wrap; + word-wrap: break-word; +} + +#ChefsAttachmentsTable tr.shown { + background-color: rgba(13, 110, 253, 0.05); +} diff --git a/Submission_files/ChefsAttachments.js.download b/Submission_files/ChefsAttachments.js.download new file mode 100644 index 0000000000..969a7e5382 --- /dev/null +++ b/Submission_files/ChefsAttachments.js.download @@ -0,0 +1,558 @@ +// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js +$(function () { + globalThis.queueAttachmentSummary = function (triggerButton = null) { + $('#generateAiSummaries') + .data('trigger-button', triggerButton || null) + .trigger('click'); + }; + + const downloadAll = $('#downloadAll'); + const dt = $('#ChefsAttachmentsTable'); + let chefsDataTable; + let selectedAttachmentIds = []; + const nullPlaceholder = '—'; + + let inputAction = function (requestData, dataTableSettings) { + const urlParams = new URL(globalThis.location.toLocaleString()).searchParams; + const applicationId = urlParams.get('ApplicationId'); + return applicationId; + }; + + let responseCallback = function (result) { + if (result.length <= 0) { + $('.dataTables_paginate').hide(); + } + + if (result) { + setTimeout(function () { + PubSub.publish('update_application_attachment_count', { + chefs: result.length, + }); + }, 10); + + $(downloadAll).prop('disabled', result.length === 0); + selectedAttachmentIds = []; + setGenerateSummariesEnabled(); + + const hasAISummaries = result.some( + (item) => item.aiSummary && item.aiSummary.trim() !== '' + ); + const $toggleButton = $('#toggleAllAISummaries'); + if ($toggleButton.length > 0) { + $toggleButton.prop('disabled', !hasAISummaries); + if (!hasAISummaries) { + $toggleButton.attr('title', 'No AI summaries available'); + } else { + $toggleButton.attr('title', 'Show AI Summaries'); + } + } + } + return { + data: formatItems(result), + }; + }; + + function getColumns() { + return [ + getSelectColumn('Select Attachment', 'rowCount', 'chefs-files'), + getChefsFileNameColumn(), + getChefsLabelColumn(), + getChefsFileDownloadColumn(), + ]; + } + + function setGenerateSummariesEnabled() { + $('#generateAiSummaries').prop('disabled', selectedAttachmentIds.length === 0); + } + + function setSelectAllState() { + const totalCheckboxes = $('#ChefsAttachmentsTable .chkbox').length; + const selectedCheckboxes = $('#ChefsAttachmentsTable .chkbox:checked').length; + $('.select-all-chefs-files').prop( + 'checked', + totalCheckboxes > 0 && selectedCheckboxes === totalCheckboxes + ); + } + + function resetAttachmentSelection() { + selectedAttachmentIds = []; + chefsDataTable.rows().deselect(); + chefsDataTable.$('.chkbox').prop('checked', false); + $('.select-all-chefs-files').prop('checked', false); + setGenerateSummariesEnabled(); + } + + function setAllAttachmentSelections(isSelected) { + if (isSelected) { + chefsDataTable.rows({ page: 'current' }).select(); + } else { + chefsDataTable.rows({ page: 'current' }).deselect(); + } + } + + function getChefsFileNameColumn() { + return { + title: 'Document Name', + name: 'chefsFileName', + data: 'fileName', + className: 'data-table-header text-break', + index: 1, + orderable: false, + width: '40%', + }; + } + + function getChefsLabelColumn() { + return { + title: 'Label', + data: 'displayName', + className: 'data-table-header text-break', + width: '35%', + render: function (data) { + return data ?? nullPlaceholder; + }, + }; + } + + let formatItems = function (items) { + const newData = items.map((item, index) => { + return { + ...item, + rowCount: index, + }; + }); + return newData; + }; + + chefsDataTable = dt.DataTable( + abp.libs.datatables.normalizeConfiguration({ + serverSide: false, + paging: true, + order: [[1, 'desc']], + searching: true, + iDisplayLength: 25, + lengthMenu: [10, 25, 50, 100], + scrollX: true, + scrollCollapse: false, + processing: true, + autoWidth: true, + select: { + style: 'multiple', + selector: 'td:not(:nth-child(4))', + }, + ajax: abp.libs.datatables.createAjax( + unity.grantManager.attachments.attachment + .getApplicationChefsFileAttachments, + inputAction, + responseCallback + ), + columnDefs: getColumns(), + externalFilterButtonId: 'btn-toggle-filter-submissions', + }) + ); + + initializeFilterRowPlugin(chefsDataTable, 'btn-toggle-filter-submissions'); + + PubSub.subscribe('refresh_chefs_attachment_list', (msg, data) => { + chefsDataTable.ajax.reload(); + }); + + // Generate AI summaries for the current application attachments. + const $generateAISummariesButton = $('#generateAiSummaries'); + if ($generateAISummariesButton.length > 0) { + $generateAISummariesButton.on('click', function () { + const $button = $(this); + const triggerButton = $button.data('trigger-button'); + const $activeButton = triggerButton ? $(triggerButton) : $button; + const rows = triggerButton + ? chefsDataTable.rows().data().toArray() + : chefsDataTable.rows({ selected: true }).data().toArray(); + const summaryAttachmentIds = rows.map((row) => row.id); + + $button.removeData('trigger-button'); + + if (summaryAttachmentIds.length === 0) { + abp.message.warn( + triggerButton + ? 'No attachments were found to generate summaries.' + : 'Select at least one attachment to generate summaries.' + ); + return; + } + + const existingHTML = $activeButton.html(); + + $activeButton + .html( + 'Generating...' + ) + .prop('disabled', true); + globalThis.AIGenerationButtonState?.setGenerating($activeButton); + + $.ajax({ + url: '/api/app/attachment-summary/generate-attachment-summaries', + data: JSON.stringify(summaryAttachmentIds), + contentType: 'application/json', + type: 'POST', + success: function () { + resetAttachmentSelection(); + chefsDataTable.ajax.reload(); + abp.notify.success('AI summaries generated successfully.'); + globalThis.AIGenerationButtonState?.restore($activeButton); + $activeButton.html(existingHTML).prop('disabled', false); + }, + error: function (error) { + console.error('Error generating AI summaries:', error); + abp.message.error('An error occurred while generating AI summaries. Please try again.'); + globalThis.AIGenerationButtonState?.restore($activeButton); + $activeButton.html(existingHTML).prop('disabled', false); + setGenerateSummariesEnabled(); + }, + }); + }); + } + + // Toggle all AI summaries (only if feature is enabled) + const $toggleAllAISummariesButton = $('#toggleAllAISummaries'); + let allAISummariesExpanded = false; + + if ($toggleAllAISummariesButton.length > 0) { + $toggleAllAISummariesButton.on('click', function () { + const $button = $(this); + const $icon = $button.find('i'); + const $label = $button.find('.toggle-ai-summaries-label'); + + if ($button.prop('disabled')) { + return; + } + + if (allAISummariesExpanded) { + chefsDataTable.rows().every(function () { + const row = this; + if (row.child.isShown()) { + const $childRow = $(row.child()); + const $summaryRow = $childRow.find('.ai-summary-row'); + + $summaryRow.removeClass('fade-in').addClass('fade-out'); + + setTimeout(function () { + row.child.hide(); + $(row.node()).removeClass('shown'); + $summaryRow.removeClass('fade-out'); + }, 500); + } + }); + $icon.removeClass('fa-chevron-up').addClass('fa-chevron-down'); + $label.text('Show Summaries'); + $button.attr('title', 'Show AI Summaries'); + allAISummariesExpanded = false; + } else { + chefsDataTable.rows().every(function () { + const row = this; + const rowData = row.data(); + + if (rowData.aiSummary && rowData.aiSummary.trim() !== '') { + const summaryHtml = formatAISummary(rowData); + + row.child(summaryHtml, 'ai-summary-cell').show(); + $(row.node()).addClass('shown'); + + setTimeout(function () { + const $childRow = $(row.child()); + $childRow.find('.ai-summary-row').addClass('fade-in'); + }, 10); + } + }); + $icon.removeClass('fa-chevron-down').addClass('fa-chevron-up'); + $label.text('Hide Summaries'); + $button.attr('title', 'Hide AI Summaries'); + allAISummariesExpanded = true; + } + }); + } + + chefsDataTable.on('draw.dt', function () { + if (allAISummariesExpanded) { + const $button = $('#toggleAllAISummaries'); + const $icon = $button.find('i'); + const $label = $button.find('.toggle-ai-summaries-label'); + $icon.removeClass('fa-chevron-up').addClass('fa-chevron-down'); + $label.text('Show Summaries'); + $button.attr('title', 'Show AI Summaries'); + allAISummariesExpanded = false; + } + }); + + function formatAISummary(data) { + const safeSummary = escapeHtml(data.aiSummary || 'No summary available'); + return ( + '
' + + '
' + + ' Summary: ' + + '

' + + safeSummary + + '

' + + '
' + + '
' + ); + } + + $(document).on('click', '.select-all-chefs-files', function () { + setAllAttachmentSelections($(this).is(':checked')); + }); + + chefsDataTable.on('select', function (e, dt, type, indexes) { + if (type !== 'row') { + return; + } + + indexes.forEach((index) => { + const data = chefsDataTable.row(index).data(); + $('#row_' + index).prop('checked', true); + + if (data?.id && !selectedAttachmentIds.includes(data.id)) { + selectedAttachmentIds.push(data.id); + } + }); + setGenerateSummariesEnabled(); + setSelectAllState(); + }); + + chefsDataTable.on('deselect', function (e, dt, type, indexes) { + if (type !== 'row') { + return; + } + + indexes.forEach((index) => { + const data = chefsDataTable.row(index).data(); + $('#row_' + index).prop('checked', false); + + if (data?.id) { + selectedAttachmentIds = selectedAttachmentIds.filter((id) => id !== data.id); + } + }); + setGenerateSummariesEnabled(); + setSelectAllState(); + }); + + $('#resyncSubmissionAttachments').on('click', function () { + let applicationId = document.getElementById( + 'AssessmentResultViewApplicationId' + ).value; + try { + unity.grantManager.attachments.attachment + .resyncSubmissionAttachments(applicationId) + .done(function () { + abp.notify.success('Submission Attachment/s has been resynced.'); + chefsDataTable.ajax.reload(); + chefsDataTable.columns.adjust(); + }); + } catch (error) { + console.log(error); + } + }); + + $('#attachments-tab').on('click', function () { + chefsDataTable.columns.adjust(); + }); + + $(downloadAll).on('click', function () { + const refNo = + document.getElementsByClassName('reference-no')[0].textContent; + const _this = $(this); + const existingHTML = _this.html(); + const zip = new JSZip(); + const tempFiles = chefsDataTable.rows().data().toArray().map((row) => ({ + FormSubmissionId: row.chefsSubmissionId, + ChefsFileId: row.chefsFileId, + Filename: row.fileName, + })); + + if (tempFiles.length > 0) { + $.ajax({ + url: '/api/app/attachment/chefs/download-all', + data: JSON.stringify(tempFiles), + contentType: 'application/json', + type: 'POST', + beforeSend: function () { + $(_this) + .html( + '
Downloading...
' + ) + .prop('disabled', true); + }, + success: function (data) { + data.forEach((file) => { + zip.file(file.fileDownloadName, file.fileContents, { + base64: true, + }); + }); + + zip.generateAsync({ type: 'blob' }).then(function (content) { + const link = document.createElement('a'); + link.href = URL.createObjectURL(content); + link.download = `${refNo}-All_Attachments.zip`; + link.click(); + }); + + abp.notify.success( + '', + 'The files have been downloaded successfully.' + ); + $(_this).html(existingHTML).prop('disabled', false); + }, + error: function (error) { + if (error.status === 403) { + showChefsAPIAccessError(); + } else { + abp.notify.error( + '', + 'The selected files exceed more than 80MB download limit. Please deselect some files and try again.' + ); + } + + $(_this).html(existingHTML).prop('disabled', false); + }, + }); + } + }); +}); + +function getChefsFileDownloadColumn() { + return { + title: '', + name: 'chefsFileDownload', + data: 'chefsFileId', + width: '60px', + className: 'text-nowrap', + render: function (data, type, full, meta) { + let submissionId = encodeURIComponent(full.chefsSubmissionId); + let fileId = encodeURIComponent(data); + let fileName = full.fileName; + let displayName = full.displayName || full.fileName; + let html = + ''; + return html; + }, + orderable: false, + index: 2, + }; +} + +function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; +} + +function downloadChefsFile(event) { + const button = event.currentTarget; + const chefsFileId = button.getAttribute('chefs-data'); + const chefsSubmissionId = button.getAttribute('chefs-submission-id'); + const chefsFileName = button.getAttribute('chefs-file-name'); + console.log('Downloading CHEFS file:', { + chefsFileId, + chefsSubmissionId, + chefsFileName, + }); + + $.ajax({ + url: + '/api/app/attachment/chefs/' + + chefsSubmissionId + + '/download/' + + chefsFileId + + '/' + + chefsFileName, + type: 'GET', + success: function (data) { + const downloadUrl = + '/api/app/attachment/chefs/' + + encodeURIComponent(chefsSubmissionId) + + '/download/' + + encodeURIComponent(chefsFileId) + + '/' + + encodeURIComponent(chefsFileName); + + const link = document.createElement('a'); + link.href = downloadUrl; + link.download = chefsFileName; + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + abp.notify.success('', 'The file has been downloaded successfully.'); + }, + error: function (error) { + console.log('Error downloading CHEFS file:', error); + if (error.responseText?.includes('You do not have access')) { + showChefsAPIAccessError(); + } else { + abp.notify.error( + '', + error.responseText || + 'An error occurred while downloading the file.' + ); + } + }, + }); +} + +function previewChefsFile(event) { + const button = event.currentTarget; + const chefsFileId = button.getAttribute('chefs-data'); + const chefsSubmissionId = button.getAttribute('chefs-submission-id'); + const chefsFileName = button.getAttribute('chefs-file-name'); + const chefsDisplayName = button.getAttribute('chefs-display-name'); + + let previewModal = new abp.ModalManager({ + viewUrl: '../Attachments/PreviewAttachmentModal' + }); + previewModal.open({ + attachmentType: 'chefs', + ownerId: chefsSubmissionId, + chefsFileId: chefsFileId, + fileName: chefsFileName, + displayName: chefsDisplayName + }); +} + +function showChefsAPIAccessError() { + const message = + 'Please check that the CHEFS checkbox is enabled for: ' + + "'Allow this API key to access submitted files' in the related CHEFS form"; + + Swal.fire({ + title: 'CHEFS is not allowing Unity access to the File Download', + text: message, + confirmButtonText: 'Ok', + customClass: { + confirmButton: 'btn btn-primary', + }, + }); +} diff --git a/Submission_files/DateUtils.js.download b/Submission_files/DateUtils.js.download new file mode 100644 index 0000000000..651e25ebc5 --- /dev/null +++ b/Submission_files/DateUtils.js.download @@ -0,0 +1,41 @@ +/** + * Date utility functions for Grant Manager application + */ +const DateUtils = (function () { + 'use strict'; + + /** + * Formats a UTC date string to local date format + * @param {string|Date} dateUtc - The UTC date to format + * @param {string} type - The type of formatting (for DataTables compatibility) + * @param {object} options - Additional formatting options + * @returns {string|number|null} Formatted date string or timestamp for sorting, null if input is invalid + */ + function formatUtcDateToLocal(dateUtc, type, options) { + if (!dateUtc) { + return null; + } + + const date = new Date(dateUtc); + + // Required for DataTables sorting & filtering + if (type === 'sort' || type === 'type') { + return date.getTime(); + } + + return date.toLocaleDateString( + abp.localization.currentCulture.name, + { + year: 'numeric', + month: '2-digit', + day: '2-digit', + ...options + } + ); + } + + // Public API + return { + formatUtcDateToLocal: formatUtcDateToLocal + }; +})(); \ No newline at end of file diff --git a/Submission_files/Default(1).css b/Submission_files/Default(1).css new file mode 100644 index 0000000000..5ccbfa7afb --- /dev/null +++ b/Submission_files/Default(1).css @@ -0,0 +1,53 @@ +.spinner-loader { + display: flex; + align-items: center; + justify-content: center; +} + +.action-bar__drop-down-icon-link { + cursor: pointer; + display: flex; + gap: 0.5rem; +} + + +.search-action-bar { + display: flex; + justify-content: flex-end; + align-items: center; +} + +.search-action-bar_search-wrapper { + flex: 1; +} + +.action-bar-btn-unavailable { + display: none; +} + +.margin-left-auto { + margin-left: auto; +} + +.date-input-filter-div { + display: inline-block; + padding: 10px; + padding-top: 0px; + margin-top: -10px; + margin-bottom: -10px; + padding-bottom: 0px !important; +} + +.custom-date-range-container-div { + display: inline-block; + padding: 0px; + margin: 0px; +} + +.quick-date-input { + font-size: var(--bc-font-size); + color: var(--bc-colors-grey-text-500); + border-radius: var(--bc-layout-margin-small) !important; + border: 2px solid var(--bc-colors-blue-primary); + text-overflow: ellipsis; +} diff --git a/Submission_files/Default(1).js.download b/Submission_files/Default(1).js.download new file mode 100644 index 0000000000..80b1dc11f9 --- /dev/null +++ b/Submission_files/Default(1).js.download @@ -0,0 +1,261 @@ +$(function () { + let selectedApplicationIds = decodeURIComponent($("#DetailsViewApplicationId").val()); + + let approveApplicationsModal = new abp.ModalManager({ + viewUrl: '../Approve/ApproveApplicationsModal' + }); + + let dontApproveApplicationsModal = new abp.ModalManager({ + viewUrl: '../Approve/ApproveApplicationsModal' + }); + + let tagApplicationModal = new abp.ModalManager({ + viewUrl: '../ApplicationTags/ApplicationTagsSelectionModal', + }); + + approveApplicationsModal.onResult(function () { + abp.notify.success( + 'This application has been successfully approved', + 'Approve Application' + ); + }); + dontApproveApplicationsModal.onResult(function () { + abp.notify.success( + 'This application has now been disapproved', + 'Not Approve Application' + ); + }); + + $('#approveApplications').on('click', function () { + approveApplicationsModal.open({ + applicationIds: JSON.stringify(new Array(selectedApplicationIds)), + operation: 'GRANT_APPROVED', + message: 'Are you sure you want to approve this application?', + title: 'Approve Applications', + }); + }); + + let startAssessmentModal = new abp.ModalManager({ + viewUrl: '../Approve/ApproveApplicationsModal' + }); + + startAssessmentModal.onResult(function () { + abp.notify.success( + 'Assessment is now started for this application', + 'Start Assessment' + ); + }); + + $('#startAssessment').on('click', function () { + startAssessmentModal.open({ + applicationIds: JSON.stringify(new Array(selectedApplicationIds)), + operation: 'UNDER_ASSESSMENT', + message: 'Are you sure you want to start assessment for this application?', + title: 'Start Assessment', + }); + }); + + let completeAssessmentModal = new abp.ModalManager({ + viewUrl: '../Approve/ApproveApplicationsModal' + }); + + completeAssessmentModal.onResult(function () { + abp.notify.success( + 'Assessment is now completed for this application', + 'Completed Assessment' + ); + }); + + // Helper function to process tag items and group them by application ID + function processTagItems(tags, groupedTags) { + tags.forEach(function (item) { + if (!item.tag) return; + let appId = item.applicationId; + + if (!groupedTags[appId]) { + groupedTags[appId] = []; + } + + let exists = groupedTags[appId].some(t => t.id === item.tag.id); + if (!exists) { + groupedTags[appId].push(item.tag); + } + }); + } + + // Helper function to ensure all application IDs have entries in groupedTags + function initializeApplicationEntries(applicationIds, groupedTags) { + applicationIds.forEach(function (id) { + if (!groupedTags.hasOwnProperty(id)) { + groupedTags[id] = []; + } + }); + } + + // Helper function to check if tag exists in application tags + function tagExistsInApp(tag, appTags) { + return appTags.some(n => n.id === tag.id); + } + + // Helper function to filter common tags between two applications + function filterCommonTags(prevTags, nextTags) { + return prevTags.filter(p => tagExistsInApp(p, nextTags)); + } + + // Helper function to calculate common tags across all applications + function calculateCommonTags(groupedTags) { + let groupedValues = Object.values(groupedTags); + if (groupedValues.length === 0) return []; + + return groupedValues.reduce(filterCommonTags); + } + + // Helper function to check if tag is common + function isCommonTag(tag, commonTags) { + return commonTags.some(ct => ct.id === tag.id); + } + + // Helper function to sort tags by name + function sortTagsByName(tags) { + return [...tags].sort((a, b) => a.name.localeCompare(b.name)); + } + + // Helper function to create application tag summary + function createAppTagSummary(appId, tagList, commonTags) { + let uncommonTags = tagList.filter(tag => !isCommonTag(tag, commonTags)); + + return { + applicationId: appId, + commonTags: sortTagsByName(commonTags), + uncommonTags: sortTagsByName(uncommonTags) + }; + } + + // Helper function to create tag summary data + function createTagSummary(groupedTags, commonTags) { + return Object.entries(groupedTags).map(([appId, tagList]) => + createAppTagSummary(appId, tagList, commonTags) + ); + } + + // Helper function to collect uncommon tags + function collectUncommonTags(groupedTags, commonTags) { + let uncommonTags = []; + Object.entries(groupedTags).forEach(([appId, tagList]) => { + let uncommon = tagList.filter(tag => !isCommonTag(tag, commonTags)); + uncommonTags = uncommonTags.concat(uncommon); + }); + return uncommonTags; + } + + // Helper function to build tag input array + function buildTagInputArray(commonTags, uncommonTags) { + let tagInputArray = []; + + if (uncommonTags.length > 0) { + tagInputArray.unshift({ + tagId: '00000000-0000-0000-0000-000000000000', + name: 'Uncommon Tags', + class: 'tags-uncommon', + id: '00000000-0000-0000-0000-000000000000' + }); + } + + commonTags.forEach(function (tag) { + tagInputArray.push({ + tagId: tag.id, + name: tag.name, + class: 'tags-common', + id: tag.id + }); + }); + + return tagInputArray; + } + + tagApplicationModal.onOpen(async function () { + let tagInput = new TagsInput({ + selector: 'SelectedTags', + duplicate: false, + max: 50 + }); + + let cacheKey = $('#CacheKey').val(); + let applicationIds = []; + + if (!cacheKey) { + console.error("Cache key is missing"); + abp.notify.error('Failed to load application tags. Please try again.'); + return; + } + + // Retrieve application IDs from hidden field (populated by modal code-behind) + let selectedIds = $('#SelectedApplicationIds').val(); + applicationIds = JSON.parse(selectedIds); + + if (!applicationIds || applicationIds.length === 0) return; + + try { + let groupedTags = {}; + + let allTags = await unity.grantManager.globalTag.tags.getList(); + let tags = await unity.grantManager.grantApplications.applicationTags.getListWithCacheKey(cacheKey); + + processTagItems(tags, groupedTags); + initializeApplicationEntries(applicationIds, groupedTags); + + let commonTags = calculateCommonTags(groupedTags); + let alltags = createTagSummary(groupedTags, commonTags); + let uncommonTags = collectUncommonTags(groupedTags, commonTags); + + $('#TagsJson').val(JSON.stringify(alltags)); + + let tagInputArray = buildTagInputArray(commonTags, uncommonTags); + + tagInput.setSuggestions( + (allTags || []).filter((value, index, self) => + index === self.findIndex(t => t.id === value.id) + ).sort((a, b) => a.name.localeCompare(b.name)) + ); + + tagInput.addData(tagInputArray); + } catch (error) { + console.error("Error loading tag select list", error); + } + }); + + tagApplicationModal.onResult(function () { + abp.notify.success( + 'The application tags have been successfully updated.', + 'Application Tags' + ); + PubSub.publish("ApplicationTags_refresh"); + PubSub.publish("refresh_application_list"); + + }); + + $('#completeAssessment').on('click', function () { + completeAssessmentModal.open({ + applicationIds: JSON.stringify(new Array(selectedApplicationIds)), + operation: 'ASSESSMENT_COMPLETED', + message: 'Are you sure you want to complete assessment for this application?', + title: 'Complete Assessment', + }); + }); + + $('#tagApplication').on('click', function () { + // Store application IDs in distributed cache to avoid URL length limits + unity.grantManager.applications.applicationBulkActions + .storeApplicationIds({ applicationIds: new Array(selectedApplicationIds) }) + .then(function(response) { + tagApplicationModal.open({ + cacheKey: response.cacheKey, + actionType: 'Add' + }); + }) + .catch(function(error) { + abp.notify.error('Failed to prepare tag selection. Please try again.'); + console.error('Error storing application IDs:', error); + }); + }); +}); diff --git a/Submission_files/Default(10).css b/Submission_files/Default(10).css new file mode 100644 index 0000000000..9cc85b1d6d --- /dev/null +++ b/Submission_files/Default(10).css @@ -0,0 +1 @@ +/* Placeholder file required by the component structure */ \ No newline at end of file diff --git a/Submission_files/Default(10).js.download b/Submission_files/Default(10).js.download new file mode 100644 index 0000000000..d7ab43374f --- /dev/null +++ b/Submission_files/Default(10).js.download @@ -0,0 +1,196 @@ +$(function () { + let selectedPaymentIds = []; + let tagPaymentModal = new abp.ModalManager({ + viewUrl: 'PaymentTags/PaymentTagsSelectionModal', + }); + + tagPaymentModal.onOpen(async function () { + let tagInput = new TagsInput({ + selector: 'SelectedTags', + duplicate: false, + max: 50 + }); + let selectedIds = $('#SelectedPaymentRequestIds').val(); + let paymentRequestIds = JSON.parse(selectedIds); + let cacheKey = $('#CacheKey').val(); + + if (!paymentRequestIds || paymentRequestIds.length === 0) return; + if (!cacheKey) { + console.error("Cache key is missing"); + abp.notify.error('Failed to load payment tags. Please try again.'); + return; + } + + try { + let commonTags = []; + let uncommonTags = []; + let allTags = []; + let groupedTags = {}; + + + allTags = await unity.grantManager.globalTag.tags.getList(); + + // Use cache key to avoid URL length limits with many payment IDs + let tags = await unity.payments.paymentTags.paymentTag.getListWithCacheKey(cacheKey); + + + tags.forEach(function (item) { + if (!item.tag) return; + let paymentId = item.paymentRequestId; + if (!groupedTags[paymentId]) { + groupedTags[paymentId] = []; + } + + let exists = groupedTags[paymentId].some(t => t.id === item.tag.id); + if (!exists) { + groupedTags[paymentId].push(item.tag); + } + }); + + paymentRequestIds.forEach(function (id) { + if (!groupedTags.hasOwnProperty(id)) { + groupedTags[id] = []; + } + }); + + // Helper functions to reduce nesting depth + function hasMatchingId(tagA, tagB) { + return tagA.id === tagB.id; + } + + function tagExistsInList(tag, tagList) { + return tagList.some(t => hasMatchingId(t, tag)); + } + + function filterCommonTags(prev, next) { + return prev.filter(p => tagExistsInList(p, next)); + } + + function getUncommonTags(tagList) { + return tagList.filter(tag => !tagExistsInList(tag, commonTags)); + } + + function sortByName(a, b) { + return a.name.localeCompare(b.name); + } + + let groupedValues = Object.values(groupedTags); + if (groupedValues.length > 0) { + commonTags = groupedValues.reduce(filterCommonTags); + } + + let allTagEntries = Object.entries(groupedTags).map(([paymentId, tagList]) => { + let uncommon = getUncommonTags(tagList); + + return { + paymentRequestId : paymentId, + commonTags: [...commonTags].sort(sortByName), + uncommonTags: uncommon.sort(sortByName) + }; + }); + + + $('#TagsJson').val(JSON.stringify(allTagEntries)); + + let tagInputArray = []; + + + Object.entries(groupedTags).forEach(function ([paymentId, tagList]) { + let uncommon = getUncommonTags(tagList); + uncommonTags = uncommonTags.concat(uncommon); + }); + + if (uncommonTags.length > 0) { + tagInputArray.unshift({ + tagId: '00000000-0000-0000-0000-000000000000', + name: 'Uncommon Tags', + class: 'tags-uncommon', + id: '00000000-0000-0000-0000-000000000000' + }); + } + + + if (commonTags.length > 0) { + commonTags.forEach(function (tag) { + tagInputArray.push({ + tagId: tag.id, + name: tag.name, + class: 'tags-common', + id: tag.id + }); + }); + } + + tagInput.setSuggestions( + (allTags || []).filter((value, index, self) => + index === self.findIndex(t => t.id === value.id) + ).sort((a, b) => a.name.localeCompare(b.name)) + ); + + tagInput.addData(tagInputArray); + } catch (error) { + console.error("Error loading tag select list", error); + } + + }); + + PubSub.subscribe("select_batchpayment_application", (msg, data) => { + if (!selectedPaymentIds.includes(data.id)) { + selectedPaymentIds.push(data.id); + } + manageActionButtons(); + }); + + PubSub.subscribe("deselect_batchpayment_application", (msg, data) => { + if (data === "reset_data") { + selectedPaymentIds = []; + } else { + selectedPaymentIds = selectedPaymentIds.filter(item => item !== data.id); + } + manageActionButtons(); + }); + + function manageActionButtons() { + if (selectedPaymentIds.length == 0) { + $('*[data-selector="batch-payment-table-actions"]').prop('disabled', true); + $('*[data-selector="batch-payment-table-actions"]').addClass('action-bar-btn-unavailable'); + $('.action-bar').addClass('disabled'); + $('#tagPayment').prop('disabled', true); + } + else { + $('*[data-selector="batch-payment-table-actions"]').prop('disabled', false); + $('*[data-selector="batch-payment-table-actions"]').removeClass('action-bar-btn-unavailable'); + $('.action-bar').addClass('active'); + $('#tagPayment').removeClass('disabled'); + $('#tagPayment').prop('disabled', false); + } + } + + $('#tagPayment').on('click', function () { + // Store payment IDs in distributed cache to avoid URL length limits + unity.payments.paymentRequests.paymentBulkActions + .storePaymentIds({ paymentRequestIds: selectedPaymentIds }) + .then(function(response) { + tagPaymentModal.open({ + cacheKey: response.cacheKey, + actionType: 'Add' + }); + }) + .catch(function(error) { + abp.notify.error('Failed to prepare tag selection. Please try again.'); + console.error('Error storing payment IDs:', error); + }); + }); + + + tagPaymentModal.onResult(function () { + abp.notify.success( + 'The payment tags have been successfully updated.', + 'Payment Tags' + ); + selectedPaymentIds = []; + manageActionButtons(); + PubSub.publish("refresh_payment_list"); + }); +}); + diff --git a/Submission_files/Default(11).css b/Submission_files/Default(11).css new file mode 100644 index 0000000000..97c7876681 --- /dev/null +++ b/Submission_files/Default(11).css @@ -0,0 +1,2 @@ +/* Intentionally left blank */ + diff --git a/Submission_files/Default(11).js.download b/Submission_files/Default(11).js.download new file mode 100644 index 0000000000..0ab5b2c64d --- /dev/null +++ b/Submission_files/Default(11).js.download @@ -0,0 +1,2 @@ +$(function () { +}); diff --git a/Submission_files/Default(12).css b/Submission_files/Default(12).css new file mode 100644 index 0000000000..d96a3fce6c --- /dev/null +++ b/Submission_files/Default(12).css @@ -0,0 +1,59 @@ +.summary-container .form-label { + font-size: var(--bc-font-size-sm); + color: var(--bc-colors-grey-text-300); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 0; +} + +.display-input-label { + font-size: var(--bc-font-size-sm); + color: var(--bc-colors-grey-text-300); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 0; +} + +.display-input { + color: var(--bc-colors-grey-text-200); + pointer-events: none; + background-color: var(--bc-colors-grey-hover) !important; + opacity: var(--bs-btn-disabled-opacity); + background-blend-mode: difference; + border: var(--bs-border-width) solid var(--bs-border-color); + padding: 0.4rem; + border-radius: var(--bc-layout-margin-small) !important; + min-height: 2rem; +} + +.display-input-currency { + /*text-align: right; -check if right alignment require */ +} + +.summary-table { + width: 100%; + border-collapse: separate; + border-spacing: 5px 5px; +} +.tag-wrap { + flex-wrap: wrap; + padding-right: 0px; +} + +.full-length-tag { + width: 100%; +} +.empty-user-role{ + color : gray; +} + + +.user-tags-details-input-wrapper { + border: 0px; +} + +.currency-display { + text-align: right; +} diff --git a/Submission_files/Default(12).js.download b/Submission_files/Default(12).js.download new file mode 100644 index 0000000000..0ab5b2c64d --- /dev/null +++ b/Submission_files/Default(12).js.download @@ -0,0 +1,2 @@ +$(function () { +}); diff --git a/Submission_files/Default(13).css b/Submission_files/Default(13).css new file mode 100644 index 0000000000..9cc85b1d6d --- /dev/null +++ b/Submission_files/Default(13).css @@ -0,0 +1 @@ +/* Placeholder file required by the component structure */ \ No newline at end of file diff --git a/Submission_files/Default(13).js.download b/Submission_files/Default(13).js.download new file mode 100644 index 0000000000..72d6b2e036 --- /dev/null +++ b/Submission_files/Default(13).js.download @@ -0,0 +1,5 @@ +$(function () { + // SummaryWidget initialization + // Contact modal and widget management moved to ApplicationContactsWidget component +}); + diff --git a/Submission_files/Default(14).css b/Submission_files/Default(14).css new file mode 100644 index 0000000000..17cc777f35 --- /dev/null +++ b/Submission_files/Default(14).css @@ -0,0 +1,152 @@ +.scores-block label, +input { + display: block; +} + +.scores-block { + display: flex; + flex-wrap: wrap; + align-content: center; + justify-content: flex-start; + align-items: center; + gap: 5px; +} + +.scores-block-save { + flex-basis: 100%; + display: flex; + justify-content: flex-end; + margin: 5px 0px 5px 0px; +} + +.scores-block-wrapper { + display: inline-block; +} + +.assessment-scores-container .form-label { + font-size: var(--bc-font-size-sm); + color: var(--bc-colors-grey-text-300); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 0; +} +.assessment-sum { + margin-top: 2px; +} + +#assessment-scoresheet #section-button::after { + -webkit-filter: grayscale(1) invert(0); + filter: grayscale(1) invert(0); +} + +#assessment-scoresheet #section-button:not(.collapsed)::after { + -webkit-filter: grayscale(1); + filter: grayscale(1); +} + +#assessment-scoresheet .preview-btn:not(.collapsed) { + background-color: #3470b1; + color: #ffffff; +} + +.scoresheet-top-btn-group { + margin-top: 0; +} + +/* AI-generated answer styling (blue text) */ +.ai-generated-answer { + color: #0066cc !important; + background-color: rgba(0, 102, 204, 0.05); + border: 1px solid rgba(0, 102, 204, 0.2); +} + +.ai-generated-answer::placeholder { + color: #0066cc; + opacity: 0.7; +} + +/* Human-confirmed answer styling (black text) */ +.human-confirmed-answer { + color: #000000 !important; + background-color: #ffffff; + border: 1px solid #ced4da; +} + +/* AI indicator label */ +.ai-answer-indicator { + font-size: 0.75rem; + color: #0066cc; + font-style: italic; + margin-top: 2px; + display: flex; + align-items: center; + gap: 4px; +} + +.ai-confidence-score { + font-weight: bold; + padding: 2px 6px; + border-radius: 3px; + background-color: rgba(0, 102, 204, 0.1); + font-size: 0.7rem; +} + +/* AI citation styling */ +.ai-citation { + margin-top: 4px; + padding: 6px 8px; + background-color: rgba(0, 102, 204, 0.08); + border-left: 3px solid #0066cc; + border-radius: 0 4px 4px 0; + font-size: 0.8rem; + color: #004080; + line-height: 1.3; +} + +/* Low confidence answer styling */ +.low-confidence-answer { + border: 2px solid #f3c736 !important; + background-color: #fff3e0 !important; +} + +.low-confidence-indicator { + display: inline-block; + margin-left: 8px; + color: #f3c736; + font-size: 0.875rem; + font-weight: 600; +} + +.low-confidence-indicator i { + margin-right: 4px; +} + +/* Low confidence question styling (for accordion items) */ +.low-confidence-question { + border-left: 4px solid #f3c736 !important; + background-color: #fff8e1; +} + +.low-confidence-question .accordion-button { + background-color: #fff8e1 !important; +} + +.low-confidence-question .accordion-button:not(.collapsed) { + background-color: #ffe0b2 !important; +} + +.low-confidence-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + background-color: #f3c736; + color: white; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; +} + +.low-confidence-badge i { + margin-right: 4px; +} diff --git a/Submission_files/Default(14).js.download b/Submission_files/Default(14).js.download new file mode 100644 index 0000000000..46971d8639 --- /dev/null +++ b/Submission_files/Default(14).js.download @@ -0,0 +1,3 @@ +$(function () { + +}); diff --git a/Submission_files/Default(15).css b/Submission_files/Default(15).css new file mode 100644 index 0000000000..895457a279 --- /dev/null +++ b/Submission_files/Default(15).css @@ -0,0 +1,203 @@ + +.single-comment { + position: relative; + border-radius: 4px; + overflow: hidden; + border-left: 0.50px #D6D6D6 solid; + border-top: 0.50px #D6D6D6 solid; + border-right: 0.50px #D6D6D6 solid; + border-bottom: 1px #D6D6D6 solid; + padding: 10px 5px 5px 5px; + flex: 1; +} + +.single-comment.edit-mode { + width: 100%; +} + +.comment-input { + outline: 0; +} + + .comment-input:hover { + box-shadow: none !important; + } + + .comment-input.selected { + border: 0 !important; + outline: 0 !important; + border-bottom: 0.5px solid #D6D6D6 !important; + border-radius: 0px !important; + } + +.comment-button-container { + display: flex; + align-items: flex-end; + justify-content: right; + gap: 8px; +} + +.add-comment { + display: none; +} + +.edit-button { + cursor: pointer; + text-decoration: none; +} + +.comment-dropdown-toggle { + cursor: pointer; + padding: 0 0.5rem; + margin-top: -5px; + font-size: 1.25rem; + color: #666; + text-decoration: none; + line-height: 1; +} + +.comment-dropdown-toggle:hover, +.comment-dropdown-toggle:focus { + color: #333; + text-decoration: none; +} + +.dropdown-item.pin-button, +.dropdown-item.unpin-button { + padding: 0.5rem 1rem; + margin-left: 0; + color: #212529; +} + +.dropdown-item.pin-button:hover, +.dropdown-item.unpin-button:hover { + background-color: #f8f9fa; + color: #212529; +} + +.dropdown-item i { + font-size: 0.875rem; +} + +.comment-input-multiple:hover { + box-shadow: none !important; + border-bottom: 1.5px solid var(--bc-colors-grey-text-500) !important; +} + +.comment-input-multiple { + border-left: 0.50px #D6D6D6 solid; + border-top: 0.50px #D6D6D6 solid; + border-right: 0.50px #D6D6D6 solid; + border-bottom: 1px #D6D6D6 solid; + padding: 10px 5px 5px 5px; + flex: 1; +} + +.comment-time { + padding-top: 0.1rem; + font-size: 0.7rem; + font-style: normal; + font-weight: 400; + line-height: normal; + word-wrap: break-word; + color: var(--bc-colors-grey-text-300, #666); +} + +.comment-btn { + margin-top: 10px; + padding-left: 14px; + padding-right: 14px; + padding-top: 6px; + padding-bottom: 6px; + background: #E6EFF7; + border-radius: 3px; + cursor: pointer; + transition: box-shadow .3s; +} + + .comment-btn:hover { + box-shadow: -3px 3px 11px -3px rgba(33,33,33,.2); + } + +.comment-lbl { + display: block; + margin-top: 0.25rem; + width: 99%; + max-height: 180px; + overflow-y: scroll; + overflow-x: hidden; + position: relative; + font-size: var(--bc-font-size); +} + +.comment-edit-btn-wrapper { + display: flex; + justify-content: right; + align-items: start; + gap: 8px; +} + +.comment-lbl-wrapper { + color: #666666; + font-size: 0.89rem; + font-weight: 400; + word-wrap: break-word; +} + +.unity-comment-block { + background: var(--bc-surface--color--brand--gold--20); + padding: 0.75rem 0.5rem 0.5rem 1rem; + border-radius: 0.25rem; + font-size: var(--bc-font-size-xs); + color: var(--bc-colors-grey-text-300); + flex: 1; + width: 90%; +} + + .unity-comment-block .commented-time { + font-size: 0.875rem; + } + +.comment-read-mode { + display: flex; +} + + .comment-read-mode > .unity-user-initials { + margin-top: 0.5rem; + padding: 5px; + width: 22px; + height: 22px; + font-size: 0.45rem; + } + +.commenter-name { + font-size: var(--bc-font-size); +} + +.comment-with-mention { + min-height:120px; +} + +/* Pinned comment styles */ +.pinned-comment { + border-left: 4px solid var(--bs-primary-border-subtle); +} + +.pinned-comment.unity-comment-block { + background-color: var(--bs-primary-bg-subtle); + color: var(--bs-primary-text-emphasis); + border-radius: 0; +} + +.pinned-icon { + color: var(--bs-info-text-emphasis); + margin-right: 0.5rem; + font-size: 1rem; + vertical-align: middle; +} + +.pinned-time { + font-size: 0.75rem; + color: #92400e; + font-style: italic; +} diff --git a/Submission_files/Default(15).js.download b/Submission_files/Default(15).js.download new file mode 100644 index 0000000000..23f509ab45 --- /dev/null +++ b/Submission_files/Default(15).js.download @@ -0,0 +1,625 @@ +function saveScoresSection(formId, sectionId) { + const assessmentId = $('#AssessmentId').val(); + const secSaveButton = document.getElementById( + 'scoresheet-section-save-' + sectionId + ); + const secDiscardButton = document.getElementById( + 'scoresheet-section-discard-' + sectionId + ); + + const assessmentAnswersArr = []; + const inputFieldArr = []; + const origAnswersArr = []; + const formData = $(`#${formId}`).serializeArray(); + + //Handle form object data + $.each(formData, function (_, inputData) { + buildFormData( + assessmentAnswersArr, + inputData, + inputFieldArr, + origAnswersArr + ); + }); + + const data = { + AssessmentId: assessmentId, + AssessmentAnswers: assessmentAnswersArr.map( + ({ questionId, questionType, answer }) => ({ + questionId, + questionType, + answer, + }) + ), + }; + + //Calls an enpoint and disabled buttons + secSaveButton.disabled = true; + secDiscardButton.disabled = true; + unity.grantManager.assessments.assessment + .saveScoresheetSectionAnswers(data) + .done(function () { + abp.notify.success( + 'The answers have been saved successfully.', + 'Save Answers' + ); + + if (inputFieldArr.length > 0) { + for (let item of inputFieldArr) { + const inputField = document.getElementById(item); + inputField.setAttribute( + 'data-original-value', + inputField.value + ); + } + } + + updateSubtotal(); + PubSub.publish( + 'refresh_review_list_without_sidepanel', + assessmentId + ); + }) + .fail(function () { + secSaveButton.disabled = false; + secDiscardButton.disabled = false; + }); +} + +function markAsHumanConfirmed(inputElement) { + console.log('markAsHumanConfirmed inputElement', inputElement); + // Check if this was an AI-generated answer + const isHumanConfirmed = + inputElement.getAttribute('data-is-human-confirmed') === 'true'; + + if (!isHumanConfirmed) { + // Mark as human confirmed + inputElement.setAttribute('data-is-human-confirmed', 'true'); + + // Update styling from AI-generated to human-confirmed + inputElement.classList.remove('ai-generated-answer'); + inputElement.classList.add('human-confirmed-answer'); + + // Remove AI indicator if it exists + const aiIndicator = inputElement.parentElement.querySelector( + '.ai-answer-indicator' + ); + + if (aiIndicator) { + aiIndicator.remove(); + } + + // Remove low-confidence-badge from the question header (accordion button) + const questionAccordion = inputElement.closest('.accordion-item'); + if (questionAccordion) { + const lowConfidenceBadge = questionAccordion.querySelector( + '.low-confidence-badge' + ); + if (lowConfidenceBadge) { + lowConfidenceBadge.remove(); + } + + // Also remove the low-confidence-question class from the accordion item + questionAccordion.classList.remove('low-confidence-question'); + } + + // Log the change for potential tracking + console.log( + 'Answer marked as human-confirmed for element:', + inputElement.id + ); + } +} + +// Utility function to help debug AI answer integration +function debugAIAnswers() { + const aiAnswers = document.querySelectorAll( + '[data-is-human-confirmed="false"]' + ); + const humanAnswers = document.querySelectorAll( + '[data-is-human-confirmed="true"]' + ); + + console.log('=== AI Answer Integration Debug ==='); + console.log(`Found ${aiAnswers.length} AI-generated answers`); + console.log(`Found ${humanAnswers.length} human-confirmed answers`); + + // Focus on select lists specifically + const aiSelectLists = Array.from(aiAnswers).filter( + (el) => el.tagName === 'SELECT' + ); + const brokenSelectLists = aiSelectLists.filter( + (el) => el.value === '' || el.value === null + ); + + console.log( + `AI Select Lists: ${aiSelectLists.length} total, ${brokenSelectLists.length} broken` + ); + + brokenSelectLists.forEach((select) => { + console.log('Broken Select List:', { + id: select.id, + value: select.value, + selectedIndex: select.selectedIndex, + optionCount: select.options.length, + options: Array.from(select.options).map((opt) => ({ + value: opt.value, + text: opt.text, + })), + }); + }); + + aiAnswers.forEach((element) => { + console.log('AI Answer:', { + id: element.id, + tagName: element.tagName, + value: element.value, + hasAiClass: element.classList.contains('ai-generated-answer'), + hasIndicator: !!element.parentElement.querySelector( + '.ai-answer-indicator' + ), + }); + }); + + return { + aiCount: aiAnswers.length, + humanCount: humanAnswers.length, + brokenSelectCount: brokenSelectLists.length, + aiAnswers: Array.from(aiAnswers).map((el) => ({ + id: el.id, + tagName: el.tagName, + value: el.value, + })), + humanAnswers: Array.from(humanAnswers).map((el) => ({ + id: el.id, + tagName: el.tagName, + value: el.value, + })), + }; +} +function discardChangesScoresSection(formId, sectionId) { + const secSaveButton = document.getElementById( + 'scoresheet-section-save-' + sectionId + ); + const secDiscardButton = document.getElementById( + 'scoresheet-section-discard-' + sectionId + ); + + const assessmentAnswersArr = []; + const inputFieldArr = []; + const origAnswersArr = []; + const formData = $(`#${formId}`).serializeArray(); + + $.each(formData, function (_, inputData) { + buildFormData( + assessmentAnswersArr, + inputData, + inputFieldArr, + origAnswersArr + ); + }); + + //Handle dynamic data to bring back original values + if (inputFieldArr.length > 0) { + for (let item of inputFieldArr) { + let questionId = item.split('-').slice(2).join('-'); + const inputField = document.getElementById(item); + const originalValue = inputField.getAttribute( + 'data-original-value' + ); + inputField.value = originalValue; + + if ( + item.includes('answer-number-') || + item.includes('answer-text-') + ) { + const errorMessage = document.getElementById( + 'error-message-' + questionId + ); + errorMessage.textContent = ''; + } + } + } + + secSaveButton.disabled = true; + secDiscardButton.disabled = true; +} + +function buildFormData( + assessmentAnswersArr, + inputData, + inputFieldArr, + origAnswersArr +) { + const questionTypes = { + Number: 1, + Text: 2, + YesNo: 6, + SelectList: 12, + Textarea: 14, + }; + const n = 2; + const formAnsObj = {}; + const origAnsObj = {}; + const inputName = inputData.name.split('-'); + + if (formAnsObj[inputData.name.split('-')[0]] == '') { + formAnsObj['answer'] = null; + } + + if (inputName[0] === 'Answer') { + let answerValue = inputData.value; + let inputFieldValue = inputName.slice(0, n).join('-'); + let questionIdValue = inputName.slice(n).join('-'); + const questionTypeValue = + questionTypes[inputName.slice(1, n).join('-')]; + + if (questionTypeValue === 1 && !answerValue) { + answerValue = 0; + } + + let tempInputField = `${inputFieldValue.toLowerCase()}-${questionIdValue}`; + + origAnsObj['questionId'] = inputName.slice(n).join('-'); + origAnsObj['questionType'] = questionTypeValue; + origAnsObj['answer'] = $(`#${tempInputField}`).attr( + 'data-original-value' + ); + origAnsObj['isValid'] = true; + origAnsObj['isSame'] = true; + + formAnsObj['questionId'] = inputName.slice(n).join('-'); + formAnsObj['questionType'] = questionTypeValue; + formAnsObj['answer'] = answerValue; + formAnsObj['isValid'] = true; + formAnsObj['isSame'] = true; + + inputFieldArr.push(tempInputField); + origAnswersArr.push(origAnsObj); + assessmentAnswersArr.push(formAnsObj); + } +} + +function saveAssessmentScores() { + try { + let data = { + financialAnalysis: parseScoreValueInput('financialAnalysis'), + economicImpact: parseScoreValueInput('economicImpact'), + inclusiveGrowth: parseScoreValueInput('inclusiveGrowth'), + cleanGrowth: parseScoreValueInput('cleanGrowth'), + assessmentId: $('#AssessmentId').val(), + }; + unity.grantManager.assessments.assessment + .updateAssessmentScore(data) + .done(function () { + abp.notify.success('Assessment scores has been updated.'); + PubSub.publish('refresh_assessment_scores', null); + PubSub.publish( + 'refresh_review_list_without_sidepanel', + $('#AssessmentId').val() + ); + }); + } catch (error) { + console.log(error); + } +} + +function parseScoreValueInput(name) { + let control = '#' + name; + return $(control).val() == '' + ? 0 + : Math.min($(control).attr('max'), $(control).val()); +} + +function enableSaveButton(inputText) { + if (inputText.value.trim() != '') { + $('#saveAssessmentScoresBtn').prop('disabled', false); + } else { + $('#saveAssessmentScoresBtn').prop('disabled', true); + } + updateSum(); +} + +function updateSum() { + let financialAnalysis = $('#financialAnalysis').val() || 0; + let inclusiveGrowth = $('#inclusiveGrowth').val() || 0; + let cleanGrowth = $('#cleanGrowth').val() || 0; + let economicImpact = $('#economicImpact').val() || 0; + let sum = + parseInt(financialAnalysis) + + parseInt(inclusiveGrowth) + + parseInt(cleanGrowth) + + parseInt(economicImpact); + $('#subTotal').val(sum); +} + +function positiveIntegersOnly(e) { + if ( + e.keyCode === 9 || + e.keyCode === 8 || + e.keyCode === 37 || + e.keyCode === 39 + ) { + return true; + } + if (e.target?.value?.length >= 2) { + return false; + } + if ( + !( + (e.keyCode > 95 && e.keyCode < 106) || + (e.keyCode > 47 && e.keyCode < 58) || + e.keyCode == 8 + ) + ) { + return false; + } +} + +function compareObj(objA, objB) { + let res = true; + Object.keys(objB).forEach((key) => { + if (!objA.hasOwnProperty(key) || objA[key] !== objB[key]) { + res = false; + } + }); + return res; +} + +function handleInputChange(questionId, inputFieldPrefix) { + const sectionFormId = $(`#${inputFieldPrefix + questionId}`) + .closest('form') + .attr('id'); + let sectionId = + sectionFormId !== null + ? sectionFormId?.split('-').slice(2).join('-') + : null; + const secSaveButton = document.getElementById( + 'scoresheet-section-save-' + sectionId + ); + const secDiscardButton = document.getElementById( + 'scoresheet-section-discard-' + sectionId + ); + + const assessmentAnswersArr = []; + const inputFieldArr = []; + const origAnswersArr = []; + const formData = $(`#${sectionFormId}`).serializeArray(); + + $.each(formData, function (_, inputData) { + buildFormData( + assessmentAnswersArr, + inputData, + inputFieldArr, + origAnswersArr + ); + }); + + //Handle values and objects comparison + for (let x = 0; x < assessmentAnswersArr.length; x++) { + if (assessmentAnswersArr[x].questionType === 1) { + let inputNumberField = document.getElementById( + 'answer-number-' + assessmentAnswersArr[x].questionId + ); + let numberErrorMessage = document.getElementById( + 'error-message-' + assessmentAnswersArr[x].questionId + ); + assessmentAnswersArr[x].isValid = validateNumericField( + inputNumberField, + numberErrorMessage + ); + } else if (assessmentAnswersArr[x].questionType === 2) { + let inputTextField = document.getElementById( + 'answer-text-' + assessmentAnswersArr[x].questionId + ); + let textErrorMessage = document.getElementById( + 'error-message-' + assessmentAnswersArr[x].questionId + ); + + if (inputTextField.required) { + assessmentAnswersArr[x].isValid = validateTextField( + inputTextField, + textErrorMessage + ); + } + } + assessmentAnswersArr[x].isSame = compareObj( + assessmentAnswersArr[x], + origAnswersArr[x] + ); + } + + //Handle button events + let isNotSame = assessmentAnswersArr.some((item) => item.isSame === false); + let isInValid = assessmentAnswersArr.some((item) => item.isValid === false); + + if (isNotSame && isInValid) { + secSaveButton.disabled = true; + secDiscardButton.disabled = false; + } + + if (isNotSame && !isInValid) { + secSaveButton.disabled = false; + secDiscardButton.disabled = false; + } else { + secSaveButton.disabled = true; + } +} + +function validateTextField(textInputField, errorMessage) { + if ( + textInputField.validity.tooShort || + textInputField.validity.valueMissing + ) { + errorMessage.textContent = + 'The answer is too short. Minimum length is ' + + textInputField.minLength + + ' characters.'; + return false; + } else if (textInputField.validity.tooLong) { + errorMessage.textContent = + 'The answer is too long. Maximum length is ' + + textInputField.maxLength + + ' characters.'; + return false; + } else { + errorMessage.textContent = ''; + return true; + } +} + +function validateNumericField(numericInputField, errorMessage) { + if (numericInputField.validity.rangeOverflow) { + errorMessage.textContent = `Value must be less than or equal to ${numericInputField.max}.`; + return false; + } else if (numericInputField.validity.rangeUnderflow) { + errorMessage.textContent = `Value must be greater than or equal to ${numericInputField.min}.`; + return false; + } else { + errorMessage.textContent = ''; + return true; + } +} + +function updateSubtotal() { + setTimeout(function () { + let subtotal = 0; + + // Handle number inputs + const numberInputs = document.querySelectorAll('.answer-number-input'); + numberInputs.forEach((input) => { + subtotal += parseFloat(input.value) || 0; + }); + + // Handle Yes/No inputs + const yesNoInputs = document.querySelectorAll('.answer-yesno-input'); + yesNoInputs.forEach((input) => { + let value = 0; + if (input.value === 'Yes') { + value = + parseFloat(input.getAttribute('data-yes-numeric-value')) || + 0; + } else if (input.value === 'No') { + value = + parseFloat(input.getAttribute('data-no-numeric-value')) || + 0; + } + subtotal += value; + }); + + // Handle select list inputs + const selectListInputs = document.querySelectorAll( + '.answer-selectlist-input' + ); + selectListInputs.forEach((select) => { + const selectedOption = select.options[select.selectedIndex]; + const numericValue = + parseFloat(selectedOption.getAttribute('data-numeric-value')) || + 0; + subtotal += numericValue; + }); + + // Update the subtotal field + const subTotalField = document.getElementById('scoresheetSubtotal'); + if (subTotalField) { + subTotalField.value = subtotal; + } + }, 500); +} + +function discardChanges( + questionId, + inputFieldPrefix, + saveButtonPrefix, + discardButtonPrefix +) { + const inputField = document.getElementById(inputFieldPrefix + questionId); + const saveButton = document.getElementById(saveButtonPrefix + questionId); + const discardButton = document.getElementById( + discardButtonPrefix + questionId + ); + + const originalValue = inputField.getAttribute('data-original-value'); + inputField.value = originalValue; + + saveButton.disabled = true; + discardButton.disabled = true; + + if ( + inputFieldPrefix == 'answer-number-' || + inputFieldPrefix == 'answer-text-' + ) { + const errorMessage = document.getElementById( + 'error-message-' + questionId + ); + errorMessage.textContent = ''; + } +} + +function expandAllAccordions(divId) { + const accordions = document.querySelectorAll( + '#' + divId + ' .accordion-collapse' + ); + accordions.forEach((accordion) => { + accordion.classList.add('show'); + accordion.previousElementSibling + .querySelector('.accordion-button') + .classList.remove('collapsed'); + }); +} + +function collapseAllAccordions(divId) { + const accordions = document.querySelectorAll( + '#' + divId + ' .accordion-collapse' + ); + accordions.forEach((accordion) => { + accordion.classList.remove('show'); + accordion.previousElementSibling + .querySelector('.accordion-button') + .classList.add('collapsed'); + }); +} + +function queueApplicationScoring(triggerButton = null) { + const applicationId = $('#DetailsViewApplicationId').val(); + const $button = triggerButton ? $(triggerButton) : $('#regenerateAiScoresheetBtn'); + const existingHtml = $button.html(); + + if (!applicationId || $button.prop('disabled')) { + return; + } + + globalThis.AIGenerationButtonState?.setGenerating($button); + + const monitorScoring = () => globalThis.AIGenerationButtonState.monitor({ + $button, + originalHtml: existingHtml, + getStatus: () => unity.grantManager.grantApplications.grantApplication + .getAIGenerationStatus(applicationId, 'application-scoring'), + onComplete: () => PubSub.publish('refresh_assessment_scores', null), + onFailed: (request) => abp.message.error(request?.failureReason || 'AI scoring failed.') + }); + + unity.grantManager.grantApplications.grantApplication + .queueApplicationScoring(applicationId) + .done(function (request) { + const status = globalThis.AIGenerationButtonState?.resolveStatus(request?.status) ?? ''; + + if (status === 'Completed') { + globalThis.AIGenerationButtonState?.restore($button); + $button.html(existingHtml).prop('disabled', false); + PubSub.publish('refresh_assessment_scores', null); + globalThis.refreshAIRateLimitState?.(); + return; + } + + monitorScoring(); + }) + .fail(function () { + abp.message.error( + 'Failed to queue AI scoring. Please try again.' + ); + globalThis.AIGenerationButtonState?.restore($button); + $button.html(existingHtml).prop('disabled', false); + }); +} diff --git a/Submission_files/Default(16).css b/Submission_files/Default(16).css new file mode 100644 index 0000000000..8d852c7702 --- /dev/null +++ b/Submission_files/Default(16).css @@ -0,0 +1,270 @@ +#applicationEmailsWidget .single-email { + position: relative; + border-radius: 4px; + overflow: hidden; + border-left: 0.50px #D6D6D6 solid; + border-top: 0.50px #D6D6D6 solid; + border-right: 0.50px #D6D6D6 solid; + border-bottom: 1px #D6D6D6 solid; + padding: 10px 5px 5px 5px; + flex: 1; +} + +#applicationEmailsWidget .single-email.edit-mode { + width: 100%; +} + +#applicationEmailsWidget .email-input { + outline: 0; + margin-right: 8px; + margin-left: 8px; + margin-top: 2px; + margin-bottom: 2px; +} + + +#applicationEmailsWidget .email-form label { + color: var(--bc-colors-grey-text-300); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-left: 8px; + margin-bottom: 0; +} + +#applicationEmailsWidget .email-input:hover { + box-shadow: none !important; +} + +#applicationEmailsWidget .email-input.selected { + border: 0 !important; + outline: 0 !important; + border-bottom: 0.5px solid #D6D6D6 !important; + border-radius: 0px !important; +} + +#applicationEmailsWidget .email-button-container { + display: flex; + align-items: flex-end; + justify-content: right; + gap: 8px; +} + +#applicationEmailsWidget .email-input-multiple:hover { + box-shadow: none !important; + border-bottom: 1.5px solid var(--bc-colors-grey-text-500) !important; +} + +#applicationEmailsWidget .email-input::placeholder { + color: #b9b9b9 !important; +} + +#applicationEmailsWidget textarea::placeholder { + color: #b9b9b9 !important; +} + + +#applicationEmailsWidget .email-btn { + margin-top: 10px; + padding-left: 14px; + padding-right: 14px; + padding-top: 6px; + padding-bottom: 6px; + background: #E6EFF7; + border-radius: 3px; + cursor: pointer; + transition: box-shadow .3s; +} + +#applicationEmailsWidget .email-btn:hover { + box-shadow: -3px 3px 11px -3px rgba(33, 33, 33, .2); +} + +#applicationEmailsWidget .email-lbl { + display: block; + margin-top: 0.25rem; + width: 99%; + max-height: 180px; + overflow-y: scroll; + overflow-x: hidden; + position: relative; + font-size: var(--bc-font-size); +} + +#applicationEmailsWidget .email-lbl-wrapper { + color: #666666; + font-size: 0.89rem; + font-weight: 400; + word-wrap: break-word; +} + +#applicationEmailsWidget .unity-email-block { + background: var(--bc-surface--color--brand--gold--20); + padding: 0.75rem 0.5rem 0.5rem 1rem; + border-radius: 0.25rem; + font-size: var(--bc-font-size-xs); + color: var(--bc-colors-grey-text-300); + flex: 1; + width: 90%; +} + +#applicationEmailsWidget .field-validation-error { + margin-left: 8px; +} + +#applicationEmailsWidget .confirmation-label { + font-size: 19px; + font-weight: 600; + text-align: center; + align-content: center; + margin: 30px; + display: flex; + max-width: fit-content; + margin-left: auto; + margin-right: auto; + color: inherit; +} + +#confirmation-modal { + z-index: 1; + justify-content: center; + margin: 1em 1.6em .3em; + padding: 0; + overflow: auto; + color: inherit; + font-size: 1.125em; + font-weight: normal; + line-height: normal; + text-align: center; + word-wrap: break-word; + word-break: break-word; +} + +#btn-cancel-email { + border: 0; + border-radius: .25em; + background: initial; + background-color: #6e7881; + color: #fff; + font-size: 1em; + margin: 4px; +} + +#applicationEmailsWidget .btn-send-close { + margin: 4px; +} + +#applicationEmailsWidget #modal-background { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, .8); + opacity: .50; + -webkit-opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity=50); + z-index: 1000; +} + +#applicationEmailsWidget #modal-content { + display: none; +} + +#applicationEmailsWidget #spinner-modal { + display: none; +} + +#applicationEmailsWidget .modal-footer { + justify-content: center; +} + +#applicationEmailsWidget .modal-content { + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + height: fit-content; + left: 50%; + margin: -120px 0 0 -160px; + position: fixed; + top: 50%; + z-index: 1000; + box-sizing: border-box; + grid-template-columns: minmax(0, 100%); + width: 32em; + max-width: 100%; + padding: 1.25em; + border: none; + background: #fff; + color: #545454; + font-family: inherit; + font-size: 1rem; + justify-content: center; +} + + + +#EmailForm { + display: none; +} + +#EmailForm.active { + display: block; +} + +#applicationEmailsWidget .hide { + display: none; +} + +#applicationEmailsWidget .toast-top-center { + top: 220px; + margin: 0 auto; + left: 50%; + margin-left: -450px; +} + + +#applicationEmailsWidget #modal-background.active, +#applicationEmailsWidget #modal-content.active { + display: block; +} + +#applicationEmailsWidget #email-spinner { + width: 40px; + height: 40px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -20px; + margin-left: 40px; + border-radius: 50%; + border: 5px solid #eaf5fe; + border-right-color: #5597d4; + animation: rotateSpinner 800ms linear infinite; +} + +#applicationEmailsWidget .email-spinner-text { + display: flex; + padding-right: 100px; +} + +#applicationEmailsWidget button { + margin: 2px; + border: 1px solid var(--bc-colors-blue-primary); +} + +#applicationEmailsWidget .fl-cancel { + color: var(--bc-colors-blue-primary); +} + +#applicationEmailsWidget .btn-delete-draft { + background-color: white !important; +} + +@keyframes rotateSpinner { + to { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/Submission_files/Default(16).js.download b/Submission_files/Default(16).js.download new file mode 100644 index 0000000000..83a614c099 --- /dev/null +++ b/Submission_files/Default(16).js.download @@ -0,0 +1,244 @@ +// Fetch raw markdown for comment editing +async function fetchRawCommentMarkdown(commentId, ownerId, commentType) { + try { + const result = await unity.grantManager.comments.comment.get(commentId, { + ownerId: ownerId, + commentType: commentType + }); + return result.comment; + } catch (error) { + console.error('Error fetching raw comment:', error); + return null; + } +} + +$(function () { + const assigneeListElement = document.getElementById("assigneeListData"); + const assigneeList = JSON.parse(assigneeListElement.dataset.assignees); + const mentionDataList = assigneeList.map(item => ({ + key: item.FullName, + value: item.FullName, + email: item.Email, + })); + + initTribute(mentionDataList); + + $('body').on('click', '.edit-button', async function (e) { + e.preventDefault(); + let itemId = $(this).data('id'); + let ownerId = $(this).data('ownerid'); + let commentType = $(this).data('type'); + + // Fetch raw markdown from API for editing + const rawMarkdown = await fetchRawCommentMarkdown(itemId, ownerId, commentType); + if (rawMarkdown !== null) { + $(".comment-input-multiple[data-id='" + itemId + "']").val(rawMarkdown); + } + toggleEditMode(itemId); + }); + + $('body').on('focus', '.comment-input', function () { + $('#addCommentContainer' + $(this).data('ownerid')).css('display', 'flex'); + }); + + $('body').on('click', '.edit-comment-cancel-button', function () { + let itemId = $(this).data('id'); + toggleEditMode(itemId); + $(".comment-input-multiple[data-id='" + itemId + "']").val($(".comment-lbl[data-id='" + itemId + "']").text()); + }); + + $('body').on('click', '.edit-comment-save-button', function () { + const isEdit = true; + let itemId = $(this).data('id'); + const tempOwnerId = $(this).data('ownerid'); + const tempType = $(this).data('type'); + let editedValue = $(".comment-input-multiple[data-id='" + itemId + "']").val(); + const mentions = mentionDataList.filter(person => editedValue.includes(`@${person.value}`)); + + if (mentions.length > 0) { + const mentionedNamesEmail = mentions.map(m => m.email); + sendComment(isEdit, tempOwnerId, tempType, editedValue, mentionedNamesEmail, itemId, mentionDataList); + } else { + updateComment(tempOwnerId, itemId, editedValue, tempType, mentionDataList); + } + }); + + $('body').on('click', '.add-comment-save-button', function () { + const isEdit = false; + const tempOwnerId = $(this).data('ownerid'); + const tempType = $(this).data('type'); + const tempComment = $('#addCommentTextArea' + tempOwnerId).val(); + const mentions = mentionDataList.filter(person => tempComment.includes(`${person.value}`)); + + if (mentions.length > 0) { + const mentionedNamesEmail = mentions.map(m => m.email); + sendComment(isEdit, tempOwnerId, tempType, tempComment, mentionedNamesEmail, null, mentionDataList) + } else { + saveComment(tempOwnerId, tempComment, tempType, mentionDataList); + } + }); + + $('body').on('click', '.add-comment-cancel-button', function () { + let text = $('#addCommentTextArea' + $(this).data('ownerid')).val(); + if (text.length === 0) { + $('#addCommentContainer' + $(this).data('ownerid')).css('display', 'none'); + } + $('#addCommentTextArea' + $(this).data('ownerid')).val(''); + }); + + $('body').on('click', '.pin-button', function (e) { + e.preventDefault(); + let itemId = $(this).data('id'); + let ownerId = $(this).data('ownerid'); + let commentType = $(this).data('type'); + + pinComment(itemId, ownerId, commentType); + }); + + $('body').on('click', '.unpin-button', function (e) { + e.preventDefault(); + let itemId = $(this).data('id'); + let ownerId = $(this).data('ownerid'); + let commentType = $(this).data('type'); + + unpinComment(itemId, ownerId, commentType); + }); +}); + + +function toggleEditMode(itemId) { + $(".edit-mode[data-id='" + itemId + "']").toggle(); + let editedValue = $(".comment-input-multiple[data-id='" + itemId + "']").val(); + $(".comment-input-multiple[data-id='" + itemId + "']").val(editedValue.trim()); + $(".read-mode[data-id='" + itemId + "']").toggle(); +} + +function updateComment(ownerId, commentId, comment, commentType, mentionList) { + if (comment.length < 1) return; + try { + unity.grantManager.comments.comment + .update({ ownerId: ownerId, commentId: commentId, comment: comment, commentType: commentType }) + .done(function () { + abp.notify.success( + 'The comment has been updated.' + ); + toggleEditMode(commentId); + $(".comment-lbl[data-id='" + commentId + "']").text(comment); + PubSub.publish(commentType + '_refresh'); + setTimeout(() => { + initTribute(mentionList); + }, 500); + }); + } + catch (error) { + console.log(error); + } +} + +function saveComment(ownerId, comment, commentType, mentionList) { + if (comment.length < 1) return; + try { + unity.grantManager.comments.comment + .create({ ownerId: ownerId, comment: comment, commentType: commentType }) + .then((response) => { + return response; + }) + .done(function () { + abp.notify.success( + 'The comment has been created.' + ); + PubSub.publish(commentType + '_refresh'); + setTimeout(() => { + initTribute(mentionList); + }, 500); + }); + } + catch (error) { + console.log(error); + } +} + +function sendComment(tempIsEdit, tempOwnerId, tempCommentType, tempComment, tempMentionedNamesEmail, tempItemId, mentionList) { + const submissionNo = $(".reference-no").first().text().trim(); + const applicantName = $(".applicant-name").first().text().trim(); + const subject = submissionNo ? `${submissionNo}-${applicantName}` : applicantName; + + const requestData = { + subject: subject, + body: tempComment, + ownerId: tempOwnerId, + commentType: tempCommentType, + mentionNamesEmail: tempMentionedNamesEmail + }; + + return $.ajax({ + url: `/api/app/email-notification/send-comment-notification`, + type: "POST", + contentType: "application/json", + data: JSON.stringify(requestData), + }).then(response => { + if (tempIsEdit) { + updateComment(tempOwnerId, tempItemId, tempComment, tempCommentType, mentionList); + } else { + saveComment(tempOwnerId, tempComment, tempCommentType, mentionList); + } + }).catch(error => { + console.error('There was a problem with the post operation:', error); + }); +} + +function initTribute(mentionData) { + //Tributejs getting textarea dynamic id + const areaWithMentions = document.querySelectorAll('.comment-with-mention'); + + let tribute = new Tribute({ + values: mentionData, + selectTemplate: function (item) { + if (typeof item === 'undefined') return null; + if (this.range.isContentEditable(this.current.element)) { + return (`${item.original.value}`); + } + return `@${item.original.value}`; + }, + requireLeadingSpace: false, + }) + + areaWithMentions.forEach(item => { + tribute.attach(document.getElementById(item.id)); + }); +} +function pinComment(commentId, ownerId, commentType) { + abp.message.confirm( + 'Are you sure you want to pin this comment?', + 'Pin Comment', + function (confirmed) { + if (confirmed) { + unity.grantManager.comments.comment.pin(commentId, { + ownerId: ownerId, + commentType: commentType + }).then(function () { + abp.notify.success('Comment pinned successfully'); + + PubSub.publish(commentType + '_refresh'); + }).catch(function (error) { + abp.notify.error('Failed to pin comment'); + console.error(error); + }); + } + } + ); +} + +function unpinComment(commentId, ownerId, commentType) { + unity.grantManager.comments.comment.unpin(commentId, { + ownerId: ownerId, + commentType: commentType + }).then(function () { + abp.notify.success('Comment unpinned successfully'); + + PubSub.publish(commentType + '_refresh'); + }).catch(function (error) { + abp.notify.error('Failed to unpin comment'); + console.error(error); + }); +} diff --git a/Submission_files/Default(17).css b/Submission_files/Default(17).css new file mode 100644 index 0000000000..f5b40122c8 --- /dev/null +++ b/Submission_files/Default(17).css @@ -0,0 +1,60 @@ +/* Fix for DataTables alignment with scrollX enabled */ +#ApplicationLinksTable_wrapper { + width: 100%; +} + +#ApplicationLinksTable_wrapper .dt-scroll { + overflow: visible; +} + +#ApplicationLinksTable_wrapper .dt-scroll-head .dt-scroll-headInner, +#ApplicationLinksTable_wrapper .dt-scroll-head .dt-scroll-headInner table { + width: 100% !important; +} + +#ApplicationLinksTable_wrapper .dt-scroll-body { + overflow: visible !important; +} + +#ApplicationLinksTable_wrapper .dt-scroll-body table { + width: 100% !important; +} + +/* Ensure table uses full width */ +#ApplicationLinksTable { + width: 100% !important; +} + +/* Column alignment */ +.links-table th, +.links-table td { + text-align: left; + vertical-align: middle; +} + +/* Delete button column */ +.links-table th:last-child, +.links-table td:last-child { + text-align: center; + width: 40px !important; + min-width: 40px !important; + max-width: 40px !important; +} + +/* Delete button styling */ +.links-table .delete-link-btn { + font-size: 1.2rem; + padding: 0.25rem 0.5rem; + text-decoration: none !important; +} + +.links-table .delete-link-btn:hover { + opacity: 0.7; + text-decoration: none !important; +} + +/* Ensure proper text wrapping in category column */ +.links-table td:first-child { + white-space: normal; + word-wrap: break-word; +} diff --git a/Submission_files/Default(17).js.download b/Submission_files/Default(17).js.download new file mode 100644 index 0000000000..7a51887572 --- /dev/null +++ b/Submission_files/Default(17).js.download @@ -0,0 +1,1005 @@ +$(function () { + const emptyGuid = '00000000-0000-0000-0000-000000000000'; + const UIElements = { + applicationId: $('#DetailsViewApplicationId')[0].value, + btnSend: $('#btn-send'), + btnSave: $('#btn-save'), + btnDiscard: $('#btn-send-discard'), + btnConfirmSend: $('#btn-confirm-send'), + btnCancelEmail: $('#btn-cancel-email'), + btnNewEmail: $('#btn-new-email'), + btnSendClose: $('#btn-send-close'), + emailForm: $('#EmailForm'), + inputEmailId: $('#EmailId'), + inputEmailTo: $($('#EmailTo')[0]), + inputEmailToField: $('#EmailTo')[0], + inputEmailCC: $($('#EmailCC')[0]), + inputEmailBCC: $($('#EmailBCC')[0]), + inputEmailFrom: $($('#EmailFrom')[0]), + inputEmailSubject: $($('#EmailSubject')[0]), + inputEmailBody: $($('#EmailBody')[0]), + inputOriginalEmailTo: $($('#OriginalDraftEmailTo')[0]), + inputOriginalEmailCC: $($('#OriginalDraftEmailCC')[0]), + inputOriginalEmailBCC: $($('#OriginalDraftEmailBCC')[0]), + inputOriginalEmailFrom: $($('#OriginalDraftEmailFrom')[0]), + inputOriginalEmailSubject: $($('#OriginalDraftEmailSubject')[0]), + inputOriginalEmailBody: $($('#OriginalDraftEmailBody')[0]), + emailSpinner: $('#spinner-modal'), + confirmationModal: $('#confirmation-modal'), + alertEmailReadonly: $('#email-alert-readonly') + }; + + let defaultValues = { + emailTo: '', + emailFrom: '', + emailCC: '', + emailBCC: '' + }; + let applicationDetails; + let mappingConfig; + let editorInstance; + let isNewEmailDraft = false; + let newDraftId = null; + let emailAttachmentsTable = null; + function bindUIEvents() { + UIElements.btnNewEmail.on('click', handleNewEmail); + UIElements.btnSend.on('click', handleSendEmail); + UIElements.btnSave.on('click', handleSaveEmail); + UIElements.btnDiscard.on('click', handleDiscardEmail); + UIElements.btnConfirmSend.on('click', handleConfirmSendEmail); + UIElements.btnCancelEmail.on('click', handleCancelEmailSend); + UIElements.btnSendClose.on('click', handleCloseEmail); + UIElements.inputEmailSubject.on('change', handleKeyUpTrim); + UIElements.inputEmailFrom.on('change', handleKeyUpTrim); + UIElements.inputEmailCC.on('change', handleKeyUpTrim); + UIElements.inputEmailBCC.on('change', handleKeyUpTrim); + UIElements.inputEmailBody.on('change', handleKeyUpTrim); + UIElements.inputEmailTo.on('change', validateEmailTo); + UIElements.inputEmailCC.on('change', validateEmailCC); + UIElements.inputEmailBCC.on('change', validateEmailBCC); + + UIElements.inputEmailTo.on('input', handleDraftChange); + UIElements.inputEmailCC.on('input', handleDraftChange); + UIElements.inputEmailBCC.on('input', handleDraftChange); + UIElements.inputEmailFrom.on('input', handleDraftChange); + UIElements.inputEmailSubject.on('input', handleDraftChange); + UIElements.inputEmailBody.on('input', handleDraftChange); + + $('.details-scrollable').on('scroll.emailWidget', function () { + $('.tox-toolbar__overflow').hide(); + }); + } + + init(); + + function init() { + bindUIEvents(); + defaultValues.emailTo = UIElements.inputOriginalEmailTo.val(); + defaultValues.emailFrom = UIElements.inputOriginalEmailFrom.val(); + defaultValues.emailCC = UIElements.inputOriginalEmailCC.val() || ''; + defaultValues.emailBCC = UIElements.inputOriginalEmailBCC.val() || ''; + if (window.toastr) { toastr.options.positionClass = 'toast-top-center'; } + initTemplateDetails(); + $('#templateTextContainer').hide(); + UIElements.btnSave.hide(); + UIElements.btnSend.hide(); + UIElements.btnDiscard.hide(); + UIElements.btnSendClose.hide(); + } + + async function initTemplateDetails() { + applicationDetails = await loadApplicationDetails(); + mappingConfig = await getTemplateVariables(); + } + + function disableEmail() { + UIElements.btnSend.attr('disabled', true); + UIElements.btnSave.attr('disabled', true); + UIElements.btnDiscard.attr('disabled', true); + UIElements.inputEmailTo.attr('disabled', true); + UIElements.inputEmailCC.attr('disabled', true); + UIElements.inputEmailBCC.attr('disabled', true); + UIElements.inputEmailFrom.attr('disabled', true); + UIElements.inputEmailSubject.attr('disabled', true); + UIElements.inputEmailBody.attr('disabled', true); + } + + function enableEmail() { + UIElements.btnSend.attr('disabled', false); + UIElements.btnSave.attr('disabled', false); + UIElements.btnDiscard.attr('disabled', false); + UIElements.inputEmailTo.attr('disabled', false); + UIElements.inputEmailCC.attr('disabled', false); + UIElements.inputEmailBCC.attr('disabled', false); + UIElements.inputEmailFrom.attr('disabled', false); + UIElements.inputEmailSubject.attr('disabled', false); + UIElements.inputEmailBody.attr('disabled', false); + } + + function handleKeyUpTrim(e) { + let trimmedString = e.currentTarget.value.trim(); + e.currentTarget.value = trimmedString; + } + + function closeEmailFormUI() { + $('#modal-content, #modal-background').removeClass('active'); + UIElements.emailForm.removeClass('active'); + UIElements.btnNewEmail.removeClass('hide'); + UIElements.alertEmailReadonly.removeClass('hide'); + UIElements.emailForm.trigger("reset"); + $('#email-attachments-section').hide(); + enableEmail(); + UIElements.btnSave.hide(); + UIElements.btnSend.hide(); + UIElements.btnDiscard.hide(); + UIElements.btnSendClose.hide(); + } + + function handleCloseEmail() { + if (isNewEmailDraft && newDraftId) { + $.ajax({ url: `/api/app/email-notification/${newDraftId}/email`, type: 'DELETE' }) + .catch(e => console.warn('Failed to delete draft on close:', e)); + isNewEmailDraft = false; + newDraftId = null; + } + closeEmailFormUI(); + } + + function handleDiscardEmail() { + UIElements.inputEmailTo.val(UIElements.inputOriginalEmailTo.val()); + UIElements.inputEmailCC.val(UIElements.inputOriginalEmailCC.val()); + UIElements.inputEmailBCC.val(UIElements.inputOriginalEmailBCC.val()); + UIElements.inputEmailFrom.val(UIElements.inputOriginalEmailFrom.val()); + UIElements.inputEmailSubject.val(UIElements.inputOriginalEmailSubject.val()); + UIElements.inputEmailBody.val(UIElements.inputOriginalEmailBody.val()); + } + + function handleCancelEmailSend() { + $('#modal-content, #modal-background').removeClass('active'); + } + + function getToolbarOptions() { + return 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist | link image | code preview'; + } + + function getPlugins() { + return 'lists link image preview code'; + } + function resetEmailBody() { + const id = 'EmailBody'; + + // 1. Remove any existing editor instance + if (tinymce.get(id)) { + tinymce.get(id).remove(); + } + + // 2. Clear the underlying ",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0=0;u--)f=t[u],n.type(f)==="string"&&r.transports[f]||(i.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(i.log("No transports remain within the specified transport array."),t=null)}else if(r.transports[t]||t==="auto"){if(t==="auto"&&r._.ieVersion<=8)return["longPolling"]}else i.log("Invalid transport: "+t.toString()+"."),t=null;return t}function b(n){return n==="http:"?80:n==="https:"?443:void 0}function a(n,t){return t.match(/:\d+$/)?t:t+":"+b(n)}function k(t,i){var u=this,r=[];u.tryBuffer=function(i){return t.state===n.signalR.connectionState.connecting?(r.push(i),!0):!1};u.drain=function(){if(t.state===n.signalR.connectionState.connected)while(r.length>0)i(r.shift())};u.clear=function(){r=[]}}var f={nojQuery:"jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.",noTransportOnInit:"No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.",errorOnNegotiate:"Error during negotiation request.",stoppedWhileLoading:"The connection was stopped during page load.",stoppedWhileNegotiating:"The connection was stopped during the negotiate request.",errorParsingNegotiateResponse:"Error parsing negotiate response.",errorRedirectionExceedsLimit:"Negotiate redirection limit exceeded.",errorDuringStartRequest:"Error during start request. Stopping the connection.",errorFromServer:"Error message received from the server: '{0}'.",stoppedDuringStartRequest:"The connection was stopped during the start request.",errorParsingStartResponse:"Error parsing start response: '{0}'. Stopping the connection.",invalidStartResponse:"Invalid start response: '{0}'. Stopping the connection.",protocolIncompatible:"You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.",aspnetCoreSignalrServer:"Detected a connection attempt to an ASP.NET Core SignalR Server. This client only supports connecting to an ASP.NET SignalR Server. See https://aka.ms/signalr-core-differences for details.",sendFailed:"Send failed.",parseFailed:"Failed at parsing response: {0}",longPollFailed:"Long polling request failed.",eventSourceFailedToConnect:"EventSource failed to connect.",eventSourceError:"Error raised by EventSource",webSocketClosed:"WebSocket closed.",pingServerFailedInvalidResponse:"Invalid ping response when pinging server: '{0}'.",pingServerFailed:"Failed to ping server.",pingServerFailedStatusCode:"Failed to ping server. Server responded with status code {0}, stopping the connection.",pingServerFailedParse:"Failed to parse ping server response, stopping the connection.",noConnectionTransport:"Connection is in an invalid state, there is no transport active.",webSocketsInvalidState:"The Web Socket transport is in an invalid state, transitioning into reconnecting.",reconnectTimeout:"Couldn't reconnect within the configured timeout of {0} ms, disconnecting.",reconnectWindowTimeout:"The client has been inactive since {0} and it has exceeded the inactivity timeout of {1} ms. Stopping the connection.",jsonpNotSupportedWithAccessToken:"The JSONP protocol does not support connections that require a Bearer token to connect, such as the Azure SignalR Service."};if(typeof n!="function")throw new Error(f.nojQuery);var r,h,o=t.document.readyState==="complete",e=n(t),c="__Negotiate Aborted__",u={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},v=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(t,i,r){return i===t.state?(t.state=r,n(t).triggerHandler(u.onStateChanged,[{oldState:i,newState:r}]),!0):!1},y=function(n){return n.state===r.connectionState.disconnected},l=function(n){return n._.keepAliveData.activated&&n.transport.supportsKeepAlive(n)},p=function(i){var f,e;i._.configuredStopReconnectingTimeout||(e=function(t){var i=r._.format(r.resources.reconnectTimeout,t.disconnectTimeout);t.log(i);n(t).triggerHandler(u.onError,[r._.error(i,"TimeoutException")]);t.stop(!1,!1)},i.reconnecting(function(){var n=this;n.state===r.connectionState.reconnecting&&(f=t.setTimeout(function(){e(n)},n.disconnectTimeout))}),i.stateChanged(function(n){n.oldState===r.connectionState.reconnecting&&t.clearTimeout(f)}),i._.configuredStopReconnectingTimeout=!0)};if(r=function(n,t,i){return new r.fn.init(n,t,i)},r._={defaultContentType:"application/x-www-form-urlencoded; charset=UTF-8",ieVersion:function(){var i,n;return t.navigator.appName==="Microsoft Internet Explorer"&&(n=/MSIE ([0-9]+\.[0-9]+)/.exec(t.navigator.userAgent),n&&(i=t.parseFloat(n[1]))),i}(),error:function(n,t,i){var r=new Error(n);return r.source=t,typeof i!="undefined"&&(r.context=i),r},transportError:function(n,t,r,u){var f=this.error(n,r,u);return f.transport=t?t.name:i,f},format:function(){for(var t=arguments[0],n=0;n<\/script>.");}},typeof e.on=="function")e.on("load",function(){o=!0});else e.load(function(){o=!0});r.fn=r.prototype={init:function(t,i,r){var f=n(this);this.url=t;this.qs=i;this.lastError=null;this._={keepAliveData:{},connectingMessageBuffer:new k(this,function(n){f.triggerHandler(u.onReceived,[n])}),lastMessageAt:(new Date).getTime(),lastActiveAt:(new Date).getTime(),beatInterval:5e3,beatHandle:null,totalTransportConnectTimeout:0,redirectQs:null};typeof r=="boolean"&&(this.logging=r)},_parseResponse:function(n){var t=this;return n?typeof n=="string"?t.json.parse(n):n:n},_originalJson:t.JSON,json:t.JSON,isCrossDomain:function(i,r){var u;return(i=n.trim(i),r=r||t.location,i.indexOf("http")!==0)?!1:(u=t.document.createElement("a"),u.href=i,u.protocol+a(u.protocol,u.host)!==r.protocol+a(r.protocol,r.host))},ajaxDataType:"text",contentType:"application/json; charset=UTF-8",logging:!1,state:r.connectionState.disconnected,clientProtocol:"2.1",supportedProtocols:["1.5","2.0","2.1"],negotiateRedirectSupportedProtocols:["2.0","2.1"],reconnectDelay:2e3,transportConnectTimeout:0,disconnectTimeout:3e4,reconnectWindow:3e4,keepAliveWarnAt:2/3,start:function(i,h){var a=this,v={pingInterval:3e5,waitForPageLoad:!0,transport:"auto",jsonp:!1},g,y=a._deferral||n.Deferred(),b=t.document.createElement("a"),nt=function(i,u){i.url===u&&i.baseUrl||(i.url=u,b.href=i.url,b.protocol&&b.protocol!==":"?(i.protocol=b.protocol,i.host=b.host):(i.protocol=t.document.location.protocol,i.host=b.host||t.document.location.host),i.baseUrl=i.protocol+"//"+i.host,i.wsProtocol=i.protocol==="https:"?"wss://":"ws://",i.url.indexOf("//")===0&&(i.url=t.location.protocol+i.url,i.log("Protocol relative URL detected, normalizing it to '"+i.url+"'.")),i.isCrossDomain(i.url)&&(i.log("Auto detected cross domain url."),v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]),typeof i.withCredentials=="undefined"&&(i.withCredentials=!0),n.support.cors||(i.ajaxDataType="jsonp",i.log("Using jsonp because this browser doesn't support CORS.")),i.contentType=r._.defaultContentType))},d,k;if(a.lastError=null,a._deferral=y,!a.json)throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.");if(n.type(i)==="function"?h=i:n.type(i)==="object"&&(n.extend(v,i),n.type(v.callback)==="function"&&(h=v.callback)),v.transport=w(v.transport,a),!v.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return(a._.config=v,!o&&v.waitForPageLoad===!0)?(a._.deferredStartHandler=function(){a.start(i,h)},e.bind("load",a._.deferredStartHandler),y.promise()):a.state===r.connectionState.connecting?y.promise():s(a,r.connectionState.disconnected,r.connectionState.connecting)===!1?(y.resolve(a),y.promise()):(p(a),v.transport==="auto"&&v.jsonp===!0&&(v.transport="longPolling"),a.withCredentials=v.withCredentials,a._originalUrl=a.url,a.ajaxDataType=v.jsonp?"jsonp":"text",nt(a,a.url),n(a).bind(u.onStart,function(){n.type(h)==="function"&&h.call(a);y.resolve(a)}),a._.initHandler=r.transports._logic.initHandler(a),g=function(i,o){var c=r._.error(f.noTransportOnInit);if(o=o||0,o>=i.length){o===0?a.log("No transports supported by the server were selected."):o===1?a.log("No fallback transports were selected."):a.log("Fallback transports exhausted.");n(a).triggerHandler(u.onError,[c]);y.reject(c);a.stop();return}if(a.state!==r.connectionState.disconnected){var p=i[o],h=r.transports[p],v=function(){g(i,o+1)};a.transport=h;try{a._.initHandler.start(h,function(){var f=r._.firefoxMajorVersion(t.navigator.userAgent)>=11,i=!0;a.log("The start request succeeded. Transitioning to the connected state.");l(a)&&r.transports._logic.monitorKeepAlive(a);a._.keepAliveData.activated&&r.transports._logic.startHeartbeat(a);r._.configurePingInterval(a);s(a,r.connectionState.connecting,r.connectionState.connected)||a.log("WARNING! The connection was not in the connecting state.");a._.connectingMessageBuffer.drain();n(a).triggerHandler(u.onStart);e.bind("unload",function(){a.log("Window unloading, stopping the connection.");a.stop(i)});f&&e.bind("beforeunload",function(){t.setTimeout(function(){a.stop(i)},0)})},v)}catch(w){a.log(h.name+" transport threw '"+w.message+"' when attempting to start.");v()}}},d=a.url+"/negotiate",k=function(t,i){var e=r._.error(f.errorOnNegotiate,t,i._.negotiateRequest);n(i).triggerHandler(u.onError,e);y.reject(e);i.stop()},n(a).triggerHandler(u.onStarting),d=r.transports._logic.prepareQueryString(a,d),a.log("Negotiating with '"+d+"'."),a._.negotiateRequest=function(){var t,h=0,w=100,i,e,o=[],s=[],l=function(n,t){var u=r.transports._logic.prepareQueryString(n,n.url+"/negotiate"),i;return n.log("Negotiating with '"+u+"'."),i={url:u,error:function(t,i){i!==c?k(t,n):y.reject(r._.error(f.stoppedWhileNegotiating,null,n._.negotiateRequest))},success:t},n.accessToken&&(i.headers={Authorization:"Bearer "+n.accessToken}),r.transports._logic.ajax(n,i)},p=function(c){try{t=a._parseResponse(c)}catch(d){k(r._.error(f.errorParsingNegotiateResponse,d),a);return}if(t.availableTransports){e=r._.error(f.aspnetCoreSignalrServer);n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(!t.ProtocolVersion||a.supportedProtocols.indexOf(t.ProtocolVersion)===-1){e=r._.error(r._.format(f.protocolIncompatible,a.clientProtocol,t.ProtocolVersion));n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(a.negotiateRedirectSupportedProtocols.indexOf(t.ProtocolVersion)!==-1){if(t.Error){e=r._.error(r._.format(f.errorFromServer,t.Error));n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(t.RedirectUrl){if(h===w){k(r._.error(f.errorRedirectionExceedsLimit),a);return}v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]);a.log("Received redirect to: "+t.RedirectUrl);a.accessToken=t.AccessToken;var b=t.RedirectUrl.split("?",2);if(nt(a,b[0]),a._.redirectQs=b.length===2?b[1]:null,a.ajaxDataType==="jsonp"&&a.accessToken){k(r._.error(f.jsonpNotSupportedWithAccessToken),a);return}h++;l(a,p);return}}i=a._.keepAliveData;a.appRelativeUrl=t.Url;a.id=t.ConnectionId;a.token=t.ConnectionToken;a.webSocketServerUrl=t.WebSocketServerUrl;a._.pollTimeout=t.ConnectionTimeout*1e3+1e4;a.disconnectTimeout=t.DisconnectTimeout*1e3;a._.totalTransportConnectTimeout=a.transportConnectTimeout+t.TransportConnectTimeout*1e3;t.KeepAliveTimeout?(i.activated=!0,i.timeout=t.KeepAliveTimeout*1e3,i.timeoutWarning=i.timeout*a.keepAliveWarnAt,a._.beatInterval=(i.timeout-i.timeoutWarning)/3):i.activated=!1;a.reconnectWindow=a.disconnectTimeout+(i.timeout||0);n.each(r.transports,function(n){if(n.indexOf("_")===0||n==="webSockets"&&!t.TryWebSockets)return!0;s.push(n)});n.isArray(v.transport)?n.each(v.transport,function(t,i){n.inArray(i,s)>=0&&o.push(i)}):v.transport==="auto"?o=s:n.inArray(v.transport,s)>=0&&o.push(v.transport);g(o)};return l(a,p)}(),y.promise())},starting:function(t){var i=this;return n(i).bind(u.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===r.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===r.connectionState.connecting)throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.");return t.transport.send(t,n),t},received:function(t){var i=this;return n(i).bind(u.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(u.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(u.onError,function(n,r,u){i.lastError=r;t.call(i,r,u)}),i},disconnected:function(t){var i=this;return n(i).bind(u.onDisconnect,function(){t.call(i)}),i},connectionSlow:function(t){var i=this;return n(i).bind(u.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(u.onReconnecting,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(u.onReconnect,function(){t.call(i)}),i},stop:function(i,h){var a=this,v=a._deferral;if(a._.deferredStartHandler&&e.unbind("load",a._.deferredStartHandler),delete a._.config,delete a._.deferredStartHandler,!o&&(!a._.config||a._.config.waitForPageLoad===!0)){a.log("Stopping connection prior to negotiate.");v&&v.reject(r._.error(f.stoppedWhileLoading));return}if(a.state!==r.connectionState.disconnected)return a.log("Stopping connection."),t.clearTimeout(a._.beatHandle),t.clearInterval(a._.pingIntervalId),a.transport&&(a.transport.stop(a),h!==!1&&a.transport.abort(a,i),l(a)&&r.transports._logic.stopMonitoringKeepAlive(a),a.transport=null),a._.negotiateRequest&&(a._.negotiateRequest.abort(c),delete a._.negotiateRequest),a._.initHandler&&a._.initHandler.stop(),delete a._deferral,delete a.messageId,delete a.groupsToken,delete a.id,delete a._.pingIntervalId,delete a._.lastMessageAt,delete a._.lastActiveAt,a._.connectingMessageBuffer.clear(),n(a).unbind(u.onStart),delete a.accessToken,delete a.protocol,delete a.host,delete a.baseUrl,delete a.wsProtocol,delete a.contentType,a.url=a._originalUrl,a._.redirectQs=null,s(a,a.state,r.connectionState.disconnected),n(a).triggerHandler(u.onDisconnect),a},log:function(n){v(n,this.logging)}};r.fn.init.prototype=r.fn;r.noConflict=function(){return n.connection===r&&(n.connection=h),r};n.connection&&(h=n.connection);n.connection=n.signalR=r})(window.jQuery,window),function(n,t,i){function s(n){n._.keepAliveData.monitoring&&l(n);u.markActive(n)&&(n._.beatHandle=t.setTimeout(function(){s(n)},n._.beatInterval))}function l(t){var i=t._.keepAliveData,u;t.state===r.connectionState.connected&&(u=(new Date).getTime()-t._.lastMessageAt,u>=i.timeout?(t.log("Keep alive timed out. Notifying transport that connection has been lost."),t.transport.lostConnection(t)):u>=i.timeoutWarning?i.userNotified||(t.log("Keep alive has been missed, connection may be dead/slow."),n(t).triggerHandler(f.onConnectionSlow),i.userNotified=!0):i.userNotified=!1)}function e(n,t){var i=n.url+t;return n.transport&&(i+="?transport="+n.transport.name),u.prepareQueryString(n,i)}function h(n){this.connection=n;this.startRequested=!1;this.startCompleted=!1;this.connectionStopped=!1}var r=n.signalR,f=n.signalR.events,c=n.signalR.changeState,o="__Start Aborted__",u;r.transports={};h.prototype={start:function(n,r,u){var f=this,e=f.connection,o=!1;if(f.startRequested||f.connectionStopped){e.log("WARNING! "+n.name+" transport cannot be started. Initialization ongoing or completed.");return}e.log(n.name+" transport starting.");n.start(e,function(){o||f.initReceived(n,r)},function(t){return o||(o=!0,f.transportFailed(n,t,u)),!f.startCompleted||f.connectionStopped});f.transportTimeoutHandle=t.setTimeout(function(){o||(o=!0,e.log(n.name+" transport timed out when trying to connect."),f.transportFailed(n,i,u))},e._.totalTransportConnectTimeout)},stop:function(){this.connectionStopped=!0;t.clearTimeout(this.transportTimeoutHandle);r.transports._logic.tryAbortStartRequest(this.connection)},initReceived:function(n,i){var u=this,f=u.connection;if(u.startRequested){f.log("WARNING! The client received multiple init messages.");return}u.connectionStopped||(u.startRequested=!0,t.clearTimeout(u.transportTimeoutHandle),f.log(n.name+" transport connected. Initiating start request."),r.transports._logic.ajaxStart(f,function(){u.startCompleted=!0;i()}))},transportFailed:function(i,u,e){var o=this.connection,h=o._deferral,s;this.connectionStopped||(t.clearTimeout(this.transportTimeoutHandle),this.startRequested?this.startCompleted||(s=r._.error(r.resources.errorDuringStartRequest,u),o.log(i.name+" transport failed during the start request. Stopping the connection."),n(o).triggerHandler(f.onError,[s]),h&&h.reject(s),o.stop()):(i.stop(o),o.log(i.name+" transport failed to connect. Attempting to fall back."),e()))}};u=r.transports._logic={ajax:function(t,i){return n.ajax(n.extend(!0,{},n.signalR.ajaxDefaults,{type:"GET",data:{},xhrFields:{withCredentials:t.withCredentials},contentType:t.contentType,dataType:t.ajaxDataType},i))},pingServer:function(t){var e,f,i=n.Deferred();return t.transport?(e=t.url+"/ping",e=u.addQs(e,t.qs),f=u.ajax(t,{url:e,headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},success:function(n){var u;try{u=t._parseResponse(n)}catch(e){i.reject(r._.transportError(r.resources.pingServerFailedParse,t.transport,e,f));t.stop();return}u.Response==="pong"?i.resolve():i.reject(r._.transportError(r._.format(r.resources.pingServerFailedInvalidResponse,n),t.transport,null,f))},error:function(n){n.status===401||n.status===403?(i.reject(r._.transportError(r._.format(r.resources.pingServerFailedStatusCode,n.status),t.transport,n,f)),t.stop()):i.reject(r._.transportError(r.resources.pingServerFailed,t.transport,n,f))}})):i.reject(r._.transportError(r.resources.noConnectionTransport,t.transport)),i.promise()},prepareQueryString:function(n,i){var r;return r=u.addQs(i,"clientProtocol="+n.clientProtocol),r=typeof n._.redirectQs=="string"?u.addQs(r,n._.redirectQs):u.addQs(r,n.qs),n.token&&(r+="&connectionToken="+t.encodeURIComponent(n.token)),n.data&&(r+="&connectionData="+t.encodeURIComponent(n.data)),r},addQs:function(t,i){var r=t.indexOf("?")!==-1?"&":"?",u;if(!i)return t;if(typeof i=="object")return t+r+n.param(i);if(typeof i=="string")return u=i.charAt(0),(u==="?"||u==="&")&&(r=""),t+r+i;throw new Error("Query string property must be either a string or object.");},getUrl:function(n,i,r,f,e){var h=i==="webSockets"?"":n.baseUrl,o=h+n.appRelativeUrl,s="transport="+i;return!e&&n.groupsToken&&(s+="&groupsToken="+t.encodeURIComponent(n.groupsToken)),r?(o+=f?"/poll":"/reconnect",!e&&n.messageId&&(s+="&messageId="+t.encodeURIComponent(n.messageId))):o+="/connect",o+="?"+s,o=u.prepareQueryString(n,o),n.transport&&n.accessToken&&(n.transport.name==="serverSentEvents"||n.transport.name==="webSockets")&&(o+="&access_token="+t.encodeURIComponent(n.accessToken)),e||(o+="&tid="+Math.floor(Math.random()*11)),o},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Initialized:typeof n.S!="undefined"?!0:!1,ShouldReconnect:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,GroupsToken:n.G,Error:n.E}},updateGroups:function(n,t){t&&(n.groupsToken=t)},stringifySend:function(n,t){return typeof t=="string"||typeof t=="undefined"||t===null?t:n.json.stringify(t)},ajaxSend:function(t,i){var h=u.stringifySend(t,i),c=e(t,"/send"),o,s=function(t,u){n(u).triggerHandler(f.onError,[r._.transportError(r.resources.sendFailed,u.transport,t,o),i])};return o=u.ajax(t,{url:c,type:t.ajaxDataType==="jsonp"?"GET":"POST",contentType:r._.defaultContentType,headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},data:{data:h},success:function(n){var i;if(n){try{i=t._parseResponse(n)}catch(r){s(r,t);t.stop();return}u.triggerReceived(t,i)}},error:function(n,i){i!=="abort"&&i!=="parsererror"&&s(n,t)}})},ajaxAbort:function(n,i){if(typeof n.transport!="undefined"){i=typeof i=="undefined"?!0:i;var r=e(n,"/abort"),f=n.accessToken?{Authorization:"Bearer "+n.accessToken}:{};t.fetch?t.fetch(r,{method:"POST",keepalive:!0,headers:f,credentials:n.withCredentials===!0?"include":"same-origin"}):u.ajax(n,{url:r,async:i,timeout:1e3,type:"POST",headers:f,dataType:"text"});n.log("Fired ajax abort async = "+i+".")}},ajaxStart:function(t,i){var h=function(n){var i=t._deferral;i&&i.reject(n)},s=function(i){t.log("The start request failed. Stopping the connection.");n(t).triggerHandler(f.onError,[i]);h(i);t.stop()};t._.startRequest=u.ajax(t,{url:e(t,"/start"),headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},success:function(n,u,f){var e;try{e=t._parseResponse(n)}catch(o){s(r._.error(r._.format(r.resources.errorParsingStartResponse,n),o,f));return}e.Response==="started"?i():s(r._.error(r._.format(r.resources.invalidStartResponse,n),null,f))},error:function(n,i,u){i!==o?s(r._.error(r.resources.errorDuringStartRequest,u,n)):(t.log("The start request aborted because connection.stop() was called."),h(r._.error(r.resources.stoppedDuringStartRequest,null,n)))}})},tryAbortStartRequest:function(n){n._.startRequest&&(n._.startRequest.abort(o),delete n._.startRequest)},tryInitialize:function(n,t,i){t.Initialized&&i?i():t.Initialized&&n.log("WARNING! The client received an init message after reconnecting.")},triggerReceived:function(t,i){t._.connectingMessageBuffer.tryBuffer(i)||n(t).triggerHandler(f.onReceived,[i])},processMessages:function(t,i,f){var e;if(i&&typeof i.I!="undefined"){u.triggerReceived(t,i);return}if(u.markLastMessage(t),i){if(e=u.maximizePersistentResponse(i),e.Error){t.log("Received an error message from the server: "+i.E);n(t).triggerHandler(r.events.onError,[r._.error(i.E,"ServerError")]);t.stop(!1,!1);return}u.updateGroups(t,e.GroupsToken);e.MessageId&&(t.messageId=e.MessageId);e.Messages&&(n.each(e.Messages,function(n,i){u.triggerReceived(t,i)}),u.tryInitialize(t,e,f))}},monitorKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring?t.log("Tried to monitor keep alive but it's already being monitored."):(i.monitoring=!0,u.markLastMessage(t),t._.keepAliveData.reconnectKeepAliveUpdate=function(){u.markLastMessage(t)},n(t).bind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+i.timeoutWarning+", keep alive timeout of "+i.timeout+" and disconnecting timeout of "+t.disconnectTimeout))},stopMonitoringKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring&&(i.monitoring=!1,n(t).unbind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t._.keepAliveData={},t.log("Stopping the monitoring of the keep alive."))},startHeartbeat:function(n){n._.lastActiveAt=(new Date).getTime();s(n)},markLastMessage:function(n){n._.lastMessageAt=(new Date).getTime();n._.lastActiveAt=n._.lastMessageAt},markActive:function(n){return u.verifyLastActive(n)?(n._.lastActiveAt=(new Date).getTime(),!0):!1},isConnectedOrReconnecting:function(n){return n.state===r.connectionState.connected||n.state===r.connectionState.reconnecting},ensureReconnectingState:function(t){return c(t,r.connectionState.connected,r.connectionState.reconnecting)===!0&&n(t).triggerHandler(f.onReconnecting),t.state===r.connectionState.reconnecting},clearReconnectTimeout:function(n){n&&n._.reconnectTimeout&&(t.clearTimeout(n._.reconnectTimeout),delete n._.reconnectTimeout)},verifyLastActive:function(t){if(!t._.keepAliveData.activated||(new Date).getTime()-t._.lastActiveAt0&&n--}}}();r.transports.foreverFrame={name:"foreverFrame",supportsKeepAlive:function(){return!0},iframeClearThreshold:50,start:function(n,r,e){if(n.accessToken){e&&(n.log("Forever Frame does not support connections that require a Bearer token to connect, such as the Azure SignalR Service."),e());return}var l=this,s=i.foreverFrame.count+=1,h,o=u(),c=function(){n.log("Forever frame iframe finished loading and is no longer receiving messages.");e&&e()||l.reconnect(n)};if(t.EventSource){e&&(n.log("Forever Frame is not supported by SignalR on browsers with SSE support."),e());return}o.setAttribute("data-signalr-connection-id",n.id);f.prevent();h=i.getUrl(n,this.name);h+="&frameId="+s;t.document.documentElement.appendChild(o);n.log("Binding to iframe's load event.");o.addEventListener?o.addEventListener("load",c,!1):o.attachEvent&&o.attachEvent("onload",c);o.src=h;i.foreverFrame.connections[s]=n;n.frame=o;n.frameId=s;r&&(n.onSuccess=function(){n.log("Iframe transport started.");r()})},reconnect:function(n){var r=this;i.isConnectedOrReconnecting(n)&&i.verifyLastActive(n)&&t.setTimeout(function(){if(i.verifyLastActive(n)&&n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'.");u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,u){var f,e,o;if(t.json!==t._originalJson&&(u=t._originalJson.stringify(u)),o=t._parseResponse(u),i.processMessages(t,o,t.onSuccess),t.state===n.signalR.connectionState.connected&&(t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>r.transports.foreverFrame.iframeClearThreshold&&(t.frameMessageCount=0,f=t.frame.contentWindow||t.frame.contentDocument,f&&f.document&&f.document.body)))for(e=f.document.body;e.firstChild;)e.removeChild(e.firstChild)},stop:function(n){var r=null;if(f.cancel(),n.frame){if(n.frame.stop)n.frame.stop();else try{r=n.frame.contentWindow||n.frame.contentDocument;r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(u){n.log("Error occurred when stopping foreverFrame transport. Message = "+u.message+".")}n.frame.parentNode===t.document.documentElement&&t.document.documentElement.removeChild(n.frame);delete i.foreverFrame.connections[n.frameId];n.frame=null;n.frameId=null;delete n.frame;delete n.frameId;delete n.onSuccess;delete n.frameMessageCount;n.log("Stopping forever frame.")}},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){o(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).triggerHandler(e.onReconnect)}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,e=n.signalR.changeState,f=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:function(){return!1},reconnectDelay:3e3,start:function(o,s,h){var a=this,v=function(){v=n.noop;o.log("LongPolling connected.");s?s():o.log("WARNING! The client received an init message after reconnecting.")},y=function(n){return h(n)?(o.log("LongPolling failed to connect."),!0):!1},c=o._,l=0,p=function(i){t.clearTimeout(c.reconnectTimeoutId);c.reconnectTimeoutId=null;e(i,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(i.log("Raising the reconnect event"),n(i).triggerHandler(u.onReconnect))},w=36e5;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop());o.messageId=null;c.reconnectTimeoutId=null;c.pollTimeoutId=t.setTimeout(function(){(function e(s,h){var g=s.messageId,nt=g===null,k=!nt,tt=!h,d=i.getUrl(s,a.name,k,tt,!0),b={};(s.messageId&&(b.messageId=s.messageId),s.groupsToken&&(b.groupsToken=s.groupsToken),f(s)!==!0)&&(o.log("Opening long polling request to '"+d+"'."),s.pollXhr=i.ajax(o,{xhrFields:{onprogress:function(){i.markLastMessage(o)}},url:d,type:"POST",contentType:r._.defaultContentType,data:b,timeout:o._.pollTimeout,headers:o.accessToken?{Authorization:"Bearer "+o.accessToken}:{},success:function(r){var h,w=0,u,a;o.log("Long poll complete.");l=0;try{h=o._parseResponse(r)}catch(b){i.handleParseFailure(s,r,b,y,s.pollXhr);return}(c.reconnectTimeoutId!==null&&p(s),h&&(u=i.maximizePersistentResponse(h)),i.processMessages(s,h,v),u&&n.type(u.LongPollDelay)==="number"&&(w=u.LongPollDelay),f(s)!==!0)&&(a=u&&u.ShouldReconnect,!a||i.ensureReconnectingState(s))&&(w>0?c.pollTimeoutId=t.setTimeout(function(){e(s,a)},w):e(s,a))},error:function(f,h){var v=r._.transportError(r.resources.longPollFailed,o.transport,f,s.pollXhr);if(t.clearTimeout(c.reconnectTimeoutId),c.reconnectTimeoutId=null,h==="abort"){o.log("Aborted xhr request.");return}if(!y(v)){if(l++,o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+h+". Response = "+f.responseText+"."),n(s).triggerHandler(u.onError,[v])),(o.state===r.connectionState.connected||o.state===r.connectionState.reconnecting)&&!i.verifyLastActive(o))return;if(!i.ensureReconnectingState(s))return;c.pollTimeoutId=t.setTimeout(function(){e(s,!0)},a.reconnectDelay)}}}),k&&h===!0&&(c.reconnectTimeoutId=t.setTimeout(function(){p(s)},Math.min(1e3*(Math.pow(2,l)-1),w))))})(o)},250)},lostConnection:function(n){n.pollXhr&&n.pollXhr.abort("lostConnection")},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){t.clearTimeout(n._.pollTimeoutId);t.clearTimeout(n._.reconnectTimeoutId);delete n._.pollTimeoutId;delete n._.reconnectTimeoutId;n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n){function r(n){return n+s}function c(n,t,i){for(var f=n.length,u=[],r=0;r=0}function i(n,t){return new i.fn.init(n,t)}function t(i,r){var u={qs:null,logging:!1,useDefaultPath:!0};return n.extend(u,r),(!i||u.useDefaultPath)&&(i=(i||"")+"/signalr"),new t.fn.init(i,u)}var o=0,s=".hubProxy",h=n.signalR;i.fn=i.prototype={init:function(n,t){this.state={};this.connection=n;this.hubName=t;this._={callbackMap:{}}},constructor:i,hasSubscriptions:function(){return u(this._.callbackMap)},on:function(t,i,u){var c=this,l=c._.callbackMap,v=!u&&e(i),f,h,s,a;for(u=u||i,u._signalRGuid||(u._signalRGuid=o++),t=t.toLowerCase(),f=l[t],f||(f=[],l[t]=f),s=0;s=0&&(t&&typeof t.then=="function"&&typeof t.catch=="function"?t.then(function(t){f(n,t)}).catch(function(t){s(n,t)}):t&&t.continueWith?t.continueWith(function(t){f(n,t)}):i.invoke("sys.callback",!1,[n,t]))},s=function(n,t){i.invoke("sys.callbackException",!1,[n,t])},e,o,i;typeof Promise=="function"?(o=function(n){n.continueWith=function(t){var i=n.then(t);return o(i),i}},e=function(){var n={id:i.generateId()};return n.promise=new Promise(function(t,i){n.setResult=t;n.setException=i}),o(n.promise),n}):e=function(){var n={id:i.generateId(),callback:null,promise:{continueWith:function(t){if(typeof t=="function")if(n.callback){var i=n.callback;n.callback=function(n){return t(i(n))}}else n.callback=t;return n.promise}},setResult:function(n){this.callback!==null&&this.callback(n)},setException:function(){}};return n};i={extensions:[],inits:[],callbackTable:[],nextId:0,connection:null,isReconnecting:!1,isUnloading:!1,extractName:function(n){var t=n.lastIndexOf("."),i=null,r=null;return t>0&&(i=n.substr(0,t).toLowerCase(),r=n.substr(t+1)),{factoryName:i,methodName:r}},log:function(){typeof console!="undefined"&&(window.console.debug?window.console.debug.apply(null,arguments):window.console.log&&window.console.log.apply(null,arguments))},invoke:function(n,i,r){var u={},h,f,c,o,l,s,a;u.name=n;u.args=r;u.callbackId=-1;i&&(f=e(),c=f.promise,this.callbackTable[f.id]=f,u.callbackId=f.id);h=t.stringify(u);try{for(o=this.breakIntoSegments(h),l=o.length>1?this.generateId():0,s=0;s0;)i=t>u?u:t,f.push(n.substring(r,r+i)),r+=i,t-=i;return f},dispatchCallback:function(n,t,i){var r=this.extractName(n),e,u,o,c;if(r.factoryName&&r.methodName){if(r.factoryName==="sys"){if(r.methodName==="callback"){e=t[0];u=t[1];try{this.callbackTable[e].setResult(u)}catch(h){this.log("Failed to invoke return value callback:\n"+h.toString())}this.removeTask(e)}if(r.methodName==="callbackException"){e=t[0];u=t[1];try{this.callbackTable[e].setException(new Error(u).toString())}catch(h){this.log("Failed to invoke exception handler callback:\n"+h.toString())}this.removeTask(e)}return}if(o=this.extensions[r.factoryName],!o||!o[r.methodName]){this.log("Failed to match method call "+n);return}for(c=t.length;c<15;c++)t[c]=null;try{u=o[r.methodName](t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14])}catch(h){u=undefined;this.log("Exception thrown in callback method "+r.methodName+": %o",h);s(i,h.toString())}typeof u!="undefined"&&f(i,u)}},addExtensions:function(){try {{ var extension = +(function(n){"use strict";return{log:function(t){n.log(t)}}});; +this.addExtension("Microsoft.WebTools.BrowserLink.CoreExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.CoreExtensionFactory'."); return; }} +try {{ var extension = +(function(n,t){"use strict";var f=[],i=[],h=function(n){for(var i,t=0;t=i.originalStart&&t<=i.originalStart+i.originalLength},o=function(n,t){return e(n,function(n){return n.type!=1?!1:y(n,t)})},it=function(n,t,i){return e(n,function(n){var u=r(n);return u&&typeof u.originalStart!="undefined"&&u.originalStart==t&&u.originalLength==i})},p=function(n){var t=s(n);return{index:t.length,source:n,collection:t}},w=function(n,t){var r=n.index-1,i;return r>=0&&(i=n.collection[r],i.type==4&&y(i,t))?(n=p(i),w(n,t)):n},rt=function(n,t){var i=e(n,function(n){var i=r(n);return i&&typeof i.originalStart!="undefined"&&t=0;r--)if(f=t.children[r],u=n(f,i),u)return u;return t.getDomNode()===i?{logicalNode:t}:t.getDomNode()?{foundOtherDomNode:!0}:null},u=function(t,r){for(var o,f,e=t.parent,s=e.children.indexOf(t),u=s-1;u>=0;u--)if(o=e.children[u],f=n(o,r),i,f)return f;return null},t=function(n,i){var r=u(n,i);return r?r:n.parent?n.parent.getDomNode()===i?{logicalNode:n.parent}:n.parent.getDomNode()?{foundOtherDomNode:!0}:t(n.parent,i):null},r=function(n){return o.innerHTML=n,o.innerHTML},f=function(n){for(var f,t=n.__browserLink_LogicalNodes.slice(),u="",i=0;i1&&u==n.textContent?!0:!1},e=function(n){for(var f,e,t=n.__browserLink_LogicalNodes.slice(),i=n,u=0;u0&&(t=n.indexOf(this),t>=0&&n.splice(t,1))};this.setupRelatedDomNode=function(){var n,i;this.domNode.__browserLink_LogicalNodes?(n=t(this,this.domNode),n&&n.logicalNode?(i=this.domNode.__browserLink_LogicalNodes.indexOf(n.logicalNode),this.domNode.__browserLink_LogicalNodes.splice(i+1,0,this)):this.domNode.__browserLink_LogicalNodes.splice(0,0,this),this.domNode.nodeType===Node.TEXT_NODE&&f(this.domNode)&&e(this.domNode)):this.domNode.__browserLink_LogicalNodes=[this]};this.setDomNode=function(n){this.domNode!==n&&(this.domNode&&this.disconnectRelatedDomNode(),this.domNode=n,this.domNode&&this.setupRelatedDomNode())}}function ht(){var f,e;this.root={};var u="\0",s=1,h={},k=this;this.createNewLogicalNode=function(n,t,i,r){var u=new d,f,e;return n&&(u.type=n),t&&u.setDomNode(t),i&&(u.parent=i,n===st.Attribute?i.attributes.push(u):(f=r?i.children.indexOf(r):-1,f>=0?(e=f+1,i.children.splice(e,0,u)):i.children.splice(0,0,u))),u};var c=function(n){var r=t.extend(new d,n),i,u,f;if(n.children)for(i=0;i0&&(r=h[i],n.setDomNode(r)),n.children)for(t=0;t=i?e>=o?(u=i,f=0,s=0):e>u?(u=i,f=o-e,s=e>=h?0:h-e):u+=r:h>i?(e>h?s=i-u:s+=r,e>o?f=i-u:f+=r):o>i&&(e>o?f=i-u:f+=r);n.start.position=u;n.length=f;n.startTagLength&&(n.startTagLength=s);w(n,t,i,r)}};this.buildDocumentBlockList=function(){var t=[];y(document,t);n.invoke("UpdateBlockListFromDOM",n.initializationData.requestId,t)};this.initialize=function(t){o==null&&(o=document.createElement("textarea"));this.root=c(t.root);v(this.root);g();a=!0;n.sourceMapping.ensureUpToDateAsync(null)};this.applyChangesInFile=function(n,t){while(t.length>=2){var i=t.shift(),r=t.shift();b(this.root,n,i,r)}};this.getLogicalNodesFromDomNode=function(n){return n&&n.__browserLink_LogicalNodes?n.__browserLink_LogicalNodes:[]};this.getFirstLogicalNodeFromDomNode=function(n){var t=this.getLogicalNodesFromDomNode(n);return t&&t.length>0?t[0]:null};this.getAllNodesStartingAtPosition=function(n,t){var i=[];return f(n,t,this.root,i),i};f=function(n,t,i,r){var e,u,o;if(i){if(i.start&&t===i.start.position&&n===i.start.path&&r.push(i),i.children)for(u=0;u=i.start.position&&t=f.length)&&(r=f);if(i.attributes)for(u=0;u=f.length)&&(r=f);return r}}function ct(){var o=this,l=function(n){return w(n)},v=function(n,t,r){if(n0)return i.Task;for(u=c,c=[],t=0;t0?t.Task:f.length==0?t.Task:(ot(function(){var t=f,n;for(f=[],n=0;n=t-u.start)return i.cssRules[r];break}return null};this.getAllSourcePaths=function(){return i};this.internal={addMappingRangeForObject:function(n,t){var r=e(t.sourcePath||t.sourceUrl),i={sourceIndex:r,start:t.startPosition,length:t.length};b(n,i);u.push(i)}};t=7e3;s=[];this.validateStyleSheet=function(i){var u=s.indexOf(i.href)>=0,r;return u?!1:(r=function(n){var u=0,f,e;try{if(n&&n.cssRules&&(u+=i.cssRules.length,u>t))return u;for(f=0;ft))break;return u}catch(o){return t+1}},r(i)>t)?(s.push(i.href),n.log(`CSS Hot Reload ignoring ${i.href} because it was inaccessible or had more than ${t} rules.`),!1):!0}}var i=[],s={},h=!1,a=!1,r=0,f=[],c=[],u=[],v={},y=function(){var n=[];this.complete=function(){for(var t=null;n.length;)t=n.shift()(t)};this.Task={continueWith:function(t){n.push(t)}}},rt=function(n){return n.selectorText||n.media},p=function(n){var r=rt(n),t,i,u;if(!r)return{value:null};for(t=v[r],t||(t=[],v[r]=t),i=0;i=t?f>=o?(r=t,u=0,e=0):f>r?(u=o-f,r=t,e=f>=s?0:s-f):r+=i:s>t?(f>s?e=t-r:e+=i,f>o?u=t-r:u+=i):o>t&&(f>o?u=t-r:u+=i);n.start=r;n.length=u;n.startTag&&(n.startTag=e)},et=function(n,t){for(var f,e,i,r;t.length>=2;)for(f=t.shift(),e=t.shift(),i=0;i=2?s[1]:{},i={selectorData:r,sourceIndex:f[0]+t,start:f[1],length:f[2],isLiteral:f[3],startTag:f.length>=5?f[4]:null,children:g(l.children,t),ancestors:g(l.ancestors,t)},l.templateLike&&o.length==2&&(r.isTemplateLike=!0,r.isInTemplateLike=!0),e=0;e0))for(i=document.styleSheets,t=0;t=0?(et(r,t),!0):!1},applyChangesInFileToLogicalTree:function(t,i){n.logicalTree.applyChangesInFile(t,i)},onConnected:function(){Array.prototype.indexOf&&(n.logicalTree.buildDocumentBlockList(),n.sourceMapping.ensureUpToDateAsync(null))},setLogicalTree:function(t,r){i=i.concat(r);n.logicalTree.initialize(t)}}});; +this.addExtension("Microsoft.WebTools.BrowserLink.SourceMappingExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.SourceMappingExtensionFactory'."); return; }} +try {{ var extension = +(function(){"use strict";return{refresh:function(){location.reload(!0)},navigate:function(n){location.href=n}}});; +this.addExtension("Microsoft.WebTools.BrowserLink.Package.RefreshExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.Package.RefreshExtensionFactory'."); return; }} +},generateId:function(){return this.nextId++,this.nextId<0&&(this.nextId=0),this.nextId},removeTask:function(n){delete this.callbackTable[n]},addExtension:function(f,e){var o={},s,h,c,l;if(typeof e!="function"){this.log("Extension function definition was not defined as a function object.");return}h=function(n,t){if(typeof n=="undefined")throw new Error("Browser Link: Method call failed, missing method name argument.");if(!t)throw new Error('Method call failed, missing class name. Use the format "namespace."methodName"');return t+"."+n};c=function(n){for(var i=[],t=1;t=0||navigator.userAgent.search(/trident/i)>=0?!0:!1},r()&&(u=window.location,t=window.document.createElement("a"),t.href=n,i=function(n){return n&&n.indexOf(".")<0?!0:!1},i(t.hostname)&&!i(u.hostname)))return!1;try{return f=new XMLHttpRequest,f.open("get",n),!0}catch(e){return!1}};o(i.connection.url)?i.connection.start().done(f):i.connection.start({transport:"longPolling",jsonp:!0}).done(f)}};n(window).on("beforeunload",function(){i.isUnloading=!0});if(i.initialize(),window._vwdonbeforeunload)n(window).on("beforeunload",window._vwdonbeforeunload)})($.noConflict(!0),JSON);window._vwdJSON&&(JSON=window._vwdJSON);window._vwdDefine&&(define=window._vwdDefine); \ No newline at end of file diff --git a/Submission_files/buttons.bootstrap5.js.download b/Submission_files/buttons.bootstrap5.js.download new file mode 100644 index 0000000000..b5e5ce494d --- /dev/null +++ b/Submission_files/buttons.bootstrap5.js.download @@ -0,0 +1,122 @@ +/*! Bootstrap integration for DataTables' Buttons + * © SpryMedia Ltd - datatables.net/license + */ + +(function( factory ){ + if ( typeof define === 'function' && define.amd ) { + // AMD + define( ['jquery', 'datatables.net-bs5', 'datatables.net-buttons'], function ( $ ) { + return factory( $, window, document ); + } ); + } + else if ( typeof exports === 'object' ) { + // CommonJS + var jq = require('jquery'); + var cjsRequires = function (root, $) { + if ( ! $.fn.dataTable ) { + require('datatables.net-bs5')(root, $); + } + + if ( ! $.fn.dataTable.Buttons ) { + require('datatables.net-buttons')(root, $); + } + }; + + if (typeof window === 'undefined') { + module.exports = function (root, $) { + if ( ! root ) { + // CommonJS environments without a window global must pass a + // root. This will give an error otherwise + root = window; + } + + if ( ! $ ) { + $ = jq( root ); + } + + cjsRequires( root, $ ); + return factory( $, root, root.document ); + }; + } + else { + cjsRequires( window, jq ); + module.exports = factory( jq, window, window.document ); + } + } + else { + // Browser + factory( jQuery, window, document ); + } +}(function( $, window, document ) { +'use strict'; +var DataTable = $.fn.dataTable; + + + +$.extend(true, DataTable.Buttons.defaults, { + dom: { + container: { + className: 'dt-buttons btn-group flex-wrap' + }, + button: { + className: 'btn btn-secondary', + active: 'active', + dropHtml: '', + dropClass: 'dropdown-toggle' + }, + collection: { + container: { + tag: 'div', + className: 'dt-button-collection', + content: { + tag: 'ul', + className: 'dropdown-menu show' + } + }, + closeButton: false, + button: { + tag: 'li', + className: 'dt-button', + active: 'dt-button-active-a', + disabled: 'disabled', + liner: { + tag: 'a', + className: 'dropdown-item' + }, + spacer: { + className: 'divider', + tag: 'li' + } + } + }, + split: { + action: { + tag: 'a', + className: 'btn btn-secondary dt-button-split-drop-button', + closeButton: false + }, + dropdown: { + tag: 'button', + className: + 'btn btn-secondary dt-button-split-drop dropdown-toggle-split', + closeButton: false, + align: 'split-left', + splitAlignClass: 'dt-button-split-left' + }, + wrapper: { + tag: 'div', + className: 'dt-button-split btn-group', + closeButton: false + } + } + }, + buttonCreated: function (config, button) { + return config.buttons ? $('
').append(button) : button; + } +}); + +DataTable.ext.buttons.collection.rightAlignClassName = 'dropdown-menu-right'; + + +return DataTable; +})); diff --git a/Submission_files/buttons.bootstrap5.min.css b/Submission_files/buttons.bootstrap5.min.css new file mode 100644 index 0000000000..6c0c20c93c --- /dev/null +++ b/Submission_files/buttons.bootstrap5.min.css @@ -0,0 +1 @@ +@keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dataTables_wrapper{position:relative}div.dt-buttons{position:initial}div.dt-buttons .dt-button{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border-radius:.75em;box-shadow:3px 4px 10px 1px rgba(0, 0, 0, 0.8);text-align:center;z-index:2003;overflow:hidden}div.dt-button-info h2{padding:2rem 2rem 1rem 2rem;margin:0;font-weight:normal}div.dt-button-info>div{padding:1em 2em 2em 2em}div.dtb-popover-close{position:absolute;top:6px;right:6px;width:22px;height:22px;text-align:center;border-radius:3px;cursor:pointer;z-index:2003}button.dtb-hide-drop{display:none !important}div.dt-button-collection-title{text-align:center;padding:.3em .5em .5em;margin-left:.5em;margin-right:.5em;font-size:.9em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}div.dt-button-collection-title:empty{display:none}span.dt-button-spacer{display:inline-block;margin:.5em;white-space:nowrap}span.dt-button-spacer.bar{border-left:1px solid rgba(0, 0, 0, 0.3);vertical-align:middle;padding-left:.5em}span.dt-button-spacer.bar:empty{height:1em;width:1px;padding-left:0}div.dt-button-collection .dt-button-active{padding-right:3em}div.dt-button-collection .dt-button-active:after{position:absolute;top:50%;margin-top:-10px;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection .dt-button-active.dt-button-split{padding-right:0}div.dt-button-collection .dt-button-active.dt-button-split:after{display:none}div.dt-button-collection .dt-button-active.dt-button-split>*:first-child{padding-right:3em}div.dt-button-collection .dt-button-active.dt-button-split>*:first-child:after{position:absolute;top:50%;margin-top:-10px;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection .dt-button-active-a a{padding-right:3em}div.dt-button-collection .dt-button-active-a a:after{position:absolute;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection span.dt-button-spacer{width:100%;font-size:.9em;text-align:center;margin:.5em 0}div.dt-button-collection span.dt-button-spacer:empty{height:0;width:100%}div.dt-button-collection span.dt-button-spacer.bar{border-left:none;border-bottom:1px solid rgba(0, 0, 0, 0.1);padding-left:0}@media print{table.dataTable tr>*{box-shadow:none !important}}div.dt-buttons div.btn-group{position:initial}div.dt-buttons span.dt-button-spacer.empty{margin:1px}div.dt-buttons span.dt-button-spacer.bar:empty{height:inherit}div.dt-buttons .btn.processing{color:rgba(0, 0, 0, 0.2)}div.dt-buttons .btn.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:" ";border:2px solid rgb(40, 40, 40);border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear}div.dt-button-collection{position:absolute;min-width:200px;margin-top:4px;z-index:2002;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);box-shadow:var(--bs-box-shadow)}div.dt-button-collection div.dt-button-collection-title{padding:.75em 0 .25em}div.dt-button-collection .dropdown-menu{position:relative;display:block;width:100%;background-color:transparent;border:none;border-radius:0;box-shadow:none}div.dt-button-collection .dt-button{position:relative}div.dt-button-collection .dt-button.dropdown-toggle::after{position:absolute;right:12px;top:14px}div.dt-button-collection div.dt-button-split{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:stretch}div.dt-button-collection div.dt-button-split>*:first-child{min-width:auto;flex:1 0 50px}div.dt-button-collection div.dt-button-split button:last-child{min-width:33px;flex:0;background:transparent;border:none;line-height:1rem;color:var(--bs-dropdown-link-color);padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);overflow:visible}div.dt-button-collection div.dt-button-split button:last-child:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}div.dt-button-collection.fixed{position:fixed;display:block;top:50%;left:50%;margin-left:-75px;border-radius:5px;background-color:white;padding:.5em}div.dt-button-collection.fixed.two-column{margin-left:-200px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection.fixed.columns{margin-left:-409px}@media screen and (max-width: 1024px){div.dt-button-collection.fixed.columns{margin-left:-308px}}@media screen and (max-width: 640px){div.dt-button-collection.fixed.columns{margin-left:-203px}}@media screen and (max-width: 460px){div.dt-button-collection.fixed.columns{margin-left:-100px}}div.dt-button-collection.fixed>:last-child{max-height:100vh;overflow:auto}div.dt-button-collection.two-column>:last-child,div.dt-button-collection.three-column>:last-child,div.dt-button-collection.four-column>:last-child{display:block !important;column-gap:8px}div.dt-button-collection.two-column>:last-child>*,div.dt-button-collection.three-column>:last-child>*,div.dt-button-collection.four-column>:last-child>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:400px}div.dt-button-collection.two-column>:last-child{padding-bottom:1px;column-count:2}div.dt-button-collection.three-column{width:450px}div.dt-button-collection.three-column>:last-child{padding-bottom:1px;column-count:3}div.dt-button-collection.four-column{width:600px}div.dt-button-collection.four-column>:last-child{padding-bottom:1px;column-count:4}div.dt-button-collection .dt-button{border-radius:0}div.dt-button-collection.columns{width:auto}div.dt-button-collection.columns>:last-child{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:6px;width:818px;padding-bottom:1px}div.dt-button-collection.columns>:last-child .dt-button{min-width:200px;flex:0 1;margin:0}div.dt-button-collection.columns.dtb-b3>:last-child,div.dt-button-collection.columns.dtb-b2>:last-child,div.dt-button-collection.columns.dtb-b1>:last-child{justify-content:space-between}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:1 1 32%}div.dt-button-collection.columns.dtb-b2 .dt-button{flex:1 1 48%}div.dt-button-collection.columns.dtb-b1 .dt-button{flex:1 1 100%}@media screen and (max-width: 1024px){div.dt-button-collection.columns>:last-child{width:612px}}@media screen and (max-width: 640px){div.dt-button-collection.columns>:last-child{width:406px}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:0 1 32%}}@media screen and (max-width: 460px){div.dt-button-collection.columns>:last-child{width:200px}}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999}@media screen and (max-width: 767px){div.dt-buttons{float:none;width:100%;text-align:center;margin-bottom:.5em}div.dt-buttons a.btn{float:none}}div.dt-button-info{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color-translucent)}:root[data-bs-theme=dark] div.dt-button-collection.fixed{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color-translucent)} diff --git a/Submission_files/buttons.colVis.min.js.download b/Submission_files/buttons.colVis.min.js.download new file mode 100644 index 0000000000..b4a0642cb3 --- /dev/null +++ b/Submission_files/buttons.colVis.min.js.download @@ -0,0 +1,5 @@ +/*! + * Column visibility buttons for Buttons and DataTables. + * © SpryMedia Ltd - datatables.net/license + */ +(i=>{var o,e;"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(n){return i(n,window,document)}):"object"==typeof exports?(o=require("jquery"),e=function(n,t){t.fn.dataTable||require("datatables.net")(n,t),t.fn.dataTable.Buttons||require("datatables.net-buttons")(n,t)},"undefined"==typeof window?module.exports=function(n,t){return n=n||window,t=t||o(n),e(n,t),i(t,0,n.document)}:(e(window,o),module.exports=i(o,window,window.document))):i(jQuery,window,document)})(function(n,t,i){var e=n.fn.dataTable;return n.extend(e.ext.buttons,{colvis:function(n,t){var i=null,o={extend:"collection",init:function(n,t){i=t},text:function(n){return n.i18n("buttons.colvis","Column visibility")},className:"buttons-colvis",closeButton:!1,buttons:[{extend:"columnsToggle",columns:t.columns,columnText:t.columnText}]};return n.on("column-reorder.dt"+t.namespace,function(){n.button(null,n.button(null,i).node()).collectionRebuild([{extend:"columnsToggle",columns:t.columns,columnText:t.columnText}])}),o},columnsToggle:function(n,t){return n.columns(t.columns).indexes().map(function(n){return{extend:"columnToggle",columns:n,columnText:t.columnText}}).toArray()},columnToggle:function(n,t){return{extend:"columnVisibility",columns:t.columns,columnText:t.columnText}},columnsVisibility:function(n,t){return n.columns(t.columns).indexes().map(function(n){return{extend:"columnVisibility",columns:n,visibility:t.visibility,columnText:t.columnText}}).toArray()},columnVisibility:{columns:void 0,text:function(n,t,i){return i._columnText(n,i)},className:"buttons-columnVisibility",action:function(n,t,i,o){var t=t.columns(o.columns),e=t.visible();t.visible(void 0!==o.visibility?o.visibility:!(e.length&&e[0]))},init:function(e,n,t){var u=this,l=e.column(t.columns);n.attr("data-cv-idx",t.columns),e.on("column-visibility.dt"+t.namespace,function(n,t,i,o){l.index()!==i||t.bDestroying||t.nTable!=e.settings()[0].nTable||u.active(o)}).on("column-reorder.dt"+t.namespace,function(){t.destroying||1===e.columns(t.columns).count()&&(l=e.column(t.columns),u.text(t._columnText(e,t)),u.active(l.visible()))}),this.active(l.visible())},destroy:function(n,t,i){n.off("column-visibility.dt"+i.namespace).off("column-reorder.dt"+i.namespace)},_columnText:function(n,t){var i,o;return"string"==typeof t.text?t.text:(o=n.column(t.columns).title(),i=n.column(t.columns).index(),o=o.replace(/\n/g," ").replace(//gi," ").replace(//gi,""),o=e.Buttons.stripHtmlComments(o),o=e.util.stripHtml(o).trim(),t.columnText?t.columnText(n,i,o):o)}},colvisRestore:{className:"buttons-colvisRestore",text:function(n){return n.i18n("buttons.colvisRestore","Restore visibility")},init:function(n,t,i){n.columns().every(function(){var n=this.init();void 0===n.__visOriginal&&(n.__visOriginal=this.visible())})},action:function(n,t,i,o){t.columns().every(function(n){var t=this.init();this.visible(t.__visOriginal)})}},colvisGroup:{className:"buttons-colvisGroup",action:function(n,t,i,o){t.columns(o.show).visible(!0,!1),t.columns(o.hide).visible(!1,!1),t.columns.adjust()},show:[],hide:[]}}),e}); \ No newline at end of file diff --git a/Submission_files/buttons.html5.min.js.download b/Submission_files/buttons.html5.min.js.download new file mode 100644 index 0000000000..26eb324034 --- /dev/null +++ b/Submission_files/buttons.html5.min.js.download @@ -0,0 +1,8 @@ +/*! + * HTML5 export buttons for Buttons and DataTables. + * © SpryMedia Ltd - datatables.net/license + * + * FileSaver.js (1.3.3) - MIT license + * Copyright © 2016 Eli Grey - http://eligrey.com + */ +(o=>{var l,n;"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(t){return o(t,window,document)}):"object"==typeof exports?(l=require("jquery"),n=function(t,e){e.fn.dataTable||require("datatables.net")(t,e),e.fn.dataTable.Buttons||require("datatables.net-buttons")(t,e)},"undefined"==typeof window?module.exports=function(t,e){return t=t||window,e=e||l(t),n(t,e),o(e,t,t.document)}:(n(window,l),module.exports=o(l,window,window.document))):o(jQuery,window,document)})(function(S,C,u){var e,o,t=S.fn.dataTable;function T(){return e||C.JSZip}function m(){return o||C.pdfMake}t.Buttons.pdfMake=function(t){if(!t)return m();o=t},t.Buttons.jszip=function(t){if(!t)return T();e=t};function k(t){var e="Sheet1";return e=t.sheetName?t.sheetName.replace(/[\[\]\*\/\\\?\:]/g,""):e}function c(t,e){function o(t){for(var e="",o=0,l=t.length;o{var p,i,f,m,s,u,e,c,y,l,t;if(!(void 0===d||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent)))return t=d.document,p=function(){return d.URL||d.webkitURL||d},i=t.createElementNS("http://www.w3.org/1999/xhtml","a"),f="download"in i,m=/constructor/i.test(d.HTMLElement)||d.safari,s=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(d.setImmediate||d.setTimeout)(function(){throw t},0)},e=4e4,c=function(t){setTimeout(function(){"string"==typeof t?p().revokeObjectURL(t):t.remove()},e)},y=function(t){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob([String.fromCharCode(65279),t],{type:t.type}):t},t=(l=function(t,o,e){e||(t=y(t));var l,n,r=this,e="application/octet-stream"===t.type,a=function(){for(var t=r,e="writestart progress write writeend".split(" "),o=void 0,l=(e=[].concat(e)).length;l--;){var n=t["on"+e[l]];if("function"==typeof n)try{n.call(t,o||t)}catch(t){u(t)}}};r.readyState=r.INIT,f?(l=p().createObjectURL(t),setTimeout(function(){var t,e;i.href=l,i.download=o,t=i,e=new MouseEvent("click"),t.dispatchEvent(e),a(),c(l),r.readyState=r.DONE})):(s||e&&m)&&d.FileReader?((n=new FileReader).onloadend=function(){var t=s?n.result:n.result.replace(/^data:[^;]*;/,"data:attachment/file;");d.open(t,"_blank")||(d.location.href=t),r.readyState=r.DONE,a()},n.readAsDataURL(t),r.readyState=r.INIT):(l=l||p().createObjectURL(t),!e&&d.open(l,"_blank")||(d.location.href=l),r.readyState=r.DONE,a(),c(l))}).prototype,"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(t,e,o){return e=e||t.name||"download",o||(t=y(t)),navigator.msSaveOrOpenBlob(t,e)}:(t.abort=function(){},t.readyState=t.INIT=0,t.WRITING=1,t.DONE=2,t.error=t.onwritestart=t.onprogress=t.onwrite=t.onabort=t.onerror=t.onwriteend=null,function(t,e,o){return new l(t,e||t.name||"download",o)})})("undefined"!=typeof self&&self||void 0!==C&&C||this.content),y=(t.fileSave=N,function(t){return t.newline||(navigator.userAgent.match(/Windows/)?"\r\n":"\n")});function O(t){for(var e="A".charCodeAt(0),o="Z".charCodeAt(0)-e+1,l="";0<=t;)l=String.fromCharCode(t%o+e)+l,t=Math.floor(t/o)-1;return l}try{var z,E=new XMLSerializer}catch(t){}function A(t,e,o){var l=t.createElement(e);return o&&(o.attr&&S(l).attr(o.attr),o.children&&S.each(o.children,function(t,e){l.appendChild(e)}),null!=o.text)&&l.appendChild(t.createTextNode(o.text)),l}function D(t,e,o,l,n){var r=S("mergeCells",t);r[0].appendChild(A(t,"mergeCell",{attr:{ref:O(o)+e+":"+O(o+n-1)+(e+l-1)}})),r.attr("count",parseFloat(r.attr("count"))+1)}var R={"_rels/.rels":'',"xl/_rels/workbook.xml.rels":'',"[Content_Types].xml":'',"xl/workbook.xml":'',"xl/worksheets/sheet1.xml":'',"xl/styles.xml":''},$=[{match:/^\-?\d+\.\d%$/,style:60,fmt:function(t){return t/100}},{match:/^\-?\d+\.?\d*%$/,style:56,fmt:function(t){return t/100}},{match:/^\-?\$[\d,]+.?\d*$/,style:57},{match:/^\-?£[\d,]+.?\d*$/,style:58},{match:/^\-?€[\d,]+.?\d*$/,style:59},{match:/^\-?\d+$/,style:65},{match:/^\-?\d+\.\d{2}$/,style:66},{match:/^\([\d,]+\)$/,style:61,fmt:function(t){return-1*t.replace(/[\(\)]/g,"")}},{match:/^\([\d,]+\.\d{2}\)$/,style:62,fmt:function(t){return-1*t.replace(/[\(\)]/g,"")}},{match:/^\-?[\d,]+$/,style:63},{match:/^\-?[\d,]+\.\d{2}$/,style:64},{match:/^(19\d\d|[2-9]\d\d\d)\-(0\d|1[012])\-[0123][\d]$/,style:67,fmt:function(t){return Math.round(25569+Date.parse(t)/864e5)}}];return t.ext.buttons.copyHtml5={className:"buttons-copy buttons-html5",text:function(t){return t.i18n("buttons.copy","Copy")},action:function(t,e,o,l,n){var r=c(e,l),a=e.buttons.exportInfo(l),d=y(l),p=r.str,i=S("
").css({height:1,width:1,overflow:"hidden",position:"fixed",top:0,left:0}),d=(a.title&&(p=a.title+d+d+p),a.messageTop&&(p=a.messageTop+d+d+p),a.messageBottom&&(p=p+d+d+a.messageBottom),l.customize&&(p=l.customize(p,l,e)),S(""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (trac-13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (trac-12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (trac-13208) + // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (trac-13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", true ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, isSetup ) { + + // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add + if ( !isSetup ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + if ( !saved ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + this[ type ](); + result = dataPriv.get( this, type ); + dataPriv.set( this, type, false ); + + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + return result; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering + // the native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved ) { + + // ...and capture the result + dataPriv.set( this, type, jQuery.event.trigger( + saved[ 0 ], + saved.slice( 1 ), + this + ) ); + + // Abort handling of the native event by all jQuery handlers while allowing + // native handlers on the same element to run. On target, this is achieved + // by stopping immediate propagation just on the jQuery event. However, + // the native event is re-wrapped by a jQuery one on each level of the + // propagation so the only way to stop it for jQuery is to stop it for + // everyone via native `stopPropagation()`. This is not a problem for + // focus/blur which don't bubble, but it does also stop click on checkboxes + // and radios. We accept this limitation. + event.stopPropagation(); + event.isImmediatePropagationStopped = returnTrue; + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (trac-504, trac-13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + + function focusMappedHandler( nativeEvent ) { + if ( document.documentMode ) { + + // Support: IE 11+ + // Attach a single focusin/focusout handler on the document while someone wants + // focus/blur. This is because the former are synchronous in IE while the latter + // are async. In other browsers, all those handlers are invoked synchronously. + + // `handle` from private data would already wrap the event, but we need + // to change the `type` here. + var handle = dataPriv.get( this, "handle" ), + event = jQuery.event.fix( nativeEvent ); + event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; + event.isSimulated = true; + + // First, handle focusin/focusout + handle( nativeEvent ); + + // ...then, handle focus/blur + // + // focus/blur don't bubble while focusin/focusout do; simulate the former by only + // invoking the handler at the lower level. + if ( event.target === event.currentTarget ) { + + // The setup part calls `leverageNative`, which, in turn, calls + // `jQuery.event.add`, so event handle will already have been set + // by this point. + handle( event ); + } + } else { + + // For non-IE browsers, attach a single capturing handler on the document + // while someone wants focusin/focusout. + jQuery.event.simulate( delegateType, nativeEvent.target, + jQuery.event.fix( nativeEvent ) ); + } + } + + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + var attaches; + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, true ); + + if ( document.documentMode ) { + + // Support: IE 9 - 11+ + // We use the same native handler for focusin & focus (and focusout & blur) + // so we need to coordinate setup & teardown parts between those events. + // Use `delegateType` as the key as `type` is already used by `leverageNative`. + attaches = dataPriv.get( this, delegateType ); + if ( !attaches ) { + this.addEventListener( delegateType, focusMappedHandler ); + } + dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); + } else { + + // Return false to allow normal processing in the caller + return false; + } + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + teardown: function() { + var attaches; + + if ( document.documentMode ) { + attaches = dataPriv.get( this, delegateType ) - 1; + if ( !attaches ) { + this.removeEventListener( delegateType, focusMappedHandler ); + dataPriv.remove( this, delegateType ); + } else { + dataPriv.set( this, delegateType, attaches ); + } + } else { + + // Return false to indicate standard teardown should be applied + return false; + } + }, + + // Suppress native focus or blur if we're currently inside + // a leveraged native-event stack + _default: function( event ) { + return dataPriv.get( event.target, type ); + }, + + delegateType: delegateType + }; + + // Support: Firefox <=44 + // Firefox doesn't have focus(in | out) events + // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 + // + // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 + // focus(in | out) events fire after focus & blur events, + // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order + // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 + // + // Support: IE 9 - 11+ + // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, + // attach a single handler for both events in IE. + jQuery.event.special[ delegateType ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + dataHolder = document.documentMode ? this : doc, + attaches = dataPriv.get( dataHolder, delegateType ); + + // Support: IE 9 - 11+ + // We use the same native handler for focusin & focus (and focusout & blur) + // so we need to coordinate setup & teardown parts between those events. + // Use `delegateType` as the key as `type` is already used by `leverageNative`. + if ( !attaches ) { + if ( document.documentMode ) { + this.addEventListener( delegateType, focusMappedHandler ); + } else { + doc.addEventListener( type, focusMappedHandler, true ); + } + } + dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + dataHolder = document.documentMode ? this : doc, + attaches = dataPriv.get( dataHolder, delegateType ) - 1; + + if ( !attaches ) { + if ( document.documentMode ) { + this.removeEventListener( delegateType, focusMappedHandler ); + } else { + doc.removeEventListener( type, focusMappedHandler, true ); + } + dataPriv.remove( dataHolder, delegateType ); + } else { + dataPriv.set( dataHolder, delegateType, attaches ); + } + } + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (trac-8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Re-enable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + + // Unwrap a CDATA section containing script contents. This shouldn't be + // needed as in XML documents they're already not visible when + // inspecting element contents and in HTML documents they have no + // meaning but we're preserving that logic for backwards compatibility. + // This will be removed completely in 4.0. See gh-4904. + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew jQuery#find here for performance reasons: + // https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var rcustomProp = /^--/; + + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (trac-8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "box-sizing:content-box;border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is `display: block` + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + isCustomProp = rcustomProp.test( name ), + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, trac-12537) + // .css('--customProperty) (gh-3144) + if ( computed ) { + + // Support: IE <=9 - 11+ + // IE only supports `"float"` in `getPropertyValue`; in computed styles + // it's only available as `"cssFloat"`. We no longer modify properties + // sent to `.css()` apart from camelCasing, so we need to check both. + // Normally, this would create difference in behavior: if + // `getPropertyValue` returns an empty string, the value returned + // by `.css()` would be `undefined`. This is usually the case for + // disconnected elements. However, in IE even disconnected elements + // with no styles return `"none"` for `getPropertyValue( "float" )` + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( isCustomProp && ret ) { + + // Support: Firefox 105+, Chrome <=105+ + // Spec requires trimming whitespace for custom properties (gh-4926). + // Firefox only trims leading whitespace. Chrome just collapses + // both leading & trailing whitespace to a single space. + // + // Fall back to `undefined` if empty string returned. + // This collapses a missing definition with property defined + // and set to an empty string but there's no standard API + // allowing us to differentiate them without a performance penalty + // and returning `undefined` aligns with older jQuery. + // + // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED + // as whitespace while CSS does not, but this is not a problem + // because CSS preprocessing replaces them with U+000A LINE FEED + // (which *is* CSS whitespace) + // https://www.w3.org/TR/css-syntax-3/#input-preprocessing + ret = ret.replace( rtrimCSS, "$1" ) || undefined; + } + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0, + marginDelta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + // Count margin delta separately to only add it after scroll gutter adjustment. + // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). + if ( box === "margin" ) { + marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta + marginDelta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + animationIterationCount: true, + aspectRatio: true, + borderImageSlice: true, + columnCount: true, + flexGrow: true, + flexShrink: true, + fontWeight: true, + gridArea: true, + gridColumn: true, + gridColumnEnd: true, + gridColumnStart: true, + gridRow: true, + gridRowEnd: true, + gridRowStart: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + scale: true, + widows: true, + zIndex: true, + zoom: true, + + // SVG-related + fillOpacity: true, + floodOpacity: true, + stopOpacity: true, + strokeMiterlimit: true, + strokeOpacity: true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (trac-7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug trac-9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (trac-7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // Use proper attribute retrieval (trac-12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classNames, cur, curValue, className, i, finalValue; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classNames = classesToArray( value ); + + if ( classNames.length ) { + return this.each( function() { + curValue = getClass( this ); + cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + for ( i = 0; i < classNames.length; i++ ) { + className = classNames[ i ]; + if ( cur.indexOf( " " + className + " " ) < 0 ) { + cur += className + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + this.setAttribute( "class", finalValue ); + } + } + } ); + } + + return this; + }, + + removeClass: function( value ) { + var classNames, cur, curValue, className, i, finalValue; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classNames = classesToArray( value ); + + if ( classNames.length ) { + return this.each( function() { + curValue = getClass( this ); + + // This expression is here for better compressibility (see addClass) + cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + for ( i = 0; i < classNames.length; i++ ) { + className = classNames[ i ]; + + // Remove *all* instances + while ( cur.indexOf( " " + className + " " ) > -1 ) { + cur = cur.replace( " " + className + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + this.setAttribute( "class", finalValue ); + } + } + } ); + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var classNames, className, i, self, + type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + classNames = classesToArray( value ); + + return this.each( function() { + if ( isValidValue ) { + + // Toggle individual class names + self = jQuery( this ); + + for ( i = 0; i < classNames.length; i++ ) { + className = classNames[ i ]; + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (trac-14686, trac-14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (trac-2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (trac-9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (trac-6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // trac-7653, trac-8125, trac-8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes trac-9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (trac-10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket trac-12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // trac-9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (trac-11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // trac-1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see trac-8605, trac-14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // trac-14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " - -
-
- UGM 0.0.0+25511915f56325dafd27b0c08d1b88ce8e4e9ce0 -
-
- - - - - - - - -
- -
-
- - - - - - -
-
- - - - - - -
-
-
- -
-
-
-
- - - - - -
-
-
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
-
-
-
- - -
- -
- - -
- -
-
- -
-
-
Application Status
-
-
- Approved -
-
-
-
-
- -
-
-
Application Tags
-
-
- -
-
-
-
-
- - - - - -
-
Unity Application ID
-
BC-ABPP-FY2526-claims-00005
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - -
-
- -
-
- - -
- -
-
- -
- ABPP 2025 - Fall Claim for Payment -
-
- -
- 2026-03-27 -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- $0.00 -
-
- -
- $0.00 -
-
- -
- -
-
-
-
-
Assessment Summary
- - - - - - - - - - - - - - - - - - - - - -
- -
- Approved -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- 0 -
-
- -
- -
-
- -
- $0.00 -
-
- -
- $3,000.00 -
-
-
- - - - -
-
-
- -
- -
-
Emails
-
-
- -
- - - - - - - - - - - -
-
- -
-
- -
-
-
Email History
-
-
- -
-
-
-
-
Comments
-
-
- -
-
-
-
-
-
-
- -
- - -
-
-
-
-
-
-
- -
-
-
-
Internal Uploads by Program
-
-
- -
-
-
- -
-
-
- - -
-
-
- -
-
-
-
-
Submission Attachments
-
-
- - - -
-
-
-
- -
-
-
- - - -
-
-
- -
-
-
-

Application Status History

-
-
-
- - -
-
-
-
- -
-
-
-
- Status changed - to - Submitted -
-
- -
-
-
-
-
-
-
-
- -
- -
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - SunMonTueWedThuFriSat - -
123456789101112131415161718192021222324252627282930311234567891011
\ No newline at end of file diff --git a/Submission_files/AnalyticsUtils.js.download b/Submission_files/AnalyticsUtils.js.download deleted file mode 100644 index bc86ff95b8..0000000000 --- a/Submission_files/AnalyticsUtils.js.download +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Analytics utility functions for Grant Manager application - */ -const AnalyticsUtils = (function () { - 'use strict'; - - const DIMENSION_TENANT_NAME = 1; - const DIMENSION_USER_NAME = 2; - - /** - * Safely gets the current tenant name from ABP. - * - * @returns {string|null} Tenant name or null if unavailable. - */ - function getTenantName() { - return globalThis.abp?.currentTenant?.name ?? null; - } - - /** - * Safely gets the current authenticated user ID from ABP. - * - * @returns {string|null} User ID or null if unavailable. - */ - function getUserId() { - return globalThis.abp?.currentUser?.id ? String(globalThis.abp.currentUser.id) : null; - } - - /** - * Safely builds the current user's full name from ABP. - * - * @returns {string|null} Full user name or null if unavailable. - */ - function getUserName() { - const firstName = globalThis.abp?.currentUser?.name ?? ''; - - const lastName = globalThis.abp && - abp.currentUser && - ( - abp.currentUser.surname || - abp.currentUser.surName || - '' - ); - - const fullName = `${firstName} ${lastName}`.trim(); - - return fullName || null; - } - - /** - * Applies common custom dimensions for tenant and user. - * - * @param {Array} trackerQueue - Matomo tracker queue. - */ - function applyCustomDimensions(trackerQueue) { - const tenantName = getTenantName(); - const userName = getUserName(); - - if (tenantName) { - trackerQueue.push([ - 'setCustomDimension', - DIMENSION_TENANT_NAME, - tenantName - ]); - } else { - console.warn( - '[Analytics] Tenant name unavailable. Custom Dimension 1 not set.' - ); - } - - if (userName) { - trackerQueue.push([ - 'setCustomDimension', - DIMENSION_USER_NAME, - userName - ]); - } else { - console.warn( - '[Analytics] User name unavailable. Custom Dimension 2 not set.' - ); - } - } - - /** - * Loads the Matomo tracking script asynchronously. - * - * @param {string} url - Base Matomo URL. - */ - function loadMatomoScript(url) { - const script = document.createElement('script'); - - script.async = true; - script.src = `${url}/matomo.js`; - - script.onerror = function () { - console.error( - '[Analytics] Failed to load matomo.js from:', - script.src - ); - }; - - document.head.appendChild(script); - } - - /** - * Initialises Matomo analytics tracking. - * Disables cookies (GDPR), sets user identity, - * applies custom dimensions, tracks initial page view, - * and enables link tracking. - * - * @param {string} url - Base Matomo URL (no trailing slash). - * @param {string|number} siteId - Matomo site ID. - */ - function initMatomo(url, siteId) { - console.debug( - '[Analytics] initMatomo called — url:', - url, - '| siteId:', - siteId - ); - - if (!url || !siteId) { - console.warn( - '[Analytics] initMatomo aborted: url or siteId is missing.' - ); - return; - } - - const trackerQueue = globalThis._paq = globalThis._paq || []; - - trackerQueue.push( - ['disableCookies'], - ['setTrackerUrl', `${url}/matomo.php`], - ['setSiteId', String(siteId)] - ); - - const userId = getUserId(); - - if (userId) { - trackerQueue.push(['setUserId', userId]); - } - - applyCustomDimensions(trackerQueue); - - /** - * Track initial page view after dimensions are set. - */ - trackerQueue.push( - ['trackPageView'], - ['enableLinkTracking'] - ); - - loadMatomoScript(url); - } - - /** - * Tracks a virtual page view for AJAX-driven navigation - * without a full page reload. - * - * Re-applies dimensions for Action-scoped dimensions. - * - * @param {string} [url] - Virtual URL. - * @param {string} [title] - Virtual page title. - */ - function trackVirtualPageView(url, title) { - const trackerQueue = globalThis._paq; - - if (!trackerQueue) { - return; - } - - applyCustomDimensions(trackerQueue); - - trackerQueue.push( - ['setCustomUrl', url || globalThis.location.href], - ['setDocumentTitle', title || document.title], - ['trackPageView'] - ); - } - - /** - * Tracks internal site search. - * - * @param {string} keyword - Search term entered by the user. - * @param {string|false} [category] - Optional search category. - * @param {number|false} [resultCount] - Optional result count. - */ - function trackSearch(keyword, category, resultCount) { - const trackerQueue = globalThis._paq; - - if (!trackerQueue || !keyword) { - return; - } - - trackerQueue.push([ - 'trackSiteSearch', - keyword, - typeof category === 'string' ? category : false, - typeof resultCount === 'number' ? resultCount : false - ]); - } - - /** - * Public API - */ - return { - initMatomo, - trackVirtualPageView, - trackSearch - }; -})(); \ No newline at end of file diff --git a/Submission_files/ApplicationAttachments.css b/Submission_files/ApplicationAttachments.css deleted file mode 100644 index 0ec7a9efaa..0000000000 --- a/Submission_files/ApplicationAttachments.css +++ /dev/null @@ -1,31 +0,0 @@ -/* Updated for DataTables v2 - ensure proper width handling with scrollX */ -#ApplicationAttachmentsTable_wrapper .dt-scroll-body { - overflow: visible !important; -} - -/* Ensure table wrapper uses full width */ -#ApplicationAttachmentsTable_wrapper { - width: 100%; -} - -/* Ensure scroll container properly sizes */ -#ApplicationAttachmentsTable_wrapper .dt-scroll { - overflow: visible; -} - -/* Ensure inner scroll elements take full width */ -#ApplicationAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner, -#ApplicationAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner table { - width: 100% !important; -} - -#ApplicationAttachmentsTable_wrapper .dt-scroll-body table { - width: 100% !important; -} - -/*27121 Bug Fix*/ -@media (max-height: 768px) { - .dt-scroll-body { - max-height: inherit !important; - } -} \ No newline at end of file diff --git a/Submission_files/ApplicationAttachments.js.download b/Submission_files/ApplicationAttachments.js.download deleted file mode 100644 index eb0a0e8c8b..0000000000 --- a/Submission_files/ApplicationAttachments.js.download +++ /dev/null @@ -1,112 +0,0 @@ -// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js -$(function () { - const l = abp.localization.getResource('GrantManager'); - const nullPlaceholder = '—'; - - let inputAction = function (requestData, dataTableSettings) { - const urlParams = new URL(window.location.toLocaleString()).searchParams; - const applicationId = urlParams.get('ApplicationId'); - return { - attachmentType: 'APPLICATION', - attachedResourceId: applicationId - }; - }; - - let responseCallback = function (result) { - if (result) { - setTimeout(function () { - PubSub.publish('update_application_attachment_count', { files: result.length }); - }, 10); - } - - return { - data: result - }; - }; - - const dataTable = $('#ApplicationAttachmentsTable').DataTable( - abp.libs.datatables.normalizeConfiguration({ - serverSide: false, - order: [[2, 'asc']], - searching: true, - paging: false, - select: false, - info: false, - scrollX: true, - ajax: abp.libs.datatables.createAjax( - unity.grantManager.attachments.attachment.getAttachments, inputAction, responseCallback - ), - columnDefs: [ - { - title: '', - width: '40px', - className: 'text-center', - render: function (data) { - return ''; - }, - orderable: false - }, - { - title: l('AssessmentResultAttachments:DocumentName'), - data: 'fileName', - className: 'data-table-header text-break', - width: '30%', - }, - { - title: 'Label', - data: 'displayName', - className: 'data-table-header text-break', - width: '20%', - render: function (data) { - return data ?? nullPlaceholder; - } - }, - { - title: l('AssessmentResultAttachments:UploadedDate'), - data: 'time', - className: 'data-table-header', - width: '140px', - render: function (data, type) { - if (type === 'display' || type === 'filter') { - return new Date(data).toDateString(); - } - return data; - }, - }, - { - title: l('AssessmentResultAttachments:AttachedBy'), - data: 'attachedBy', - className: 'data-table-header', - width: '25%', - }, - { - title: '', - data: 's3ObjectKey', - width: '80px', - className: 'text-center', - render: function (data, type, full, meta) { - return generateAttachmentButtonContent(data, type, full, meta, 'Application'); - }, - orderable: false - } - ], - externalFilterButtonId: 'btn-toggle-filter-uploads', - }) - ); - - initializeFilterRowPlugin(dataTable, 'btn-toggle-filter-uploads'); - - dataTable.on('click', 'tbody tr', function (e) { - e.currentTarget.classList.toggle('selected'); - }); - - PubSub.subscribe( - 'refresh_application_attachment_list', - (msg, data) => { - dataTable.ajax.reload(); - } - ); - $('#attachments-tab').one('click', function () { - dataTable.columns.adjust(); - }); -}); diff --git a/Submission_files/ApplicationConfigurationScript b/Submission_files/ApplicationConfigurationScript deleted file mode 100644 index 136584556e..0000000000 --- a/Submission_files/ApplicationConfigurationScript +++ /dev/null @@ -1,350 +0,0 @@ -(function(){ - -$.extend(true, abp, { - "localization": { - "values": {}, - "resources": {}, - "languages": [ - { - "cultureName": "en", - "uiCultureName": "en", - "displayName": "en", - "twoLetterISOLanguageName": "en" - } - ], - "currentCulture": { - "displayName": "English (Canada)", - "englishName": "English (Canada)", - "threeLetterIsoLanguageName": "eng", - "twoLetterIsoLanguageName": "en", - "isRightToLeft": false, - "cultureName": "en-CA", - "name": "en-CA", - "nativeName": "English (Canada)", - "dateTimeFormat": { - "calendarAlgorithmType": "SolarCalendar", - "dateTimeFormatLong": "dddd, MMMM d, yyyy", - "shortDatePattern": "yyyy-MM-dd", - "fullDateTimePattern": "dddd, MMMM d, yyyy h:mm:ss tt", - "dateSeparator": "-", - "shortTimePattern": "h:mm tt", - "longTimePattern": "h:mm:ss tt" - } - }, - "defaultResourceName": "GrantManager", - "languagesMap": { - "bootstrap-datepicker": [ - { - "name": "zh-Hans", - "value": "zh-CN" - }, - { - "name": "zh-Hant", - "value": "zh-TW" - } - ], - "moment": [ - { - "name": "zh-Hans", - "value": "zh-cn" - }, - { - "name": "zh-Hant", - "value": "zh-tw" - }, - { - "name": "de-DE", - "value": "de" - } - ] - }, - "languageFilesMap": { - "bootstrap-datepicker": [ - { - "name": "zh-Hans", - "value": "zh-CN" - }, - { - "name": "zh-Hant", - "value": "zh-TW" - } - ], - "moment": [ - { - "name": "zh-Hans", - "value": "zh-cn" - }, - { - "name": "zh-Hant", - "value": "zh-tw" - }, - { - "name": "de-DE", - "value": "de" - } - ], - "jquery.timeago": [ - { - "name": "zh-Hans", - "value": "zh-CN" - }, - { - "name": "zh-Hant", - "value": "zh-TW" - } - ], - "jquery-validation": [ - { - "name": "zh-Hans", - "value": "zh" - }, - { - "name": "zh-Hant", - "value": "zh_TW" - } - ] - } - }, - "auth": { - "grantedPolicies": {} - }, - "setting": { - "values": { - "Abp.Localization.DefaultLanguage": "en-CA", - "Abp.Timing.TimeZone": "", - "Abp.Identity.Password.RequiredLength": "6", - "Abp.Identity.Password.RequiredUniqueChars": "1", - "Abp.Identity.Password.RequireNonAlphanumeric": "True", - "Abp.Identity.Password.RequireLowercase": "True", - "Abp.Identity.Password.RequireUppercase": "True", - "Abp.Identity.Password.RequireDigit": "True", - "Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "False", - "Abp.Identity.Password.PasswordChangePeriodDays": "0", - "Abp.Identity.Password.EnablePreventPasswordReuse": "False", - "Abp.Identity.Password.PreventPasswordReuseCount": "6", - "Abp.Identity.Lockout.AllowedForNewUsers": "True", - "Abp.Identity.Lockout.LockoutDuration": "300", - "Abp.Identity.Lockout.MaxFailedAccessAttempts": "5", - "Abp.Identity.SignIn.RequireConfirmedEmail": "False", - "Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "True", - "Abp.Identity.SignIn.RequireEmailVerificationToRegister": "False", - "Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "False", - "Abp.Identity.User.IsUserNameUpdateEnabled": "True", - "Abp.Identity.User.IsEmailUpdateEnabled": "True", - "Abp.Identity.OrganizationUnit.MaxUserMembershipCount": "2147483647", - "GrantManager.Notifications.Mailing.DefaultFromAddress": "NoReply.Unity@gov.bc.ca", - "GrantManager.Notifications.Mailing.EmailMaxRetryAttempts": "3", - "GrantManager.Locality.SectorFilter": null, - "GrantManager.UI.Tabs.Submission": null, - "GrantManager.UI.Tabs.Assessment": null, - "GrantManager.UI.Tabs.Project": null, - "GrantManager.UI.Tabs.Applicant": null, - "GrantManager.UI.Tabs.Payments": null, - "GrantManager.UI.Tabs.FundingAgreement": null, - "GrantManager.BackgroundJobs.IntakeResync_NumDaysToCheck": null, - "GrantManager.BackgroundJobs.IntakeResync_Expression": null, - "GrantManager.BackgroundJobs.CasPaymentsReconciliation_ProducerExpression": null, - "GrantManager.BackgroundJobs.CasFinancialNotificationSummary_ProducerExpression": null, - "GrantManager.BackgroundJobs.DataHealthCheckMonitor_Expression": null, - "GrantManager.BackgroundJobs.ApplicantTenantMapReconciliation_Expression": null - } - }, - "currentUser": { - "isAuthenticated": false, - "id": null, - "tenantId": null, - "impersonatorUserId": null, - "impersonatorTenantId": null, - "impersonatorUserName": null, - "impersonatorTenantName": null, - "userName": null, - "name": null, - "surName": null, - "email": null, - "emailVerified": false, - "phoneNumber": null, - "phoneNumberVerified": false, - "roles": [], - "sessionId": null - }, - "features": { - "values": { - "SettingManagement.Enable": "true", - "SettingManagement.AllowChangingEmailSettings": "false", - "Unity.Payments": "false", - "Unity.Notifications": "false", - "Unity.Flex": "false", - "Unity.Reporting": "false", - "Unity.AIReporting": "false", - "Unity.AI.AttachmentSummaries": "false", - "Unity.AI.ApplicationAnalysis": "false", - "Unity.AI.Scoring": "false", - "Unity.Analytics": "false" - } - }, - "globalFeatures": { - "enabledFeatures": [] - }, - "multiTenancy": { - "isEnabled": true, - "userSharingStrategy": 0 - }, - "currentTenant": { - "id": null, - "name": null, - "isAvailable": false - }, - "timing": { - "timeZone": { - "iana": { - "timeZoneName": null - }, - "windows": { - "timeZoneId": null - } - } - }, - "clock": { - "kind": "Utc" - }, - "objectExtensions": { - "modules": { - "Identity": { - "entities": { - "User": { - "properties": { - "OidcSub": { - "type": "System.String", - "typeSimple": "string", - "displayName": null, - "api": { - "onGet": { - "isAvailable": true - }, - "onCreate": { - "isAvailable": true - }, - "onUpdate": { - "isAvailable": true - } - }, - "ui": { - "onTable": { - "isVisible": true - }, - "onCreateForm": { - "isVisible": true - }, - "onEditForm": { - "isVisible": true - }, - "lookup": { - "url": null, - "resultListPropertyName": null, - "displayPropertyName": null, - "valuePropertyName": null, - "filterParamName": null - } - }, - "policy": { - "globalFeatures": { - "features": [], - "requiresAll": false - }, - "features": { - "features": [], - "requiresAll": false - }, - "permissions": { - "permissionNames": [], - "requiresAll": false - } - }, - "attributes": [ - { - "typeSimple": "readOnly", - "config": { - "isReadOnly": true - } - } - ], - "configuration": { - "AllowUserToEdit": false - }, - "defaultValue": null - }, - "DisplayName": { - "type": "System.String", - "typeSimple": "string", - "displayName": null, - "api": { - "onGet": { - "isAvailable": true - }, - "onCreate": { - "isAvailable": true - }, - "onUpdate": { - "isAvailable": true - } - }, - "ui": { - "onTable": { - "isVisible": true - }, - "onCreateForm": { - "isVisible": true - }, - "onEditForm": { - "isVisible": true - }, - "lookup": { - "url": null, - "resultListPropertyName": null, - "displayPropertyName": null, - "valuePropertyName": null, - "filterParamName": null - } - }, - "policy": { - "globalFeatures": { - "features": [], - "requiresAll": false - }, - "features": { - "features": [], - "requiresAll": false - }, - "permissions": { - "permissionNames": [], - "requiresAll": false - } - }, - "attributes": [ - { - "typeSimple": "readOnly", - "config": { - "isReadOnly": true - } - } - ], - "configuration": { - "AllowUserToEdit": false - }, - "defaultValue": null - } - }, - "configuration": {} - } - }, - "configuration": {} - } - }, - "enums": {} - }, - "extraProperties": {} -}) - -abp.event.trigger('abp.configurationInitialized'); - -})(); \ No newline at end of file diff --git a/Submission_files/ApplicationLinks.js.download b/Submission_files/ApplicationLinks.js.download deleted file mode 100644 index 73a5ad2eda..0000000000 --- a/Submission_files/ApplicationLinks.js.download +++ /dev/null @@ -1,227 +0,0 @@ -$(function () { - - let suggestionsArray = []; - - - // Plugin Constructor - let LinksInput = function (opts) { - this.options = Object.assign(LinksInput.defaults, opts); - this.init(); - } - // Initialize the plugin - LinksInput.prototype.init = function (opts) { - this.options = opts ? Object.assign(this.options, opts) : this.options; - - if (this.initialized) - this.destroy(); - this.orignal_input = document.getElementById(this.options.selector); - - if (!this.orignal_input) { - console.error("links-input couldn't find an element with the specified ID"); - return this; - } - - this.arr = []; - - this.wrapper = document.createElement('div'); - this.input = document.createElement('input'); - init(this); - initEvents(this); - - this.initialized = true; - return this; - } - - - // Add Tags - LinksInput.prototype.addLink = function (linkData) { - let defaultClass = 'tags-common'; - let linkText, linkClass; - - if (typeof linkData === 'string') { - linkText = linkData; - linkClass = defaultClass; - - } else { - linkText = linkData.text || ''; - linkClass = linkData.class || defaultClass; - - } - - if (this.anyErrors(linkText)) - return; - - this.arr.push(linkText); - - let linkInput = this; - - let link = document.createElement('span'); - link.className = this.options.linkClass + ' ' + linkClass; - link.innerText = linkText; - - let closeIcon = document.createElement('a'); - closeIcon.innerHTML = '×'; - - // delete the link when icon is clicked - closeIcon.addEventListener('click', function (e) { - e.preventDefault(); - let link = this.parentNode; - - for (let i = 0; i < linkInput.wrapper.childNodes.length; i++) { - if (linkInput.wrapper.childNodes[i] == link) - linkInput.deleteLink(link, i); - } - }) - - link.appendChild(closeIcon); - this.wrapper.insertBefore(link, this.input); - this.orignal_input.value = JSON.stringify(this.arr); - - return this; - } - - // Delete Tags - LinksInput.prototype.deleteLink = function (link, i) { - link.remove(); - this.arr.splice(i, 1); - this.orignal_input.value = JSON.stringify(this.arr); - return this; - } - - // Make sure input string have no error with the plugin - LinksInput.prototype.anyErrors = function (string) { - if (!this.options.duplicate && this.arr.indexOf(string) != -1) { - console.log('duplicate found " ' + string + ' " ') - return true; - } - - return false; - } - - // Add links programmatically - LinksInput.prototype.addData = function (array) { - let plugin = this; - - array.forEach(function (string) { - plugin.addLink(string); - }) - return this; - } - - // Get the Input String - LinksInput.prototype.getInputString = function () { - return this.arr.join(','); - } - LinksInput.prototype.setSuggestions = function (sugArray) { - suggestionsArray = sugArray; - } - - - // destroy the plugin - LinksInput.prototype.destroy = function () { - this.orignal_input.removeAttribute('hidden'); - - delete this.orignal_input; - let self = this; - - Object.keys(this).forEach(function (key) { - if (self[key] instanceof HTMLElement) - self[key].remove(); - - if (key != 'options') - delete self[key]; - }); - - this.initialized = false; - } - - // Private function to initialize the link input plugin - function init(links) { - links.wrapper.append(links.input); - links.wrapper.classList.add(links.options.wrapperClass); - links.orignal_input.setAttribute('hidden', 'true'); - links.orignal_input.parentNode.insertBefore(links.wrapper, links.orignal_input); - links.input.addEventListener('input', function () { - const inputValue = links.input.value.trim().toLowerCase(); - - // Show suggestions only after the first character entry - if (inputValue.length > 0) { - const suggestions = suggestionsArray.filter(link => link.toLowerCase().includes(inputValue)); - - // Display suggestions below the input element - if (suggestions.length) { - displaySuggestions(links, suggestions); - } else { - removeSuggestions(links); - } - - } else { - // Remove suggestions if input is empty - removeSuggestions(links); - } - }); - } - - // Function to display auto-completion suggestions - function displaySuggestions(links, suggestions) { - // Remove previous suggestions - removeSuggestions(links); - - // Create suggestion container - const suggestionContainer = document.createElement('div'); - suggestionContainer.classList.add('links-suggestion-container'); - const suggestionTitleElement = document.createElement('div'); - suggestionTitleElement.className = 'links-suggestion-title'; - suggestionTitleElement.innerText = 'ALL APPLICATIONS'; - suggestionContainer.appendChild(suggestionTitleElement); - - // Add suggestions to the container - suggestions.forEach(suggestion => { - const suggestionElement = document.createElement('div'); - suggestionElement.className = 'links-suggestion-element'; - suggestionElement.innerText = suggestion; - - // Add click event to add suggestion as a new link - suggestionElement.addEventListener('click', function () { - links.addLink(suggestion); - removeSuggestions(links); - links.input.value = ""; - }); - - suggestionContainer.appendChild(suggestionElement); - }); - - // Append the suggestion container below the input - links.wrapper.appendChild(suggestionContainer); - } - - // Function to remove auto-completion suggestions - function removeSuggestions(links) { - const suggestionContainer = links.wrapper.querySelector('.links-suggestion-container'); - if (suggestionContainer) { - suggestionContainer.remove(); - } - } - - // initialize the Events - function initEvents(links) { - links.wrapper.addEventListener('click', function () { - links.input.focus(); - }); - } - - // Set All the Default Values - LinksInput.defaults = { - selector: '', - wrapperClass: 'tags-input-wrapper', - linkClass: 'tag', - max: null, - duplicate: false - } - - window.LinksInput = LinksInput; - - -}); - - diff --git a/Submission_files/ApplicationLocalizationScript b/Submission_files/ApplicationLocalizationScript deleted file mode 100644 index 0ded0602b4..0000000000 --- a/Submission_files/ApplicationLocalizationScript +++ /dev/null @@ -1,1418 +0,0 @@ -(function(){ - -$.extend(true, abp.localization, { - "resources": { - "Default": { - "texts": {}, - "baseResources": [] - }, - "AbpLocalization": { - "texts": { - "DisplayName:Abp.Localization.DefaultLanguage": "Default language", - "Description:Abp.Localization.DefaultLanguage": "The default language of the application." - }, - "baseResources": [] - }, - "AbpValidation": { - "texts": { - "'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.", - "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", - "{0} is not valid.": "{0} is not valid.", - "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", - "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", - "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", - "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", - "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", - "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", - "The field {0} must match the regular expression '{1}'.": "The field {0} does not match the requested format.", - "The {0} field is required.": "The {0} field is required.", - "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", - "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", - "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", - "The field {0} is invalid.": "The field {0} is invalid.", - "The value '{0}' is invalid.": "The value '{0}' is invalid.", - "The field {0} must be a number.": "The field {0} must be a number.", - "The field must be a number.": "The field must be a number.", - "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", - "ThisFieldIsNotValid.": "This field is not valid.", - "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", - "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", - "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthOf{0}": "This field must be at most '{0}' characters long.", - "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be at least '{0}' characters long.", - "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", - "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", - "ThisFieldMustBeGreaterThanOrEqual{0}": "This field must be greater than or equal to {0}.", - "ThisFieldMustBeLessOrEqual{0}": "This field must be less than or equal to {0}.", - "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", - "ThisFieldIsRequired.": "This field is required.", - "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be at most '{0}' characters long.", - "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be at least {1} and at most {0} characters long.", - "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", - "ThisFieldIsInvalid.": "This field is invalid." - }, - "baseResources": [] - }, - "AbpAuditLogging": { - "texts": { - "Permission:AuditLogging": "Audit logging", - "Permission:AuditLogs": "Audit logs", - "Menu:AuditLogging": "Audit logs", - "AuditLogs": "Audit logs", - "HttpStatus": "HTTP status", - "HttpMethod": "HTTP method", - "HttpMethodFilter": "HTTP method filter", - "HttpRequest": "HTTP Request", - "User": "User", - "UserNameFilter": "User filter", - "HasException": "Has exception", - "IpAddress": "IP address", - "Time": "Time", - "Date": "Date", - "Duration": "Duration", - "Detail": "Detail", - "Overall": "Overall", - "Actions": "Actions", - "ClientIpAddress": "Client IP Address", - "ClientName": "Client Name", - "BrowserInfo": "Browser Info", - "Url": "URL", - "UserName": "User name", - "TenantImpersonator": "Tenant Impersonator", - "UserImpersonator": "User Impersonator", - "UrlFilter": "URL filter", - "Exceptions": "Exceptions", - "Comments": "Comments", - "HttpStatusCode": "HTTP status code", - "HttpStatusCodeFilter": "HTTP status code filter", - "ServiceName": "Service", - "MethodName": "Method", - "CorrelationId": "Correlation Id", - "ApplicationName": "Application name", - "ExecutionDuration": "Duration", - "ExtraProperties": "Extra properties", - "MaxDuration": "Max. duration", - "MinDuration": "Min. duration", - "MinMaxDuration": "Duration (Min. - Max.)", - "{0}Milliseconds": "{0} milliseconds", - "ExecutionTime": "Time", - "Parameters": "Parameters", - "EntityTypeFullName": "Entity Type Full Name", - "Entity": "Entity", - "ChangeType": "Change type", - "ChangeTime": "Time", - "NewValue": "New value", - "OriginalValue": "Old value", - "PropertyName": "Property name", - "PropertyTypeFullName": "Property Type Full Name", - "Yes": "Yes", - "No": "No", - "Changes": "Changes", - "AverageExecutionDurationInLogsPerDay": "Average execution duration", - "AverageExecutionDurationInMilliseconds": "Average execution duration in milliseconds", - "ErrorRateInLogs": "Error rate in logs", - "Success": "Success", - "Fault": "Fault", - "NoChanges": "No change(s)", - "EntityChanges": "Entity changes", - "EntityId": "Entity Id", - "EntityChangeStartTime": "Min change date", - "EntityChangeEndTime": "Max change date", - "EntityHistory": "Entity history", - "DaysAgoTitle": "{0} {1}.", - "DaysAgoWithUserTitle": "{0} {1} by {2}.", - "MinutesAgo": "{0} minutes ago", - "HoursAgo": "{0} hours ago", - "DaysAgo": "{0} days ago", - "Created": "Created", - "Updated": "Updated", - "Deleted": "Deleted", - "ChangeHistory": "Change history", - "FullChangeHistory": "Full change history", - "ChangeDetails": "Change details", - "DurationMs": "Duration (ms)", - "StartDate": "Start date", - "EndDate": "End date", - "Feature:AuditLoggingGroup": "Audit logging", - "Feature:AuditLoggingEnable": "Enable audit logging page", - "Feature:AuditLoggingEnableDescription": "Enable audit logging page in the application.", - "Feature:AuditLoggingSettingManagementEnable": "Enable audit log setting management", - "Feature:AuditLoggingSettingManagementEnableDescription": "Enable the configuration of the audit log setting management within the application.", - "InvalidAuditLogDeletionSettings": "Invalid audit log deletion settings. If deletion is enable, the period should be greater than 0 days.", - "AuditLogSettingsGeneral": "General", - "AuditLogSettingsGlobal": "Global", - "DisplayName:IsPeriodicDeleterEnabled": "Enable clean up service system wide", - "Description:IsPeriodicDeleterEnabled": "If this option is disabled the periodic deleter won't work. Audit logs won't be deleted automatically.", - "DisplayName:GlobalIsExpiredDeleterEnabled": "Enable clean up service for all tenants and host", - "Description:GlobalIsExpiredDeleterEnabled": "If this option is enabled all the tenants and the host expired items will be deleted automatically unless it has a specific setting.", - "DisplayName:IsExpiredDeleterEnabled": "Enable clean up service", - "Description:IsExpiredDeleterEnabled": "If this option is enabled the expired items will be deleted automatically.", - "DisplayName:ExpiredDeleterPeriod": "Expired item deletion period", - "Description:ExpiredDeleterPeriod": "Set the number of days after which expired items will be automatically deleted.", - "ExpiredDeleterPeriodUnit": "day(s)", - "AuditLogsBeforeXWillBeDeleted": "Audit logs before {0} will be deleted.", - "TenantId": "Tenant Id", - "Permission:Export": "Export audit logs", - "ExportToExcel": "Export to Excel", - "Exporting": "Exporting", - "ExportCompleted": "Export completed successfully", - "ExportFailed": "Export failed", - "ThereWereNoRecordsToExport": "There were no records to export.", - "ExportJobQueued": "Export job has been queued for {0} records. You will receive an email when the export is completed.", - "ExportReady": "Export completed for {0} records and is ready for download.", - "FileName": "File name", - "TotalRecords": "Total records", - "ExcelFileAttachedMessage": "The Excel file is attached to this email.", - "EntityChangeExportCompletedSubject": "Entity change export completed", - "AuditLogExportCompletedSubject": "Audit log export completed", - "DownloadLinkExplanation": "You can download the file using the link below until {0} (UTC)", - "DownloadNow": "Download now", - "TryAgainMessage": "Please try again. If the problem persists, please contact support." - }, - "baseResources": [ - "AbpValidation" - ] - }, - "AbpTiming": { - "texts": { - "DisplayName:Abp.Timing.Timezone": "Timezone", - "Description:Abp.Timing.Timezone": "Application time zone" - }, - "baseResources": [] - }, - "AbpFeatureManagement": { - "texts": { - "Features": "Features", - "NoFeatureFoundMessage": "There isn't any available feature.", - "ManageHostFeatures": "Manage host features", - "ManageHostFeaturesText": "You can manage the host side features by clicking the following button.", - "Permission:FeatureManagement": "Feature management", - "Permission:FeatureManagement.ManageHostFeatures": "Manage host features", - "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0} feature value is not valid!", - "Menu:FeatureManagement": "Feature management", - "ResetToDefault": "Reset to default", - "ResetedToDefault": "Reseted to default", - "AreYouSure": "Are you sure?", - "AreYouSureToResetToDefault": "Are you sure to reset to default?" - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "AbpMultiTenancy": { - "texts": { - "TenantNotFoundMessage": "Tenant not found!", - "TenantNotFoundDetails": "There is no tenant with the tenant id or name: {0}", - "TenantNotActiveMessage": "Tenant is not active!", - "TenantNotActiveDetails": "The tenant is not active with the tenant id or name: {0}" - }, - "baseResources": [] - }, - "AbpFeature": { - "texts": { - "Volo.Feature:010001": "Feature is not enabled: {FeatureName}", - "Volo.Feature:010002": "Required features are not enabled. All of these features must be enabled: {FeatureNames}", - "Volo.Feature:010003": "Required features are not enabled. At least one of these features must be enabled: {FeatureNames}" - }, - "baseResources": [] - }, - "AbpIdentity": { - "texts": { - "Menu:IdentityManagement": "Identity management", - "Users": "Users", - "NewUser": "New user", - "UserName": "User name", - "Surname": "Surname", - "EmailAddress": "Email address", - "PhoneNumber": "Phone number", - "UserInformations": "User Information", - "DisplayName:IsDefault": "Default", - "DisplayName:IsStatic": "Static", - "DisplayName:IsPublic": "Public", - "Roles": "Roles", - "Password": "Password", - "PersonalInfo": "My profile", - "PersonalSettings": "Personal settings", - "UserDeletionConfirmationMessage": "User '{0}' will be deleted. Do you confirm that?", - "RoleDeletionConfirmationMessage": "Role '{0}' will be deleted. Do you confirm that?", - "DisplayName:RoleName": "Role name", - "DisplayName:UserName": "User name", - "DisplayName:Name": "Name", - "DisplayName:Surname": "Surname", - "DisplayName:Password": "Password", - "DisplayName:Email": "Email address", - "DisplayName:PhoneNumber": "Phone number", - "DisplayName:TwoFactorEnabled": "Two factor verification", - "DisplayName:IsActive": "Active", - "DisplayName:LockoutEnabled": "Account lockout", - "Description:LockoutEnabled": "Lock account after failed login attempts", - "NewRole": "New role", - "RoleName": "Role name", - "CreationTime": "Creation time", - "Permissions": "Permissions", - "DisplayName:CurrentPassword": "Current password", - "DisplayName:NewPassword": "New password", - "DisplayName:NewPasswordConfirm": "Confirm new password", - "PasswordChangedMessage": "Your password has been changed successfully.", - "PersonalSettingsSavedMessage": "Your personal settings has been saved successfully.", - "Volo.Abp.Identity:DefaultError": "An unknown failure has occurred.", - "Volo.Abp.Identity:ConcurrencyFailure": "Optimistic concurrency check has been failed. The entity you're working on has modified by another user. Please discard your changes and try again.", - "Volo.Abp.Identity:DuplicateEmail": "Email '{0}' is already taken.", - "Volo.Abp.Identity:DuplicateRoleName": "Role name '{0}' is already taken.", - "Volo.Abp.Identity:DuplicateUserName": "Username '{0}' is already taken.", - "Volo.Abp.Identity:InvalidEmail": "Email '{0}' is invalid.", - "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "The provided PasswordHasherCompatibilityMode is invalid.", - "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "The iteration count must be a positive integer.", - "Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.", - "Volo.Abp.Identity:InvalidToken": "Invalid token.", - "Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid.", - "Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.", - "Volo.Abp.Identity:PasswordMismatch": "Incorrect password.", - "Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').", - "Volo.Abp.Identity:PasswordRequiresLower": "Passwords must have at least one lowercase ('a'-'z').", - "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "Passwords must have at least one non alphanumeric character.", - "Volo.Abp.Identity:PasswordRequiresUpper": "Passwords must have at least one uppercase ('A'-'Z').", - "Volo.Abp.Identity:PasswordTooShort": "Passwords must be at least {0} characters.", - "Volo.Abp.Identity:PasswordRequiresUniqueChars": "Passwords must use at least {0} different characters.", - "Volo.Abp.Identity:PasswordInHistory": "Passwords must not match your last {0} passwords.", - "Volo.Abp.Identity:RoleNotFound": "Role {0} does not exist.", - "Volo.Abp.Identity:UserAlreadyHasPassword": "User already has a password set.", - "Volo.Abp.Identity:UserAlreadyInRole": "User already in role '{0}'.", - "Volo.Abp.Identity:UserLockedOut": "User is locked out.", - "Volo.Abp.Identity:UserLockoutNotEnabled": "Lockout is not enabled for this user.", - "Volo.Abp.Identity:UserNameNotFound": "User {0} does not exist.", - "Volo.Abp.Identity:UserNotInRole": "User is not in role '{0}'.", - "Volo.Abp.Identity:PasswordConfirmationFailed": "Password does not match the confirm password.", - "Volo.Abp.Identity:NullSecurityStamp": "User security stamp cannot be null.", - "Volo.Abp.Identity:RecoveryCodeRedemptionFailed": "Recovery code redemption failed.", - "Volo.Abp.Identity:010001": "You can not delete your own account!", - "Volo.Abp.Identity:010002": "Can not set more than {MaxUserMembershipCount} organization unit for a user!", - "Volo.Abp.Identity:010003": "Can not change password of an externally logged in user!", - "Volo.Abp.Identity:010004": "There is already an organization unit with name {0}. Two units with same name can not be created in same level.", - "Volo.Abp.Identity:010005": "Static roles can not be renamed.", - "Volo.Abp.Identity:010006": "Static roles can not be deleted.", - "Volo.Abp.Identity:010007": "You can't change your two factor setting.", - "Volo.Abp.Identity:010008": "It's not allowed to change two factor setting.", - "Volo.Abp.Identity:010009": "You can not delegate yourself.", - "Volo.Abp.Identity:010021": "Name exist: '{0}'.", - "Volo.Abp.Identity:010022": "Can not update a static ClaimType.", - "Volo.Abp.Identity:010023": "Can not delete a static ClaimType.", - "Identity.OrganizationUnit.MaxUserMembershipCount": "Maximum allowed organization unit membership count for a user", - "ThisUserIsNotActiveMessage": "This user is not active.", - "Permission:IdentityManagement": "Identity management", - "Permission:RoleManagement": "Role management", - "Permission:Create": "Create", - "Permission:Edit": "Edit", - "Permission:Delete": "Delete", - "Permission:ChangePermissions": "Change permissions", - "Permission:ManageRoles": "Manage roles", - "Permission:UserManagement": "User management", - "Permission:UserLookup": "User lookup", - "DisplayName:Abp.Identity.Password.RequiredLength": "Required length", - "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Required unique characters number", - "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Required non-alphanumeric character", - "DisplayName:Abp.Identity.Password.RequireLowercase": "Required lower case character", - "DisplayName:Abp.Identity.Password.RequireUppercase": "Required upper case character", - "DisplayName:Abp.Identity.Password.RequireDigit": "Required digit", - "DisplayName:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "Force users to periodically change password", - "DisplayName:Abp.Identity.Password.PasswordChangePeriodDays": "Password change period(days)", - "DisplayName:Abp.Identity.Password.EnablePreventPasswordReuse": "Enable prevent password reuse", - "DisplayName:Abp.Identity.Password.PreventPasswordReuseCount": "Prevent password reuse count", - "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "Enabled for new users", - "DisplayName:Abp.Identity.Lockout.LockoutDuration": "Lockout duration(seconds)", - "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Max failed access attempts", - "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "Enforce email verification to sign in", - "DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Allow users to confirm their phone number", - "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Enforce phone number verification to sign in", - "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "Allow users to change their usernames", - "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "Allow users to change their email addresses", - "Description:Abp.Identity.Password.RequiredLength": "The minimum length a password must be.", - "Description:Abp.Identity.Password.RequiredUniqueChars": "The minimum number of unique characters which a password must contain.", - "Description:Abp.Identity.Password.RequireNonAlphanumeric": "If passwords must contain a non-alphanumeric character.", - "Description:Abp.Identity.Password.RequireLowercase": "If passwords must contain a lower case ASCII character.", - "Description:Abp.Identity.Password.RequireUppercase": "If passwords must contain a upper case ASCII character.", - "Description:Abp.Identity.Password.RequireDigit": "If passwords must contain a digit.", - "Description:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "Whether users are forced to periodically change their password.", - "Description:Abp.Identity.Password.PasswordChangePeriodDays": "The number of days a user's password is valid for.", - "Description:Abp.Identity.Password.EnablePreventPasswordReuse": "Whether to prevent users from reusing their previous passwords.", - "Description:Abp.Identity.Password.PreventPasswordReuseCount": "The number of previous passwords that cannot be reused.", - "Description:Abp.Identity.Lockout.AllowedForNewUsers": "Whether a new user can be locked out.", - "Description:Abp.Identity.Lockout.LockoutDuration": "The duration a user is locked out for when a lockout occurs.", - "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "The number of failed access attempts allowed before a user is locked out, assuming lock out is enabled.", - "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "Users can create accounts but cannot sign in until they verify their email address.", - "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "Users can verify their phone numbers. SMS integration required.", - "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Users can create accounts but cannot sign in until they verify their phone numbers.", - "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Whether the username can be updated by the user.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Whether the email can be updated by the user.", - "DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Enforce email verification to register", - "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "User accounts will not be created unless they verify their email addresses.", - "Details": "Details", - "CreatedBy": "Created by", - "ModifiedBy": "Modified by", - "ModificationTime": "Modification time", - "PasswordUpdateTime": "Password update time", - "LockoutEndTime": "Lockout end time", - "FailedAccessCount": "Failed access count", - "UserResourcePermissionProviderKeyLookupService": "User", - "RoleResourcePermissionProviderKeyLookupService": "Role" - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "AbpOpenIddict": { - "texts": { - "TheOpenIDConnectRequestCannotBeRetrieved": "The OpenID Connect request cannot be retrieved.", - "TheUserDetailsCannotBbeRetrieved": "The user details cannot be retrieved.", - "TheApplicationDetailsCannotBeFound": "The application details cannot be found.", - "DetailsConcerningTheCallingClientApplicationCannotBeFound": "Details concerning the calling client application cannot be found.", - "TheSpecifiedGrantTypeIsNotImplemented": "The specified grant type {0} is not implemented.", - "Authorization": "Authorization", - "DoYouWantToGrantAccessToYourData": "Do you want to grant {0} access to your data?", - "ScopesRequested": "Scopes requested", - "Accept": "Accept", - "Deny": "Deny", - "ApplicationResourcePermissionProviderKeyLookupService": "Client" - }, - "baseResources": [ - "AbpValidation" - ] - }, - "AbpPermissionManagement": { - "texts": { - "Permissions": "Permissions", - "OnlyProviderPermissons": "Only this provider", - "All": "All", - "SelectAllInAllTabs": "Grant all permissions", - "SelectAllInThisTab": "Select all", - "SaveWithoutAnyPermissionsWarningMessage": "Are you sure you want to save without any permissions?", - "PermissionGroup": "Permission Group", - "Filter": "Filter", - "ResourcePermissions": "Permissions", - "ResourcePermissionTarget": "Target", - "ResourcePermissionPermissions": "Permissions", - "AddResourcePermission": "Add permission", - "ResourcePermissionDeletionConfirmationMessage": "Are you sure you want to delete all permissions?", - "UpdateResourcePermission": "Update permission", - "GrantAllResourcePermissions": "Grant all", - "NoResourceProviderKeyLookupServiceFound": "There is no provider key lookup service was found", - "NoResourcePermissionFound": "There is no permission defined.", - "UpdatePermission": "Update permission", - "NoPermissionsAssigned": "No permissions assigned", - "SelectProvider": "Select provider", - "SearchProviderKey": "Search provider key", - "Provider": "Provider", - "ErrorLoadingPermissions": "Error loading permissions", - "PleaseSelectProviderAndPermissions": "Please select provider and permissions" - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "AbpSettingManagement": { - "texts": { - "Settings": "Settings", - "SavedSuccessfully": "Saved successfully", - "Permission:SettingManagement": "Setting management", - "Permission:Emailing": "Emailing", - "Permission:EmailingTest": "Emailing test", - "Permission:TimeZone": "Time zone", - "SendTestEmail": "Send test email", - "SenderEmailAddress": "Sender email address", - "TargetEmailAddress": "Target email address", - "Subject": "Subject", - "Body": "Body", - "TestEmailSubject": "Test email {0}", - "TestEmailBody": "Test email body message here", - "SentSuccessfully": "Sent successfully", - "MailSendingFailed": "Mail sending failed, please check your email configuration and try again.", - "Send": "Send", - "Menu:Settings": "Settings", - "Menu:Emailing": "Emailing", - "Menu:TimeZone": "Time Zone", - "DisplayName:Timezone": "Time zone", - "TimezoneHelpText": "This feature allows you to set a default time zone for your server, while users can select their own. If a user's time zone differs from the server's, all times will adjust accordingly. For example, with the server set to Europe/London(00:00) and a user in Europe/Paris(+01:00), times will be adjusted by 1 hour for that user. Selecting 'Default Timezone' will automatically use the server's or browser's time zone.", - "DefaultTimeZone": "Default time zone", - "SmtpHost": "Host", - "SmtpPort": "Port", - "SmtpUserName": "User name", - "SmtpPassword": "Password", - "SmtpDomain": "Domain", - "SmtpEnableSsl": "Enable ssl", - "SmtpUseDefaultCredentials": "Use default credentials", - "DefaultFromAddress": "Default from address", - "DefaultFromDisplayName": "Default from display name", - "Feature:SettingManagementGroup": "Setting management", - "Feature:SettingManagementEnable": "Enable setting management", - "Feature:SettingManagementEnableDescription": "Enable setting management system in the application.", - "Feature:AllowChangingEmailSettings": "Allow changing email settings", - "Feature:AllowChangingEmailSettingsDescription": "Allow changing email settings.", - "SmtpPasswordPlaceholder": "Enter a value to update password" - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "AbpTenantManagement": { - "texts": { - "Volo.Abp.TenantManagement:DuplicateTenantName": "Tenant name already exist: {Name}", - "Menu:TenantManagement": "Tenant management", - "Tenants": "Tenants", - "NewTenant": "New tenant", - "TenantName": "Tenant name", - "DisplayName:TenantName": "Tenant Name", - "TenantDeletionConfirmationMessage": "Tenant '{0}' will be deleted. Do you confirm that?", - "ConnectionStrings": "Connection Strings", - "DisplayName:DefaultConnectionString": "Default Connection String", - "DisplayName:UseSharedDatabase": "Use the Shared Database", - "Permission:TenantManagement": "Tenant management", - "Permission:Create": "Create", - "Permission:Edit": "Edit", - "Permission:Delete": "Delete", - "Permission:ManageConnectionStrings": "Manage connection strings", - "Permission:ManageFeatures": "Features", - "DisplayName:AdminEmailAddress": "Admin Email Address", - "DisplayName:AdminPassword": "Admin Password" - }, - "baseResources": [ - "AbpValidation", - "AbpFeatureManagement", - "AbpUi" - ] - }, - "Notifications": { - "texts": { - "MyAccount": "My account", - "SamplePageMessage": "A sample page for the Notifications module", - "Permission:NotificationsPermissions.Settings": "Configure Notifications", - "Setting:Notifications": "Notifications", - "Setting:Notifications.Mailing.DefaultFromAddress.DisplayName": "From Address", - "Setting:Notifications.Mailing.DefaultFromAddress.Description": "The default From sender address", - "Permission:Notifications": "Notifications", - "Permission:Notifications.Email": "Email", - "Permission:Notifications.Email.Send": "Send Email" - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "Flex": { - "texts": { - "MyAccount": "My account", - "SamplePageMessage": "A sample page for the Flex module", - "Scoresheet:Configuration:ScoresheetModal.Title": "Title", - "Scoresheet:Configuration:SectionModal.Name": "Name", - "Scoresheet:Configuration:QuestionModal.Name": "Name", - "Scoresheet:Configuration:QuestionModal.Label": "Question", - "Scoresheet:Configuration:QuestionModal.Description": "Description", - "Scoresheet:Configuration:QuestionModal.QuestionType": "Question Type", - "Scoresheet:Configuration:AddScoresheetButtonText": "ADD SCORESHEET", - "Scoresheet:Configuration:AddQuestionButtonText": "ADD QUESTION", - "Scoresheet:Configuration:AddSectionButtonText": "ADD SECTION", - "Scoresheet:Configuration:EditScoresheetButtonText": "EDIT SCORESHEET", - "Scoresheet:Configuration:CloneScoresheetButtonText": "CLONE SCORESHEET", - "Scoresheet:Configuration:PublishScoresheetButtonText": "PUBLISH SCORESHEET", - "Scoresheet:Configuration:ExportScoresheetButtonText": "EXPORT SCORESHEET", - "Scoresheet:Configuration:SaveChangesButtonText": "SAVE CHANGES", - "Scoresheet:Configuration:DiscardChangesButtonText": "DISCARD CHANGES", - "Worksheet:Configuration:SaveChangesButtonText": "SAVE CHANGES", - "Worksheet:Configuration:DiscardChangesButtonText": "DISCARD CHANGES", - "Worksheet:Configuration:EditWorksheetButtonText": "Edit", - "Worksheet:Configuration:AddCustomFieldButtonText": "Add Field", - "Worksheet:Configuration:AddSectionButtonText": "ADD SECTION", - "Worksheet:Configuration:AddWorksheetButtonText": "ADD", - "Worksheet:Configuration:LinkWorksheetButtonText": "Link", - "Worksheet:Configuration:CloneWorksheetButtonText": "Clone", - "Worksheet:Configuration:PublishWorksheetButtonText": "Publish", - "Worksheet:Configuration:DeleteWorksheetButtonText": "Delete", - "Worksheet:Configuration:AddCheckboxOptionText": "Add Option", - "Worksheet:Configuration:ExportWorksheetButtonText": "Export", - "Worksheet:Configuration:AddSelectListOptionText": "Add Option", - "Worksheet:Configuration:AddColumnOptionText": "Add Column", - "DataGrids:DynamicColumnsHeader": "Dynamic Columns", - "DataGrids:CustomColumnsHeader": "Custom Columns", - "DataGrids:PredefinedColumn": "Predefined column", - "Permission:Flex.Worksheets": "Configure Worksheet", - "Permission:Flex.Worksheets.Delete": "Delete Worksheet" - }, - "baseResources": [ - "AbpValidation" - ] - }, - "Payments": { - "texts": { - "Payments": "Payments", - "WelcomeToPayments": "Welcome to Payments Module", - "Unity.Payments:Errors:ThresholdExceeded": "There are payments in this batch that require a third level of approval. Please remove them from this batch and add to another for the appropriate level of approval", - "Unity.Payments:Errors:ZeroPayment": "Cannot submit a payment request for $0.00", - "Unity.Payments:Errors:MissingSupplierNumber": "Cannot submit a payment request without a supplier number", - "Unity.Payments:Errors:ConfigurationExists": "Configuration already exitst", - "Unity.Payments:Errors:ConfigurationDoesNotExist": "Configuration does not exits", - "Unity.Payments:Errors:InvalidAccountCodingFiled": "Invalid account coding field {field} : {length}", - "Unity.Payments:Errors:L2ApproverRestriction": "You cannot approve one or more selected payments as you have already approved them as an L1 Approver.", - "Setting:Payments.ThresholdAmount.DisplayName": "Payment threshold amount", - "Setting:Payments.ThresholdAmount.Description": "Payment threshold that triggers additional approvals and checks", - "ApplicationPaymentRequest:Title": "Request Payment", - "ApplicationPaymentRequest:Amount": "Amount", - "ApplicationPaymentRequest:Description": "Description", - "ApplicationPaymentRequest:SiteName": "Site Name", - "ApplicationPaymentRequest:InvoiceNumber": "Invoice #", - "ApplicationPaymentRequest:SiteNumber": "Site #", - "ApplicationPaymentRequest:SubmitButtonText": "Submit Payment Requests", - "ApplicationPaymentRequest:CancelButtonText": "Cancel", - "ApplicationPaymentRequest:BatchNumberName": "Batch #", - "ApplicationPaymentRequest:NumberPayment": "Number of Payments", - "ApplicationPaymentRequest:TotalAmount": "Total Amount", - "ApplicationPaymentRequest:AccountCodingOverride": "Account Coding Override", - "ApplicationPaymentRequest:AccountCodingOverrideWarning": "An overridden account code is being used for this payment request.", - "ApplicationPaymentRequest:BatchNote": "Note", - "ApplicationPaymentRequest:Validations:RemainingAmountExceeded": "Cannot add a payment that exceeds the remaining amount of ", - "ApplicationPaymentRequest:Validations:L2ApproverRestriction": "You cannot approve this payment as you have already approved it as an L1 Approver.", - "ApplicationPaymentRequest:Validations:L2ApproverRestrictionBatch": "Highlighted payments were already approved with L1 permission. L1 and L2 approvers must be different individuals", - "ApplicationPaymentTable:BatchNumber": "Batch Number", - "ApplicationPaymentTable:TotalAmount": "Total Amount", - "ApplicationPaymentTable:Status": "Status", - "ApplicationPaymentTable:RequestedOn": "Requested On", - "ApplicationPaymentListTable:SubmissionConfirmationCode": "Submission #", - "ApplicationPaymentListTable:PaymentRequesterName": "Payment Requester", - "ApplicationPaymentListTable:L1ApproverName": "L1 Approver", - "ApplicationPaymentListTable:L2ApproverName": "L2 Approver", - "ApplicationPaymentListTable:L3ApproverName": "L3 Approver", - "ApplicationPaymentListTable:L1ApprovalDate": "L1 Approval Date", - "ApplicationPaymentListTable:L2ApprovalDate": "L2 Approval Date", - "ApplicationPaymentListTable:L3ApprovalDate": "L3 Approval Date", - "ApplicationPaymentListTable:BatchName": "Batch #", - "ApplicationPaymentListTable:PaymentID": "Payment ID", - "ApplicationPaymentListTable:ApplicantName": "Applicant Name", - "ApplicationPaymentListTable:SupplierNumber": "Supplier Number", - "ApplicationPaymentListTable:SiteNumber": "Site Number", - "ApplicationPaymentListTable:ContractNumber": "Contract Number", - "ApplicationPaymentListTable:InvoiceNumber": "Invoice Number", - "ApplicationPaymentListTable:PayGroup": "Pay Group", - "ApplicationPaymentListTable:Amount": "Amount", - "ApplicationPaymentListTable:Status": "Status", - "ApplicationPaymentListTable:Description": "Description", - "ApplicationPaymentListTable:RequestedOn": "Requested On", - "ApplicationPaymentListTable:UpdatedOn": "Updated On", - "ApplicationPaymentListTable:PaidOn": "Paid On", - "ApplicationPaymentListTable:CASResponse": "CAS Response", - "ApplicationPaymentListTable:InvoiceStatus": "Invoice Status", - "ApplicationPaymentListTable:PaymentStatus": "CAS Payment Status", - "ApplicationPaymentListTable:Note": "Note", - "ApplicationPaymentListTable:FsbApNotified": "FSB-AP Notified", - "ApplicantInfoView:SupplierInfoTitle": "Supplier Info", - "ApplicantInfoView:ApplicantInfo:SupplierNumber": "Supplier #", - "ApplicantInfoView:ApplicantInfo.SiteInfo:SiteNumber": "Site #", - "ApplicantInfoView:ApplicantInfo.SiteInfo:PayGroup": "Pay Group", - "ApplicantInfoView:ApplicantInfo.SiteInfo:MailingAddress": "Mailing Address", - "ApplicantInfoView:ApplicantInfo.SiteInfo:AddSiteButtonText": "ADD SITE", - "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine1": "Address Line 1", - "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine2": "Address Line 2", - "ApplicantInfoView:ApplicantInfo.SiteInfo:AddressLine3": "Address Line 3", - "ApplicantInfoView:ApplicantInfo.SiteInfo:City": "City", - "ApplicantInfoView:ApplicantInfo.SiteInfo:Province": "Province", - "ApplicantInfoView:ApplicantInfo.SiteInfo:PostalCode": "Postal Code", - "ApplicantInfoView:ApplicantInfo.Search": "Search In BC Registries (Registered Socities Only)", - "PaymentInfoView:PaymentInfoTitle": "Payment Summary", - "PaymentInfoView:PaymentInfo.RequestedAmount": "Requested Amount", - "PaymentInfoView:PaymentInfo.RecommendedAmount": "Recommended Amount", - "PaymentInfoView:PaymentInfo.ApprovedAmount": "Approved Amount", - "PaymentInfoView:PaymentInfo.TotalPendingAmounts": "Total Pending Amounts", - "PaymentInfoView:PaymentInfo.TotalPaid": "Total Paid", - "PaymentInfoView:PaymentInfo.RemainingAmount": "Remaining Amount", - "PaymentInfoView:PaymentInfoTableTitle": "Payment List", - "PaymentInfoView:ApplicationPaymentListTable.PaymentID": "Payment ID", - "PaymentInfoView:ApplicationPaymentListTable.Amount": "Amount", - "PaymentInfoView:ApplicationPaymentListTable.Status": "Status", - "PaymentInfoView:ApplicationPaymentListTable.Description": "Description", - "PaymentInfoView:ApplicationPaymentListTable.MailingAddress": "Mailing Address", - "PaymentInfoView:ApplicationPaymentListTable.MaskedBankAccount": "Bank Account", - "PaymentInfoView:ApplicationPaymentListTable.SiteNumber": "Site Number", - "PaymentInfoView:ApplicationPaymentListTable.SupplierNumber": "Supplier Number", - "PaymentInfoView:ApplicationPaymentListTable.SupplierName": "Supplier Name", - "PaymentInfoView:ApplicationPaymentListTable.RequestedOn": "Requested On", - "PaymentInfoView:ApplicationPaymentListTable.UpdatedOn": "Updated On", - "PaymentInfoView:ApplicationPaymentListTable.PaidOn": "Paid On", - "PaymentInfoView:ApplicationPaymentListTable.CASResponse": "CAS Response", - "ApplicationPaymentStatusRequest:ApproveTitle": "Approve Payments", - "ApplicationPaymentStatusRequest:DeclineTitle": "Decline Payments", - "ApplicationPaymentStatusRequest:Id": "Payment Id", - "ApplicationPaymentStatusRequest:Amount": "Amount", - "ApplicationPaymentStatusRequest:Description": "Description", - "ApplicationPaymentStatusRequest:CancelButtonText": "Cancel", - "ApplicationPaymentStatusRequest:ApproveButtonText": "Approve Payments", - "ApplicationPaymentStatusRequest:DeclineButtonText": "Decline Payments", - "ApplicationPaymentStatusRequest:L1ApproveOrDeclineTitle": "Approve/Decline L1 Payment Requests", - "ApplicationPaymentStatusRequest:L2ApproveOrDeclineTitle": "Approve/Decline L2 Payment Requests", - "ApplicationPaymentStatusRequest:L3ApproveOrDeclineTitle": "Approve/Decline L3 Payment Requests", - "Permission:Payments": "Payments", - "Permission:Payments.Default": "Payments", - "Permission:Payments.L1ApproveOrDecline": "Approve/Decline L1 Payments", - "Permission:Payments.L2ApproveOrDecline": "Approve/Decline L2 Payments", - "Permission:Payments.L3ApproveOrDecline": "Approve/Decline L3 Payments", - "Permission:Payments.RequestPayment": "Request Payment", - "Permission:Payments.AccountCodingOverride": "Override Account Coding", - "Permission:Payments.EditFormPaymentConfiguration": "Edit Form Payment Configuration", - "Enum:PaymentRequestStatus.L1Pending": "L1 Pending", - "Enum:PaymentRequestStatus.L1Approved": "L1 Approved", - "Enum:PaymentRequestStatus.L1Declined": "L1 Declined", - "Enum:PaymentRequestStatus.L2Pending": "L2 Pending", - "Enum:PaymentRequestStatus.L2Approved": "L2 Approved", - "Enum:PaymentRequestStatus.L2Declined": "L2 Declined", - "Enum:PaymentRequestStatus.L3Pending": "L3 Pending", - "Enum:PaymentRequestStatus.L3Approved": "L3 Approved", - "Enum:PaymentRequestStatus.L3Declined": "L3 Declined", - "Enum:PaymentRequestStatus.Submitted": "Submitted to CAS", - "Enum:PaymentRequestStatus.FSB": "Sent to Accounts Payable", - "Enum:PaymentRequestStatus.Validated": "Validated", - "Enum:PaymentRequestStatus.NotValidated": "Not Validated", - "Enum:PaymentRequestStatus.Paid": "Paid", - "Enum:PaymentRequestStatus.Failed": "Payment Failed", - "Enum:PaymentRequestStatus.PaymentFailed": "Payment Failed", - "Unity.GrantManager.ApplicationManagement.Payment": "Payment Info", - "Unity.GrantManager.ApplicationManagement.Payment.Summary": "Payment Summary", - "Unity.GrantManager.ApplicationManagement.Payment.Supplier": "Supplier Info", - "Unity.GrantManager.ApplicationManagement.Payment.Supplier.Update": "Edit Supplier Info", - "Unity.GrantManager.ApplicationManagement.Payment.PaymentList": "Payment List", - "Unity.Payments.Tags.Create": "Assign Tag to Payments", - "Unity.Payments.Tags.Delete": "Remove Tag from Payments" - }, - "baseResources": [ - "AbpValidation" - ] - }, - "Reporting": { - "texts": { - "Permission:Reporting": "Reporting", - "Permission:Reporting.Configuration.Default": "Reporting Configurations - Default (View)", - "Permission:Reporting.Configuration.Update": "Update Reporting Configurations", - "Permission:Reporting.Configuration.Delete": "Delete Reporting Configurations", - "Setting:GrantManager.Reporting.ViewRole.DisplayName": "[DEPRECATED] Global View Role", - "Setting:GrantManager.Reporting.ViewRole.Description": "[DEPRECATED] This global setting is deprecated. Use tenant-specific view role configuration instead.", - "Setting:GrantManager.Reporting.TenantViewRole.DisplayName": "Tenant View Role", - "Setting:GrantManager.Reporting.TenantViewRole.Description": "The database role to assign to generated reporting views for this specific tenant" - }, - "baseResources": [ - "AbpValidation" - ] - }, - "GrantManager": { - "texts": { - "Menu:Home": "Home", - "Menu:Dashboard": "Dashboard", - "Menu:GrantPrograms": "Grant Programs", - "Menu:GrantTracker": "Grant Tracker", - "Menu:Applications": "Applications", - "Menu:Payments": "Payments", - "Menu:Scoring": "Scoring", - "Menu:Reporting": "Reporting", - "Menu:Welcome": "Welcome", - "Menu:Roles": "Roles", - "Menu:Users": "Users", - "Menu:Intakes": "Intakes", - "Menu:ApplicationForms": "Forms", - "Menu:TenantManagement": "Tenants", - "Menu:EndpointManagement": "Endpoints", - "Menu:Applicants": "Applicants", - "Menu:ConfigurationManagement": "Configuration Management", - "Welcome": "Welcome", - "LongWelcomeMessage": "Welcome to Unity Grant Manager", - "Enum:GrantProgramType.0": "Undefined", - "Enum:GrantProgramType.1": "Agriculture", - "Enum:GrantProgramType.2": "Arts, Culture and Sport", - "Enum:GrantProgramType.3": "Business", - "Enum:GrantProgramType.4": "Environment", - "Enum:GrantProgramType.5": "Research", - "Enum:GrantProgramType.6": "Jobs & Training", - "Common:Command:Edit": "Edit", - "Common:Command:Create": "Create", - "Common:Command:Update": "Update", - "Common:StartDate": "Start Date", - "Common:EndDate": "End Date", - "Common:Name": "Name", - "Common:Description": "Description", - "Common:Command:Search": "Search", - "Common:Command:Import": "Import", - "Common:Command:Select": "Select", - "GrantPrograms": "Grant Programs", - "GrantProgram": "Grant Program", - "GrantProgramType": "Sector", - "ProgramName": "Program Name", - "PublishDate": "Published", - "CreateDate": "Created", - "Sector": "Sector", - "GrantProgram_Create": "New Grant Program", - "GrantProgram_Update": "Edit Grant Program", - "Enum:GrantApplicationStatus.0": "Active", - "Enum:GrantApplicationStatus.1": "Scoring", - "Enum:GrantApplicationStatus.2": "Awaiting", - "Enum:GrantApplicationStatus.3": "On Hold", - "Enum:GrantApplicationStatus.4": "Approved", - "Enum:GrantApplicationStatus.5": "Assessing", - "Enum:GrantApplicationStatus.6": "Declined", - "ProjectName": "Project Name", - "ReferenceNo": "Reference No", - "EligibleAmount": "Eligible Amount", - "RequestedAmount": "Requested Amount", - "Assignee": "Assignee", - "Probability": "Probability", - "GrantApplicationStatus": "Status", - "ProposalDate": "Proposal Date", - "SubmissionDate": "Submission Date", - "GrantApplications": "Grant Applications", - "Applicants": "Applicants", - "Multiple": "Multiple", - "ApplicationList:OpenButton": "Open", - "ApplicationList:AssignButton": "Assign", - "ApplicationList:ApproveButton": "Approve", - "ApplicationList:StatusButton": "Status", - "ApplicationList:ApprovedButton": "Approved", - "ApplicationList:NotApprovedButton": "Not approved", - "ApplicationList:CopyLinkButton": "Copy link", - "ApplicationList:DownloadButton": "Download", - "ApplicationList:AddReviewButton": "Add Review", - "ApplicationList:FilterButton": "Filter", - "ApplicationList:SortButton": "Sort", - "ApplicationList:InfoButton": "Info", - "ApplicationList:StartAssessmentButton": "Start Assessment", - "ApplicationList:CompleteAssessmentButton": "Complete Assessment", - "ApplicationList:TagButton": "Tags", - "ApplicationList:ResyncSubmissionAttachmentsButton": "Resync", - "ApplicationList:ManageTagButton": "Manage Tags", - "ReviewerList:AssessorName": "Assessor Name", - "ReviewerList:StartDate": "Start Date", - "ReviewerList:EndDate": "End Date", - "ReviewerList:Status": "Status", - "ReviewerList:Recommended": "Recommendation", - "ReviewerList:FinancialAnalysis": "Financial Analysis", - "ReviewerList:EconomicImpact": "Economic Impact", - "ReviewerList:InclusiveGrowth": "Inclusive Growth", - "ReviewerList:CleanGrowth": "Clean Growth", - "ReviewerList:Subtotal": "Subtotal", - "ReviewerList:CloneAssessment": "Clone Assessment", - "AssessmentResultAttachments:Id": "#", - "AssessmentResultAttachments:DocumentName": "Document Name", - "AssessmentResultAttachments:UploadedDate": "Date", - "AssessmentResultAttachments:AttachedBy": "Attached by", - "ChefsAttachments:Title": "Submission Attachments", - "ChefsAttachments:Filter": "Filter", - "ChefsAttachments:Download": "Download", - "ChefsAttachments:GenerateSummaries": "Generate AI Summaries", - "ChefsAttachments:GenerateSummary": "Generate Summary", - "ChefsAttachments:HideAISummaries": "Hide AI Summaries", - "ChefsAttachments:ShowAISummaries": "Show AI Summaries", - "ChefsAttachments:HideSummaries": "Hide Summaries", - "ChefsAttachments:ShowSummaries": "Show Summaries", - "ChefsAttachments:NoSummariesAvailable": "No summaries available", - "Enum:AssessmentState.IN_PROGRESS": "In Progress", - "Enum:AssessmentState.IN_REVIEW": "Under Review by Team Lead", - "Enum:AssessmentState.COMPLETED": "Completed", - "Enum:AssessmentAction.Create": "Create Assessment", - "Enum:AssessmentAction.SendBack": "Send Back", - "Enum:AssessmentAction.Complete": "Complete Assessment", - "Permission:GrantManagerManagement": "Grant Manager Management", - "Permission:GrantManagerManagement.Default": "Default", - "Permission:GrantApplicationManagement": "Grant Application Management", - "Permission:GrantApplicationManagement.Dashboard.Default": "Dashboard", - "Permission:GrantApplicationManagement.Dashboard.ViewDashboard": "View Dashboard", - "Permission:GrantApplicationManagement.Dashboard.ApplicationStatusCount": "View Submissions by Status", - "Permission:GrantApplicationManagement.Dashboard.EconomicRegionCount": "View Submissions by Economic Region", - "Permission:GrantApplicationManagement.Dashboard.ApplicationTagsCount": "View Application Tags Overview", - "Permission:GrantApplicationManagement.Dashboard.ApplicationAssigneeCount": "View Application Assignee Overview", - "Permission:GrantApplicationManagement.Dashboard.RequestedAmountPerSubsector": "View Total Funding Requested per Sub-Sector", - "Permission:GrantApplicationManagement.Dashboard.RequestApprovedCount": "View Requested vs. Approved Funding", - "Permission:GrantApplicationManagement.Applications.Default": "Applications", - "Permission:GrantApplicationManagement.Applicants.Default": "Applicants", - "Permission:GrantApplicationManagement.Applicants.Edit": "Edit Applicant", - "Permission:GrantApplicationManagement.Applicants.ViewList": "View Applicant List", - "Permission:GrantApplicationManagement.Applicants.AssignApplicant": "Assign Applicant to an Application", - "Permission:GrantApplicationManagement.Applicants.ApplicantInfo": "Applicant Info", - "Permission:GrantApplicationManagement.Applicants.ApplicantInfo.EditRedStop": "Edit Red-Stop", - "Permission:GrantApplicationManagement.Assignments.Default": "Assignment", - "Permission:GrantApplicationManagement.Assignments.AssignInitial": "Initial Assignment", - "Permission:GrantApplicationManagement.Reviews.Default": "Reviews", - "Permission:GrantApplicationManagement.Reviews.StartInitial": "Start Initial Review", - "Permission:GrantApplicationManagement.Reviews.CompleteInitial": "Complete Initial Review", - "Permission:GrantApplicationManagement.Assessments.Default": "Assessments", - "Permission:GrantApplicationManagement.Assessments.Start": "Start Assessment", - "Permission:GrantApplicationManagement.Assessments.Complete": "Complete Assessment", - "Permission:GrantApplicationManagement.Approvals.Default": "Approvals", - "Permission:GrantApplicationManagement.Approvals.Complete": "Complete Approval", - "Permission:GrantApplicationManagement.Approvals.DeferAfterApproval": "Defer After Approval", - "Permission:GrantApplicationManagement.Comments.Default": "Comments", - "Permission:GrantApplicationManagement.Comments.Add": "Add Application Comment", - "Permission:GrantApplicationManagement.Organizations.Default": "Organizations", - "Permission:GrantApplicationManagement.Organizations.ManageProfiles": "Manage Organization Profiles", - "Permission:GrantManagerManagement.Intakes.Default": "Manage Intakes", - "Permission:GrantManagerManagement.ApplicationForms.Default": "Manage Forms", - "Permission:GrantApplicationManagement.Approvals.BulkApplicationApproval": "Bulk Application Approval", - "Permission:GrantApplicationManagement.AIReporting.Default": "AI Reporting", - "ApplicationForms": "Forms", - "ApplicationForms:Description": "Description", - "ApplicationForms:ChefsFormId": "CHEFS Form Id", - "ApplicationForms:SubmissionHeaderMapping": "Mapping", - "ApplicationForms:ChefsFormVersionGuid": "CHEFS Form Version", - "ApplicationForms:ChefsCriteriaFormId": "CHEFS Criteria Form Id", - "ApplicationForms:ChefsFormApiKey": "CHEFS Form Api Key", - "ApplicationForms:Category": "Category", - "ApplicationForms:FormApiToken": "API Token", - "ApplicationForms:Mapping": "Mapping", - "ApplicationForms:APIConfiguration": "API Configuration", - "ApplicationForms:DownloadAPIConfiguration": "Download API Configuration", - "ApplicationForms:UpdateAPIToken": "Update API Token", - "ApplicationForms:Payable": "Payable", - "ApplicationForms:RenderFormIoToHtml": "Render FormIO to HTML", - "ApplicationForms:ConfigureWorksheets": "Configure Worksheets", - "ApplicationForms.Configuration.Notes:BypassAssessmentWorkflow": "Enabling this feature will bypass the Assessment workflow when you approve submissions associated with this form.", - "ApplicationForms.Configuration.Notes:SelectedApplicantElectoralAddress": "The selected address type will determine which submitted applicant address is used to extract the electoral district.", - "ApplicationForms.Configuration.Warnings:ApplicantElectoralAddressTypeChange": "Changing the address type will only affect new submissions. Existing applications will retain the electoral district extracted from their original address type.", - "Intakes": "Intakes", - "Unity.GrantManager.ApplicationManagement.Review.Approval": "Approval", - "Unity.GrantManager.ApplicationManagement.Review.Approval.Update": "Edit Approval Fields", - "Unity.GrantManager.ApplicationManagement.Review.Approval.Update.UpdateFinalStateFields": "Edit Approval fields after approval", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults": "Application Assessment Results", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults.Update": "Edit Application Assessment Result", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentResults.Update.UpdateFinalStateFields": "Edit Application Assessment Result after approval", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList": "Assessment List", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Create": "Create Assessment", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Update.SendBack": "Send Back Assessment", - "Unity.GrantManager.ApplicationManagement.Review.AssessmentReviewList.Update.Complete": "Complete Assessment", - "Unity.GrantManager.ApplicationManagement.Review.Worksheet": "Review and Assessment Worksheet", - "Unity.GrantManager.ApplicationManagement.Review.Worksheet.Update": "Edit Review and Assessment Worksheet", - "Unity.GrantManager.ApplicationManagement.Review": "Review and Assessment", - "Unity.GrantManager.ApplicationManagement.Review.Results": "Application Assessment Results", - "Unity.GrantManager.ApplicationManagement.Review.Results.Update": "Edit Application Assessment Results", - "Unity.GrantManager.ApplicationManagement.Review.ReviewList": "Assessment List", - "Unity.GrantManager.ApplicationManagement.Project": "Project Info", - "Unity.GrantManager.ApplicationManagement.Project.Summary": "Project Summary", - "Unity.GrantManager.ApplicationManagement.Project.Summary.Update": "Edit Project Summary", - "Unity.GrantManager.ApplicationManagement.Project.Summary.Update.UpdateFinalStateFields": "Edit Project Summary after approval", - "Unity.GrantManager.ApplicationManagement.Project.Location": "Project Location", - "Unity.GrantManager.ApplicationManagement.Project.Location.Update": "Edit Project Location", - "Unity.GrantManager.ApplicationManagement.Project.Location.Update.UpdateFinalStateFields": "Edit Project Location after approval", - "Unity.GrantManager.ApplicationManagement.Applicant": "Applicant Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Summary": "Applicant Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Summary.Update": "Edit Applicant Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Contact": "Contact Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Contact.Create": "Create Contact Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Contact.Update": "Edit Contact Info", - "Unity.GrantManager.ApplicationManagement.Applicant.Authority": "Signing Authority", - "Unity.GrantManager.ApplicationManagement.Applicant.Authority.Update": "Edit Signing Authority", - "Unity.GrantManager.ApplicationManagement.Applicant.Location": "Address", - "Unity.GrantManager.ApplicationManagement.Applicant.Location.Update": "Edit Address", - "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact": "Additional Contact(s)", - "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact.Create": "Add Additional Contact(s)", - "Unity.GrantManager.ApplicationManagement.Applicant.AdditionalContact.Update": "Edit Additional Contact(s)", - "Unity.GrantManager.ApplicationManagement.Funding": "Funding", - "Unity.GrantManager.ApplicationManagement.Funding.Agreement": "Funding Agreement", - "Unity.GrantManager.ApplicationManagement.Funding.Agreement.Update": "Edit Funding Agreement", - "Unity.GrantManager.ApplicationManagement.Payment": "Payment Info", - "Unity.GrantManager.ApplicationManagement.Payment.Summary": "Payment Summary", - "Unity.GrantManager.ApplicationManagement.Payment.Supplier": "Supplier Info", - "Unity.GrantManager.ApplicationManagement.Payment.Supplier.Update": "Edit Supplier Info", - "Unity.GrantManager.ApplicationManagement.Payment.PaymentList": "Payment List", - "Permission:GrantApplicationManagement.ProjectInfo": "Project Info", - "Permission:GrantApplicationManagement.ProjectInfo.Update": "Project Info Update", - "Permission:GrantApplicationManagement.ProjectInfo.Update.UpdateFinalStateFields": "Edit Project Info Fields After Approval", - "Unity.GrantManager.SettingManagement.Tags": "Manage Tags", - "Unity.GrantManager.SettingManagement.Tags.Create": "Create Tag", - "Unity.GrantManager.SettingManagement.Tags.Update": "Edit Tag", - "Unity.GrantManager.SettingManagement.Tags.Delete": "Delete Tag", - "Permission:Tags": "Tags", - "Unity.Applications.Tags.Create": "Assign Tag to Applications", - "Unity.Applications.Tags.Delete": "Remove Tag from Applications", - "GrantManager:AssessmentUserAssignmentAlreadyExists": "Business Exception: You cannot create two assessments on an application for the same user.", - "GrantManager:CantCreateAssessmentForFinalStateApplication": "Business Exception: You cannot create an assessment for an application in final state.", - "GrantManager:PayableFormRequiresHierarchy": "Please select a form hierarchy before saving a payable form.", - "GrantManager:ChildFormRequiresParentForm": "Please select a parent form when the form hierarchy is set to Child.", - "GrantManager:ChildFormCannotReferenceSelf": "A form cannot reference itself as the parent.", - "GrantManager:CannotModifyAiAssessment": "AI assessments are read-only.", - "GrantManager:CannotCloneNonAiAssessment": "Only AI assessments can be cloned.", - "AssessmentResultsView:ApprovalTitle": "Approval", - "AssessmentResultsView:AssessmentResultsTitle": "Application Assessment Results", - "AssessmentResultsView:AssessmentResultsForm.ProjectSummary": "Project Summary", - "AssessmentResultsView:AssessmentResultsForm.RequestedAmount": "Requested Amount", - "AssessmentResultsView:AssessmentResultsForm.TotalProjectBudget": "Total Project Budget", - "AssessmentResultsView:AssessmentResultsForm.RecommendedAmount": "Recommended Amount", - "AssessmentResultsView:AssessmentResultsForm.ApprovedAmount": "Approved Amount", - "AssessmentResultsView:AssessmentResultsForm.LikelihoodOfFunding": "Likelihood of Funding", - "AssessmentResultsView:AssessmentResultsForm.DueDiligenceStatus": "Due Diligence Status", - "AssessmentResultsView:AssessmentResultsForm.SubStatus": "Sub-Status", - "AssessmentResultsView:AssessmentResultsForm.DeclineRational": "Decline Rationale", - "AssessmentResultsView:AssessmentResultsForm.Notes": "Notes", - "AssessmentResultsView:AssessmentResultsForm.TotalScore": "Total Score", - "AssessmentResultsView:AssessmentResultsForm.AssessmentResult": "Assessment Result", - "AssessmentResultsView:AssessmentResultsForm.FinalDecisionDate": "Decision Date", - "AssessmentResultsView:AssessmentResultsForm.DueDate": "Due Date", - "AssessmentResultsView:AssessmentResultsForm.NotificationDate": "Notification Date", - "AssessmentResultsView:AssessmentResultsForm.RiskRanking": "Risk Ranking", - "GrantApplication:ActionButtonName": "Status Actions", - "GrantApplication:ActionButton.RedStopWarning": "This application is from an applicant with a Red-Stop. Status actions are not permitted.", - "Enum:GrantApplicationAction.Open": "Open", - "Enum:GrantApplicationAction.Submit": "Submit", - "Enum:GrantApplicationAction.Internal_Assign": "Assign", - "Enum:GrantApplicationAction.StartReview": "Start Review", - "Enum:GrantApplicationAction.CompleteReview": "Complete Review", - "Enum:GrantApplicationAction.StartAssessment": "Start Assessment", - "Enum:GrantApplicationAction.CompleteAssessment": "Complete Assessment", - "Enum:GrantApplicationAction.Close": "Close", - "Enum:GrantApplicationAction.Withdraw": "Withdraw", - "Enum:GrantApplicationAction.Approve": "Approve", - "Enum:GrantApplicationAction.Deny": "Decline", - "Enum:GrantApplicationAction.Defer": "Defer", - "Enum:GrantApplicationAction.OnHold": "On Hold", - "Enum:GrantApplicationAction.Message.Open": "Open", - "Enum:GrantApplicationAction.Message.Submit": "Submitted", - "Enum:GrantApplicationAction.Message.Internal_Assign": "Assigned", - "Enum:GrantApplicationAction.Message.StartReview": "Under Initial Review", - "Enum:GrantApplicationAction.Message.CompleteReview": "The Initial Review is completed!", - "Enum:GrantApplicationAction.Message.StartAssessment": "Under Assessment", - "Enum:GrantApplicationAction.Message.CompleteAssessment": "The Assessment is completed!", - "Enum:GrantApplicationAction.Message.Close": "The Application is closed!", - "Enum:GrantApplicationAction.Message.Withdraw": "The Application is withdrawn!", - "Enum:GrantApplicationAction.Message.Approve": "Approved", - "Enum:GrantApplicationAction.Message.Deny": "Declined", - "Enum:GrantApplicationAction.Message.Defer": "Deferred", - "Enum:GrantApplicationAction.Message.OnHold": "On-Hold", - "Setting:GrantManager.Locality.SectorFilter.DisplayName": "SectorFilter", - "Setting:GrantManager.Locality.SectorFilter.Description": "Filter for the sector and subsector dropdown list of each tenant", - "Permission:UnitySettingManagementPermissions.BackgroundJobs": "Background Jobs", - "Permission:UnitySettingManagementPermissions.UserInterface": "Application Tabs", - "Permission:UnitySettingManagementPermissions.ConfigurePayments": "Configure Payments", - "Setting:GrantManager.UI.PageTitle": "Application Tabs Configuration", - "Setting:GrantManager.UI.Tabs.Applicant.Description": "Toggle visibility of the Applicant Info tab for the tenant", - "Setting:GrantManager.UI.Tabs.Applicant.DisplayName": "Applicant Info", - "Setting:GrantManager.UI.Tabs.Assessment.Description": "Toggle visibility of the Review & Assessment tab for the tenant", - "Setting:GrantManager.UI.Tabs.Assessment.DisplayName": "Review & Assessment", - "Setting:GrantManager.UI.Tabs.FundingAgreement.Description": "Toggle visibility of the Funding Agreement tab for the tenant", - "Setting:GrantManager.UI.Tabs.FundingAgreement.DisplayName": "Funding Agreement", - "Setting:GrantManager.UI.Tabs.Payments.Description": "Toggle visibility of the Payment Info tab for the tenant", - "Setting:GrantManager.UI.Tabs.Payments.DisplayName": "Payment Info", - "Setting:GrantManager.UI.Tabs.Project.Description": "Toggle visibility of the Project Info tab for the tenant", - "Setting:GrantManager.UI.Tabs.Project.DisplayName": "Project Info", - "Setting:GrantManager.UI.Tabs.Submission.Description": "Toggle visibility of the Submission tab for the tenant", - "Setting:GrantManager.UI.Tabs.Submission.DisplayName": "Submission", - "Setting:GrantManager.UI.Tabs.Assessment.AssessmentResults.DisplayName": "Application Assessment Results", - "Setting:GrantManager.UI.Tabs.Assessment.AssessmentApproval.DisplayName": "Approval", - "Setting:GrantManager.UI.Tabs.Assessment.ReviewList.DisplayName": "Assessment List", - "Setting:GrantManager.UI.Tabs.Project.ProjectInfo.DisplayName": "Project Summary", - "Setting:GrantManager.UI.Tabs.Applicant.ApplicantInfo.DisplayName": "Applicant Info", - "Setting:GrantManager.UI.Tabs.Applicant.ContactInfo.DisplayName": "Contact Info", - "Setting:GrantManager.UI.Tabs.Applicant.SigningAuthority.DisplayName": "Signing Authority", - "Setting:GrantManager.UI.Tabs.Applicant.PhysicalAddress.DisplayName": "Physical Address", - "Setting:GrantManager.UI.Tabs.FundingAgreement.FundingAgreementInfo.DisplayName": "Contract Info", - "Setting:GrantManager.UI.Tabs.Payments.PaymentInfo.DisplayName": "Payment Summary", - "Setting:GrantManager.UI.Tabs.Payments.PaymentList.DisplayName": "Payment List", - "Setting:GrantManager.UI.Tabs.Project.ProjectLocation.DisplayName": "Project Location", - "Summary:ApplicationSummaryTitle": "Submission", - "Summary:AssessmentSummaryTitle": "Assessment Summary", - "Summary:ContactsTitle": "Additional Contact(s)", - "Summary:Application.Category": "Category", - "Summary:Application.EconomicRegion": "Economic Region", - "Summary:Application.RegionalDistrict": "Regional District", - "Summary:Application.SubmissionDate": "Submission Date", - "Summary:Application.OrganizationName": "Registered Organization Name", - "Summary:Application.OrganizationNumber": "Registered Organization Number", - "Summary:Application.BusinessNumber": "Business Number", - "Summary:Application.NonRegOrgName": "Non-Registered Organization Name", - "Summary:Application.City": "City", - "Summary:Application.Community": "Community", - "Summary:Application.RequestedAmount": "Requested Amount", - "Summary:Application.ProjectBudget": "Total Project Budget", - "Summary:Application.Sector": "Sector", - "Summary:Application.Owner": "Owner", - "Summary:Application.UnityApplicationId": "Unity Application ID", - "Summary:Application.Assignees": "Assignees", - "Summary:Assessment.Status": "Status", - "Summary:Assessment.LikelihoodOfFunding": "Likelihood Of Funding", - "Summary:Assessment.AssessmentStartDate": "Assessment Start Date", - "Summary:Assessment.FinalDecisionDate": "Decision Date", - "Summary:Assessment.TotalScore": "Total Score", - "Summary:Assessment.AssessmentResult": "Assessment Result", - "Summary:Assessment.RecommendedAmount": "Recommended Amount", - "Summary:Assessment.ApprovedAmount": "Approved Amount", - "Summary:Assessment.Batch": "Batch #", - "Summary:ApplicationTags": "Application Tags", - "Unity.GrantManager.ApplicationManagement.Project.Summary:DisplayName": "Project Summary", - "ProjectInfoView:ProjectInfo.ProjectName": "Project Name", - "ProjectInfoView:ProjectInfo.ProjectSummary": "Project Summary", - "ProjectInfoView:ProjectInfo.ProjectStartDate": "Project Start Date", - "ProjectInfoView:ProjectInfo.ProjectEndDate": "Project End Date", - "ProjectInfoView:ProjectInfo.RequestedAmount": "Requested Amount", - "ProjectInfoView:ProjectInfo.TotalProjectBudget": "Total Project Budget", - "ProjectInfoView:ProjectInfo.PercentageTotalProjectBudget": "% of Total Project Budget", - "ProjectInfoView:ProjectInfo.ProjectFundingTotal": "Projected Funding Total", - "ProjectInfoView:ProjectInfo.Sector": "Sector", - "ProjectInfoView:ProjectInfo.SubSector": "Sub Sector", - "ProjectInfoView:ProjectInfo.Community": "Community", - "ProjectInfoView:ProjectInfo.EconomicRegion": "Economic Region", - "ProjectInfoView:ProjectInfo.ElectoralDistrict": "Project Electoral District", - "ProjectInfoView:ProjectInfo.CommunityPopulation": "Community Population", - "ProjectInfoView:ProjectInfo.Place": "Place", - "ProjectInfoView:ProjectInfo.Acquisition": "Acquisition", - "ProjectInfoView:ProjectInfo.Forestry": "Forestry/Non-Forestry", - "ProjectInfoView:ProjectInfo.ForestryFocus": "Forestry Focus", - "ProjectInfoView:ProjectInfo.CensusSubdivision": "Census Subdivision", - "ProjectInfoView:ProjectInfo.RegionalDistrict": "Regional District", - "Unity.GrantManager.ApplicationManagement.Project.Location:DisplayName": "Project Location", - "ProjectInfoView:ProjectInfoContactInfo": "Contact Info", - "ProjectInfoView:ProjectInfo.ContactFullName": "Contact Full Name", - "ProjectInfoView:ProjectInfo.ContactTitle": "Contact Title", - "ProjectInfoView:ProjectInfo.ContactEmail": "Contact Email", - "ProjectInfoView:ProjectInfo.ContactBusinessPhone": "Contact Business Phone", - "ProjectInfoView:ProjectInfo.ContactCellPhone": "Contact Cell Phone", - "ApplicantInfoView:ApplicantInfoContactInfo": "Contact Info", - "ApplicantInfoView:SigningAuthorityTitle": "Signing Authority", - "ApplicantInfoView:PhysicalAddress": "Physical Address", - "ApplicantInfoView:MailingAddress": "Mailing Address", - "ApplicantInfoView:ApplicantInfo.ContactFullName": "Full Name", - "ApplicantInfoView:ApplicantInfo.ContactTitle": "Title", - "ApplicantInfoView:ApplicantInfo.ContactEmail": "Email", - "ApplicantInfoView:ApplicantInfo.ContactBusinessPhone": "Business Phone", - "ApplicantInfoView:ApplicantInfo.ContactCellPhone": "Cell Phone", - "ApplicantInfoView:ApplicantInfo SigningAuthorityInfo": " Signing Authority", - "ApplicantInfoView:ApplicantInfo.SigningAuthorityFullName": "Full Name", - "ApplicantInfoView:ApplicantInfo.SigningAuthorityTitle": "Title", - "ApplicantInfoView:ApplicantInfo.SigningAuthorityEmail": "Email", - "ApplicantInfoView:ApplicantInfo.SigningAuthorityBusinessPhone": "Business Phone", - "ApplicantInfoView:ApplicantInfo.SigningAuthorityCellPhone": "Phone", - "ApplicantInfoView:ApplicantInfo.OrgName": "Registered Organization Name", - "ApplicantInfoView:ApplicantInfo.OrgNumber": "Registered Organization Number", - "ApplicantInfoView:ApplicantInfo.BusinessNumber": "Business Number", - "ApplicantInfoView:ApplicantInfo.OrgBookStatus": "Org book status ", - "ApplicantInfoView:ApplicantInfo.OrganizationType": "Organization Type", - "ApplicantInfoView:ApplicantInfo.OrganizationSize": "Organization Size", - "ApplicantInfoView:ApplicantInfo.UnityApplicant": "Applicant Id", - "ApplicantInfoView:ApplicantInfo.FiscalMonth": "Fiscal Year End Month", - "ApplicantInfoView:ApplicantInfo.FiscalDay": "Fiscal Year End Day", - "ApplicantInfoView:ApplicantInfo.IndigenousOrgInd": "Indigenous", - "ApplicantInfoView:ApplicantInfo.Sector": "Sector", - "ApplicantInfoView:ApplicantInfo.SubSector": "Sub-sector", - "ApplicantInfoView:ApplicantInfo.RedStop": "Red-Stop", - "ApplicantInfoView:ApplicantInfo.ApplicantInfoTitle": "Applicant Info", - "ApplicantInfoView:ApplicantInfo.SectorSubSectorIndustryDesc": "Other Sector/Sub/Industry Description", - "ApplicantInfoView:ApplicantInfo.Street": "Street", - "ApplicantInfoView:ApplicantInfo.Street2": "Street 2", - "ApplicantInfoView:ApplicantInfo.Unit": "Unit", - "ApplicantInfoView:ApplicantInfo.City": "City", - "ApplicantInfoView:ApplicantInfo.Province": "Province", - "ApplicantInfoView:ApplicantInfo.PostalCode": "Postal Code", - "ApplicantInfoView:ApplicantInfo.NonRegOrgName": "Non-Registered Organization Name", - "ApplicantInfoView:ApplicantInfo.OrgBookSearchPlaceholder": "Start typing to search for your registered organization name", - "ApplicantInfoView:ApplicantInfo.OrgBookSearch": "Search in BC Registries", - "ApplicantInfoView:ElectoralDistrict": "Electoral District", - "ApplicantInfoView:ApplicantElectoralDistrict": "Applicant Electoral District", - "ApplicantInfoView:Notes.ElectoralDistrict": "The electoral district is identified based on the {0}", - "ApplicantInfoView:ApplicantInfo.ApplicantLookUp": "Applicant Look up", - "ApplicantInfoView:ApplicantInfo.ApplicantLookUpPlaceholder": "Start typing applicant name or number to search for applicant...", - "ApplicantInfoView:ApplicantInfo.PrincipalRecord": "Principal Record", - "ApplicantInfoView:ApplicantInfo.Principal": "Use as a Principal", - "ApplicantInfoView:ApplicantInfo.ApplicantName": "Applicant Name", - "FundingAgreementInfoView:FundingAgreementInfoTitle": "Funding Agreement", - "FundingAgreementInfoView:FundingAgreementInfoContract": "Contract", - "FundingAgreementInfoView:FundingAgreementInfo.ContractNumber": "Contract #", - "FundingAgreementInfoView:FundingAgreementInfo.ContractExecutionDate": "Execution Date", - "UnityIdentity:ImportUser": "Import User", - "UnityIdentity:FirstName": "First Name", - "UnityIdentity:LastName": "Last Name", - "UnityIdentity:Import": "Import", - "ApplicationDetails:Comments.Modified": "Modified:", - "ApplicationDetails:Comments.Created": "Created:", - "ApplicationContact:AddTitle": "Add New Contact", - "ApplicationContact:EditTitle": "Edit Contact", - "ApplicationContact:Type": "Type", - "ApplicationContact:FullName": "Full Name", - "ApplicationContact:Title": "Title", - "ApplicationContact:Email": "Email", - "ApplicationContact:MobilePhone": "Mobile Phone Number", - "ApplicationContact:WorkPhone": "Work Phone Number", - "ApplicationContact:Delete": "Delete This Contact", - "ApplicantContact:SetAsPrimary": "Set as Primary", - "ApplicantContact:PrimaryHint": "This contact is currently primary because it was auto-selected by most recent timestamp. Saving with Set as Primary checked will explicitly set it as primary.", - "ApplicantContacts:ApplicantNotFound": "Applicant information not found.", - "ApplicantContacts:PrimaryContact": "Primary Contact", - "ApplicantContacts:NoPrimaryContact": "No primary contact on record.", - "ApplicantContacts:ContactsTitle": "Contacts", - "ApplicantContacts:PrimaryExplicitTooltip": "Primary contact", - "ApplicantContacts:PrimaryInferredTooltip": "Primary contact (auto-selected by most recent timestamp; not explicitly set).", - "ApplicantContacts:SourceInfoApplication": "Sourced from the Application submission. Managed on the Application Details form and cannot be edited here.", - "ApplicantContacts:SourceInfoApplicantAgent": "Sourced from the Applicant Agent on the CHEFS submission. Captured at intake and cannot be edited here.", - "ApplicantContacts:SourceInfoGeneric": "Sourced from {0} and cannot be edited here.", - "ApplicantContacts:View": "View", - "ApplicantContacts:ContactSaved": "Contact saved.", - "ApplicantContacts:ContactSetPrimary": "Contact set as primary.", - "ApplicantContacts:ServiceUnavailable": "Applicant contact service is not available.", - "ApplicantContacts:SetPrimaryFailed": "Failed to set contact as primary.", - "ApplicantContacts:ColumnName": "Name", - "ApplicantContacts:ColumnPhone": "Phone (Work)", - "ApplicantContacts:ColumnSubmission": "Submission #", - "ApplicationBatchApprovalRequest:Title": "Approve Applications", - "ApplicationBatchApprovalRequest:SubmitButtonText": "Approve", - "ApplicationBatchApprovalRequest:CancelButtonText": "Cancel", - "ApplicationBatchApprovalRequest:MaxCountExceeded": "You have exceeded the maximum number of items for bulk approval. Please reduce the number to {0} or fewer", - "ApplicationBatchApprovalRequest:DecisionDateDefaulted": "Decision Date has been defaulted", - "ApplicationBatchApprovalRequest:ApprovedAmountDefaulted": "Approved Amount has been defaulted", - "ApplicationBatchApprovalRequest:InvalidStatus": "The assessment for the selected item is not in the Assessment Completed state", - "ApplicationBatchApprovalRequest:InvalidPermissions": "Invalid permissions", - "ApplicationBatchApprovalRequest:InvalidApprovedAmount": "Invalid Approved Amount, it must be greater than 0.00", - "ApplicationBatchApprovalRequest:InvalidRecommendedAmount": "Invalid Recommended Amount, it must be greater than 0.00", - "ApplicationLinks:Category": "Category", - "ApplicationLinks:ID": "ID", - "ApplicationLinks:Status": "Status", - "ApplicationLinks:LinkType": "Link Type", - "ApplicantPortalSettings:Title": "Applicant Portal Configuration", - "ApplicantPortalSettings:ManageStatuses": "Manage Statuses", - "ApplicantPortalSettings:PortalStatusHeading": "Applicant Portal Status", - "ApplicantPortalSettings:InternalStatus": "Internal Status", - "ApplicantPortalSettings:PortalStatusLabel": "Portal Status Label", - "ApplicantPortalSettings:SaveChanges": "Save Changes", - "ApplicantPortalSettings:ResetChanges": "Reset", - "ApplicantPortalSettings:NoChanges": "No changes to save.", - "ApplicantPortalSettings:ChangesReset": "Changes have been reset to original values.", - "ApplicantPortalSettings:SaveSuccess": "Portal status labels updated successfully.", - "ApplicantPortalSettings:SaveError": "An error occurred while saving portal status labels.", - "ApplicantPortalSettings:ValidationRequired": "Portal status label cannot be empty." - }, - "baseResources": [ - "AbpValidation", - "AbpUi" - ] - }, - "AbpDddApplicationContracts": { - "texts": { - "MaxResultCountExceededExceptionMessage": "{0} can not be more than {1}! Increase {2}.{3} on the server side to allow more results." - }, - "baseResources": [] - }, - "AbpAuthorization": { - "texts": { - "Volo.Authorization:010001": "Authorization failed! Given policy has not granted.", - "Volo.Authorization:010002": "Authorization failed! Given policy has not granted: {PolicyName}", - "Volo.Authorization:010003": "Authorization failed! Given policy has not granted for given resource: {ResourceName}", - "Volo.Authorization:010004": "Authorization failed! Given requirement has not granted for given resource: {ResourceName}", - "Volo.Authorization:010005": "Authorization failed! Given requirements has not granted for given resource: {ResourceName}" - }, - "baseResources": [] - }, - "AbpExceptionHandling": { - "texts": { - "InternalServerErrorMessage": "An internal error occurred during your request!", - "ValidationErrorMessage": "Your request is not valid!", - "ValidationNarrativeErrorMessageTitle": "The following errors were detected during validation.", - "DefaultErrorMessage": "An error has occurred!", - "DefaultErrorMessageDetail": "Error detail not sent by the server.", - "DefaultErrorMessage401": "You are not authenticated!", - "DefaultErrorMessage401Detail": "You should sign in to perform this operation.", - "DefaultErrorMessage403": "You are not authorized!", - "DefaultErrorMessage403Detail": "You are not allowed to perform this operation!", - "DefaultErrorMessage404": "Resource not found!", - "DefaultErrorMessage404Detail": "The resource requested could not be found on the server!", - "EntityNotFoundErrorMessage": "There is no entity {0} with id = {1}!", - "EntityNotFoundErrorMessageWithoutId": "There is no entity {0}!", - "AbpDbConcurrencyErrorMessage": "The data you have submitted has already been changed by another user. Discard your changes and try again.", - "Error": "Error", - "UnhandledException": "Unhandled exception!", - "Authorizing": "Authorizing…", - "401Message": "Unauthorized", - "403Message": "Forbidden", - "404Message": "Page not found", - "500Message": "Internal Server Error", - "403MessageDetail": "You are not authorized to perform this operation!", - "404MessageDetail": "Sorry, there's nothing at this address.", - "Unauthorized": "Unauthorized", - "invalid_token": "Invalid token", - "SessionExpired": "Your session has expired. Please login again to continue in the application." - }, - "baseResources": [] - }, - "AbpUi": { - "texts": { - "Languages": "Languages", - "AreYouSure": "Are you sure?", - "Cancel": "Cancel", - "Clear": "Clear", - "Yes": "Yes", - "No": "No", - "Ok": "Ok", - "Close": "Close", - "Save": "Save", - "SavingWithThreeDot": "Saving...", - "Actions": "Actions", - "Delete": "Delete", - "CreatedSuccessfully": "Created successfully", - "SavedSuccessfully": "Saved successfully", - "DeletedSuccessfully": "Deleted successfully", - "Edit": "Edit", - "Refresh": "Refresh", - "Language": "Language", - "LoadMore": "Load more", - "ProcessingWithThreeDot": "Processing...", - "LoadingWithThreeDot": "Loading...", - "Welcome": "Welcome", - "Login": "Login", - "Register": "Register", - "Logout": "Log out", - "Submit": "Submit", - "Back": "Back", - "PagerSearch": "Search", - "PagerNext": "Next", - "PagerPrevious": "Previous", - "PagerFirst": "First", - "PagerLast": "Last", - "PagerInfo": "Showing _START_ to _END_ of _TOTAL_ entries", - "PagerInfo{0}{1}{2}": "Showing {0} to {1} of {2} entries", - "PagerInfoEmpty": "Showing 0 to 0 of 0 entries", - "PagerInfoFiltered": "(filtered from _MAX_ total entries)", - "NoDataAvailableInDatatable": "No data available", - "ErrorLoadingDatatable": "An error occurred during the request. Check the message for details.", - "Total": "total", - "Selected": "selected", - "PagerShowMenuEntries": "Show _MENU_ entries", - "DatatableActionDropdownDefaultText": "Actions", - "ChangePassword": "Change password", - "PersonalInfo": "My profile", - "AreYouSureYouWantToCancelEditingWarningMessage": "You have unsaved changes.", - "GoHomePage": "Go to the homepage", - "GoBack": "Go back", - "Search": "Search", - "ItemWillBeDeletedMessageWithFormat": "{0} will be deleted!", - "ItemWillBeDeletedMessage": "This item will be deleted!", - "ManageYourAccount": "Manage your account", - "OthersGroup": "Other", - "Today": "Today", - "Apply": "Apply", - "InternetConnectionInfo": "The operation could not be performed. Your internet connection is not available at the moment.", - "CopiedToTheClipboard": "Copied to the clipboard", - "AddNew": "Add new", - "ProfilePicture": "Profile picture", - "Theme": "Theme", - "NotAssigned": "Not Assigned", - "EntityActionsDisabledTooltip": "You do not have permission to perform any action.", - "ResourcePermissions": "Permissions" - }, - "baseResources": [ - "AbpExceptionHandling" - ] - }, - "AbpUiNavigation": { - "texts": { - "Menu:Administration": "Administration" - }, - "baseResources": [] - }, - "AbpGlobalFeature": { - "texts": { - "Volo.GlobalFeature:010001": "The '{ServiceName}' service needs to enable '{GlobalFeatureName}' feature." - }, - "baseResources": [] - }, - "AbpEmailing": { - "texts": { - "DisplayName:Abp.Mailing.DefaultFromAddress": "Default from address", - "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Default from display name", - "DisplayName:Abp.Mailing.Smtp.Host": "Host", - "DisplayName:Abp.Mailing.Smtp.Port": "Port", - "DisplayName:Abp.Mailing.Smtp.UserName": "User name", - "DisplayName:Abp.Mailing.Smtp.Password": "Password", - "DisplayName:Abp.Mailing.Smtp.Domain": "Domain", - "DisplayName:Abp.Mailing.Smtp.EnableSsl": "Enable SSL", - "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Use default credentials", - "Description:Abp.Mailing.DefaultFromAddress": "The default from address", - "Description:Abp.Mailing.DefaultFromDisplayName": "The default from display name", - "Description:Abp.Mailing.Smtp.Host": "The name or IP address of the host used for SMTP transactions.", - "Description:Abp.Mailing.Smtp.Port": "The port used for SMTP transactions.", - "Description:Abp.Mailing.Smtp.UserName": "User name associated with the credentials.", - "Description:Abp.Mailing.Smtp.Password": "The password for the user name associated with the credentials.", - "Description:Abp.Mailing.Smtp.Domain": "The domain or computer name that verifies the credentials.", - "Description:Abp.Mailing.Smtp.EnableSsl": "Whether the SmtpClient uses Secure Sockets Layer (SSL) to encrypt the connection.", - "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Whether the DefaultCredentials are sent with requests.", - "TextTemplate:StandardEmailTemplates.Layout": "Default email layout template", - "TextTemplate:StandardEmailTemplates.Message": "Simple message template for emails" - }, - "baseResources": [] - }, - "AI": { - "texts": { - "Permission:AI": "AI", - "Permission:AI.Reporting": "AI Reporting", - "Permission:AI.ViewApplicationAnalysis": "View AI Application Analysis", - "Permission:AI.ViewAttachmentSummary": "View AI Attachment Summary", - "Permission:AI.ViewScoringResult": "View AI Scoring Result", - "Permission:AI.GenerateApplicationAnalysis": "Generate AI Application Analysis", - "Permission:AI.GenerateAttachmentSummaries": "Generate AI Attachment Summaries", - "Permission:AI.GenerateScoring": "Generate AI Scoring", - "Permission:AI.ConfigureAI": "AI Configuration", - "Permission:AI.Prompts": "AI Prompt Management", - "Permission:AI.Prompts.Create": "Create Prompts", - "Permission:AI.Prompts.Update": "Edit Prompts", - "Permission:AI.Prompts.Delete": "Delete Prompts", - "Menu:AIReporting": "AI Reporting", - "Setting:AI.AutomaticGenerationEnabled": "Automatically Generate AI Analysis", - "Setting:AI.ManualGenerationEnabled": "Manually Initiate AI Analysis", - "AI:AttachmentSummariesDisabled": "AI attachment summaries are not enabled.", - "AI:ApplicationAnalysisDisabled": "AI application analysis is not enabled.", - "AI:ScoringDisabled": "AI scoring is not enabled.", - "AI:GenerateAllDisabled": "AI generation is not enabled.", - "AIPrompts": "AI Prompts", - "AIPrompt": "AI Prompt", - "AIPromptVersion": "Prompt Version", - "AIPromptVersions": "Prompt Versions", - "PromptType": "Type", - "PromptName": "Name", - "PromptDescription": "Description", - "PromptIsActive": "Active", - "VersionNumber": "Version Number", - "SystemPrompt": "System Prompt", - "UserPromptTemplate": "User Prompt Template", - "DeveloperNotes": "Developer Notes", - "TargetModel": "Target Model", - "TargetProvider": "Target Provider", - "Temperature": "Temperature", - "MaxTokens": "Max Tokens", - "IsPublished": "Published", - "IsDeprecated": "Deprecated" - }, - "baseResources": [ - "AbpValidation" - ] - }, - "AbpUiMultiTenancy": { - "texts": { - "GivenTenantIsNotExist": "Given tenant doesn't exist: {0}", - "GivenTenantIsNotAvailable": "Given tenant isn't available: {0}", - "Tenant": "Tenant", - "Switch": "switch", - "Name": "Name", - "SwitchTenantHint": "Leave the name field blank to switch to the host side.", - "SwitchTenant": "Switch tenant", - "NotSelected": "Not selected" - }, - "baseResources": [] - } - }, - "currentCulture": { - "displayName": "English (Canada)", - "englishName": "English (Canada)", - "threeLetterIsoLanguageName": "eng", - "twoLetterIsoLanguageName": "en", - "isRightToLeft": false, - "cultureName": "en-CA", - "name": "en-CA", - "nativeName": "English (Canada)", - "dateTimeFormat": { - "calendarAlgorithmType": "SolarCalendar", - "dateTimeFormatLong": "dddd, MMMM d, yyyy", - "shortDatePattern": "yyyy-MM-dd", - "fullDateTimePattern": "dddd, MMMM d, yyyy h:mm:ss tt", - "dateSeparator": "-", - "shortTimePattern": "h:mm tt", - "longTimePattern": "h:mm:ss tt" - } - } -}) - -})(); \ No newline at end of file diff --git a/Submission_files/ApplicationTags.js.download b/Submission_files/ApplicationTags.js.download deleted file mode 100644 index 1d537c4793..0000000000 --- a/Submission_files/ApplicationTags.js.download +++ /dev/null @@ -1,357 +0,0 @@ -$(function () { - - let suggestionsArray = []; - - let TagsInput = function (opts) { - this.options = Object.assign(TagsInput.defaults, opts); - this.init(); - } - - TagsInput.prototype.init = function (opts) { - this.options = opts ? Object.assign(this.options, opts) : this.options; - - if (this.initialized) - this.destroy(); - this.orignal_input = document.getElementById(this.options.selector); - - if (!this.orignal_input) { - console.error("tags-input couldn't find an element with the specified ID"); - return this; - } - - this.arr = []; - - this.wrapper = document.createElement('div'); - this.input = document.createElement('input'); - this.input.id = "tags-input-control"; - init(this); - initEvents(this); - - // Disable the input if user doesn't have create permission - if (!abp.auth.isGranted('Unity.Applications.Tags.Create')) { - this.input.disabled = true; - this.input.type = "hidden"; - this.wrapper.classList.add('tags-input-disabled'); - } - - this.initialized = true; - return this; - } - - TagsInput.prototype.addTag = function (tagData) { - let defaultClass = 'tags-common'; - let id, tagText, tagClass; - - id = tagData.id; - tagText = tagData.name || ''; - tagClass = tagData.class || defaultClass; - - if (this.anyErrors(tagText)) - return; - - this.arr.push({ Id: id, Name: tagText }); - - let tagInput = this; - - let tag = document.createElement('span'); - tag.className = this.options.tagClass + ' ' + tagClass; - tag.innerText = tagText; - - if (abp.auth.isGranted('Unity.Applications.Tags.Delete')) { - let closeIcon = document.createElement('a'); - closeIcon.innerHTML = '×'; - - closeIcon.addEventListener('click', function (e) { - e.preventDefault(); - let tag = this.parentNode; - - let tagIndex = Array.from(tagInput.wrapper.childNodes).indexOf(tag); - if (tagIndex !== -1) { - tagInput.deleteTag(tag, tagIndex); - } - }) - - tag.appendChild(closeIcon); - } - - this.wrapper.insertBefore(tag, this.input); - this.orignal_input.value = JSON.stringify(this.arr); - updateSelectedTagsInput(this.arr); - - return this; - } - - TagsInput.prototype.deleteTag = function (tag, i) { - let self = this; - - if (this.arr[i] && this.arr[i].Name === 'Uncommon Tags') { - abp.message.confirm('Are you sure you want to delete all the uncommon tags?') - .then(function (confirmed) { - if (confirmed) { - tag.remove(); - self.arr.splice(i, 1); - self.orignal_input.value = JSON.stringify(self.arr); - updateSelectedTagsInput(self.arr); - - // Expand input if no tags remain - if (self.arr.length === 0) { - self.input.classList.add('expanded'); - } - - return self; - } - }); - } else { - tag.remove(); - this.arr.splice(i, 1); - this.orignal_input.value = JSON.stringify(this.arr); - updateSelectedTagsInput(this.arr); - - // Expand input if no tags remain - if (this.arr.length === 0) { - this.input.classList.add('expanded'); - } - - return this; - } - } - - TagsInput.prototype.anyErrors = function (string) { - if (this.options.max != null && this.arr.length >= this.options.max) { - console.log('max tags limit reached'); - return true; - } - - if ( - !this.options.duplicate && - this.arr.some(tag => tag.name === string) - ) { - console.log('duplicate found "' + string + '"'); - return true; - } - - return false; - } - - TagsInput.prototype.addData = function (array) { - let plugin = this; - - array.forEach(function (string) { - plugin.addTag(string); - }) - return this; - } - - TagsInput.prototype.getInputString = function () { - return this.arr.join(','); - } - - TagsInput.prototype.setSuggestions = function (sugArray) { - suggestionsArray = sugArray; - } - - TagsInput.prototype.destroy = function () { - this.orignal_input.removeAttribute('hidden'); - - delete this.orignal_input; - let self = this; - - Object.keys(this).forEach(function (key) { - if (self[key] instanceof HTMLElement) - self[key].remove(); - - if (key != 'options') - delete self[key]; - }); - - this.initialized = false; - } - - function init(tags) { - // Create and append the add tag button - tags.addButton = document.createElement('button'); - tags.addButton.type = 'button'; - tags.addButton.className = 'tags-add-button'; - tags.addButton.innerHTML = '+'; - tags.addButton.title = 'Add a tag'; - - // Disable button if user doesn't have create permission - if (!abp.auth.isGranted('Unity.Applications.Tags.Create')) { - tags.addButton.disabled = true; - tags.addButton.style.display = 'none'; - } - - tags.wrapper.append(tags.input); - tags.wrapper.append(tags.addButton); - tags.wrapper.classList.add(tags.options.wrapperClass); - tags.orignal_input.setAttribute('hidden', 'true'); - tags.orignal_input.parentNode.insertBefore(tags.wrapper, tags.orignal_input); - tags.input.setAttribute('placeholder', 'Add a tag...'); - - tags.input.addEventListener('input', function () { - const inputValue = tags.input.value.trim().toLowerCase(); - - if (inputValue.length === 1) { - // Filter by first character only - const suggestions = suggestionsArray.filter(tag => - tag.name.toLowerCase().startsWith(inputValue)); - - if (suggestions.length) { - displaySuggestions(tags, suggestions, true); - } else { - removeSuggestions(tags); - } - } else if (inputValue.length > 1) { - // Filter by checking if input appears anywhere in tag name - const suggestions = suggestionsArray.filter(tag => - (tag.name.toLowerCase()).includes(inputValue)); - - if (suggestions.length) { - displaySuggestions(tags, suggestions, true); - } else { - removeSuggestions(tags); - } - } else { - removeSuggestions(tags); - } - }); - - // Expand input on focus - tags.input.addEventListener('focus', function () { - tags.input.classList.add('expanded'); - }); - } - - function displaySuggestions(tags, suggestions, isFiltered) { - - removeSuggestions(tags); - - const suggestionContainer = document.createElement('div'); - suggestionContainer.classList.add('tags-suggestion-container'); - const suggestionTitleElement = document.createElement('div'); - suggestionTitleElement.className = 'tags-suggestion-title'; - suggestionTitleElement.innerText = isFiltered ? 'FILTERED TAGS' : 'ALL TAGS'; - suggestionContainer.appendChild(suggestionTitleElement); - suggestions.forEach(suggestion => { - const suggestionElement = document.createElement('div'); - suggestionElement.className = 'tags-suggestion-element'; - suggestionElement.innerText = typeof suggestion === 'string' ? suggestion : suggestion.name; - suggestionElement.addEventListener('click', function () { - tags.addTag(suggestion); - removeSuggestions(tags); - tags.input.value = ""; - tags.wrapper.focus(); - }); - - suggestionContainer.appendChild(suggestionElement); - }); - - tags.wrapper.appendChild(suggestionContainer); - } - - function removeSuggestions(tags) { - const suggestionContainer = tags.wrapper.querySelector('.tags-suggestion-container'); - if (suggestionContainer) { - suggestionContainer.remove(); - } - } - - function initEvents(tags) { - // Capture keystrokes anywhere in the wrapper and focus input - let tagApplicationsModalElem = $("#tagApplicationsModal")[0]; - if (tagApplicationsModalElem) { - tagApplicationsModalElem.addEventListener('keydown', function (e) { - // Skip if input is already focused or if it's a special key - if (document.activeElement === tags.input) { - return; - } - - // Check if it's a printable character - const isPrintableKey = e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey; - if (isPrintableKey && abp.auth.isGranted('Unity.Applications.Tags.Create')) { - // Expand and focus the input - tags.input.classList.add('expanded'); - tags.input.focus(); - } - }); - } - - - // Add button click event - show all tags - if (tags.addButton) { - tags.addButton.addEventListener('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - - // Toggle suggestions display - const existingSuggestions = tags.wrapper.querySelector('.tags-suggestion-container'); - if (existingSuggestions) { - removeSuggestions(tags); - } else { - // Expand input and show all suggestions sorted alphabetically - tags.input.classList.add('expanded'); - const sortedSuggestions = [...suggestionsArray].sort((a, b) => - a.name.localeCompare(b.name) - ); - displaySuggestions(tags, sortedSuggestions, false); - // Focus the input field so user can type to filter - tags.input.focus(); - } - }); - } - - tags.input.addEventListener('focusout', function () { - $('#assignTagsModelSaveBtn').click(function () { - trimAndAddTag(tags); - }) - }); - - tags.input.addEventListener('keydown', function (e) { - if (~[9, 13, 188, 32].indexOf(e.keyCode)) { - e.preventDefault(); - trimAndAddTag(tags); - removeSuggestions(tags); - - } - }); - } - - function trimAndAddTag(tags) { - let str = tags.input.value.trim(); - if (!str) { - tags.input.value = ""; - return; - } - - const matched = suggestionsArray.find(s => - s.name.toLowerCase() === str.toLowerCase() - ); - - if (matched) { - tags.addTag(typeof matched === 'string' ? { name: matched } : matched); - } else { - abp.message.warn('Please select a tag from the suggestions.'); - } - - tags.input.value = ""; - } - - function updateSelectedTagsInput(tagsArray) { - let jsonValue = JSON.stringify(tagsArray); - $('#SelectedTagsJson').val(jsonValue); - } - - TagsInput.prototype.getTags = function () { - return this.arr.slice(); - } - - TagsInput.defaults = { - selector: '', - wrapperClass: 'tags-input-wrapper', - tagClass: 'tag', - max: null, - duplicate: false - } - - window.TagsInput = TagsInput; -}); diff --git a/Submission_files/AssessmentResultAttachments.css b/Submission_files/AssessmentResultAttachments.css deleted file mode 100644 index 3ada131167..0000000000 --- a/Submission_files/AssessmentResultAttachments.css +++ /dev/null @@ -1,28 +0,0 @@ -.assessment-attachment-table th:first-child, .assessment-attachment-table td:first-child { - text-align: center; -} - -/* Updated for DataTables v2 - ensure proper width handling with scrollX */ -#AssessmentResultAttachmentsTable_wrapper .dt-scroll-body { - overflow: visible !important; -} - -/* Ensure table wrapper uses full width */ -#AssessmentResultAttachmentsTable_wrapper { - width: 100%; -} - -/* Ensure scroll container allows dropdowns to overflow */ -#AssessmentResultAttachmentsTable_wrapper .dt-scroll { - overflow: visible; -} - -/* Ensure inner scroll elements take full width */ -#AssessmentResultAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner, -#AssessmentResultAttachmentsTable_wrapper .dt-scroll-head .dt-scroll-headInner table { - width: 100% !important; -} - -#AssessmentResultAttachmentsTable_wrapper .dt-scroll-body table { - width: 100% !important; -} \ No newline at end of file diff --git a/Submission_files/AssessmentResultAttachments.js.download b/Submission_files/AssessmentResultAttachments.js.download deleted file mode 100644 index 912120f93a..0000000000 --- a/Submission_files/AssessmentResultAttachments.js.download +++ /dev/null @@ -1,102 +0,0 @@ -// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js -$(function () { - const l = abp.localization.getResource('GrantManager'); - const nullPlaceholder = '—'; - - let inputAction = function (requestData, dataTableSettings) { - let assessmentId = decodeURIComponent($("#AssessmentId").val()); - return { - attachmentType: 'ASSESSMENT', - attachedResourceId: assessmentId ?? "00000000-0000-0000-0000-000000000000" - }; - }; - - let responseCallback = function (result) { - return { - data: result - }; - }; - - const dataTable = $('#AssessmentResultAttachmentsTable').DataTable( - abp.libs.datatables.normalizeConfiguration({ - serverSide: false, - order: [[2, 'asc']], - searching: true, - externalFilterButtonId: 'btn-toggle-filter-assessment-attachments', - paging: false, - select: false, - info: false, - scrollX: true, - ajax: abp.libs.datatables.createAjax( - unity.grantManager.attachments.attachment.getAttachments, inputAction, responseCallback - ), - columnDefs: [ - { - title: '', - width: '40px', - className: 'text-center', - render: function (data) { - return ''; - }, - orderable: false - }, - { - title: l('AssessmentResultAttachments:DocumentName'), - data: 'fileName', - className: 'data-table-header text-break', - width: '30%', - }, - { - title: 'Label', - data: 'displayName', - className: 'data-table-header text-break', - width: '20%', - render: function (data) { - return data ?? nullPlaceholder; - } - }, - { - title: l('AssessmentResultAttachments:UploadedDate'), - data: 'time', - className: 'data-table-header', - width: '140px', - render: function (data, type) { - if (type === 'display' || type === 'filter') { - return new Date(data).toDateString(); - } - return data; - }, - }, - { - title: l('AssessmentResultAttachments:AttachedBy'), - data: 'attachedBy', - className: 'data-table-header', - width: '25%', - }, - { - title: '', - data: 's3ObjectKey', - width: '80px', - className: 'text-center', - render: function (data, type, full, meta) { - return generateAttachmentButtonContent(data, type, full, meta, 'Assessment'); - }, - orderable: false - } - ], - }) - ); - - dataTable.on('click', 'tbody tr', function (e) { - e.currentTarget.classList.toggle('selected'); - }); - - initializeFilterRowPlugin(dataTable, 'btn-toggle-filter-assessment-attachments'); - - PubSub.subscribe( - 'refresh_assessment_attachment_list', - (msg, data) => { - dataTable.ajax.reload(); - } - ); -}); diff --git a/Submission_files/Attachments.css b/Submission_files/Attachments.css deleted file mode 100644 index 6fd1ac7e88..0000000000 --- a/Submission_files/Attachments.css +++ /dev/null @@ -1,35 +0,0 @@ -.attachments-table .dropdown-content { - display: none; - position: fixed; - right: 0; - margin-right: 20px; - background-color: #f9f9f9; - min-width: 250px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - z-index: 1039; - --bs-btn-active-color: var(--bc-colors-white-primary-500); - --bs-btn-active-bg: var(--bc-colors-blue-primary-500); -} - - .attachments-table .dropdown-content a { - text-decoration: none; - display: block; - } - - .attachments-table .dropdown-content a:hover { - background-color: #f1f1f1; - } - -.attachments-table .dropdown:hover .dropdown-content { - display: block; -} - -.attachments-table .fullwidth { - width: 100%; - display: block; - text-align: left; -} - -.spinner-loading { - color: #9f9d9c; -} diff --git a/Submission_files/Attachments.js.download b/Submission_files/Attachments.js.download deleted file mode 100644 index 7e9c4e7134..0000000000 --- a/Submission_files/Attachments.js.download +++ /dev/null @@ -1,144 +0,0 @@ -function escapeHtmlAttribute(value) { - return String(value ?? '') - .replaceAll('&', '&') - .replaceAll('"', '"') - .replaceAll("'", ''') - .replaceAll('<', '<') - .replaceAll('>', '>'); -} - -function generateAttachmentButtonContent(data, type, full, meta, attachmentType) { - let ownerId = getAttachmentOwnerId(attachmentType); - let downloadUrl = `/api/app/attachment/${attachmentType}/${encodeURIComponent(ownerId)}/download/${encodeURIComponent(full.fileName)}`; - let isCreator = abp.currentUser.id == full.creatorId; - let escapedAttachmentType = escapeHtmlAttribute(attachmentType); - let escapedOwnerId = escapeHtmlAttribute(ownerId); - let escapedFileName = escapeHtmlAttribute(full.fileName); - let escapedDisplayName = escapeHtmlAttribute(full.displayName || full.fileName); - let html = ` - - `; - - return html; -} - -function previewAttachment(attachmentType, ownerId, fileName, displayName) { - let previewModal = new abp.ModalManager({ - viewUrl: '../Attachments/PreviewAttachmentModal' - }); - previewModal.open({ - attachmentType: attachmentType, - ownerId: ownerId, - fileName: fileName, - displayName: displayName - }); -} - -$(document).on('click', '.js-preview-attachment', function () { - previewAttachment( - $(this).attr('data-attachment-type'), - $(this).attr('data-owner-id'), - $(this).attr('data-file-name'), - $(this).attr('data-display-name') - ); -}); - -function getAttachmentOwnerId(attachmentType) { - switch (attachmentType) { - case 'Assessment': - return decodeURIComponent($("#AssessmentId").val()); - case 'Application': - return decodeURIComponent($("#DetailsViewApplicationId").val()); - case 'Applicant': - return decodeURIComponent($("#DetailsViewApplicantId").val()); - default: - return null; - } -} - -function deleteAttachment(attachmentType, s3ObjectKey, fileName) { - let deleteAttachmentModal = new abp.ModalManager({ - viewUrl: '../Attachments/DeleteAttachmentModal' - }); - - deleteAttachmentModal.onResult(function () { - abp.notify.success( - 'Attachment is successfully deleted.', - 'Delete Attachment' - ); - - refreshAttachmentWidget(attachmentType); - }); - - deleteAttachmentModal.open({ - s3ObjectKey: s3ObjectKey, - fileName: fileName, - attachmentType: attachmentType, - attachmentTypeId: getAttachmentOwnerId(attachmentType), - }); -} - -function updateAttachmentMetadata(attachmentType, attachmentId) { - let updateAttachmentModal = new abp.ModalManager({ - viewUrl: '../Attachments/UpdateAttachmentModal' - }); - updateAttachmentModal.onResult(function () { - abp.notify.success( - 'Attachment is successfully updated.', - 'Update Attachment' - ); - refreshAttachmentWidget(attachmentType); - }); - updateAttachmentModal.open({ - attachmentType: attachmentType, - attachmentId: attachmentId - }); -} - -$(document).on('mouseenter', '.attachments-table .dropdown', function () { - const rect = this.getBoundingClientRect(); - const $content = $(this).find('.dropdown-content'); - $content.css({ visibility: 'hidden', display: 'block', top: '', bottom: '' }); - const dropdownHeight = $content.outerHeight(); - $content.css({ visibility: '', display: '' }); - if (rect.bottom + dropdownHeight > window.innerHeight) { - $content.css({ bottom: (window.innerHeight - rect.top) + 'px', top: '' }); - } else { - $content.css({ top: rect.bottom + 'px', bottom: '' }); - } -}); - -function refreshAttachmentWidget(attachmentType) { - switch (attachmentType) { - case 'Assessment': - PubSub.publish('refresh_assessment_attachment_list'); break; - case 'Application': - PubSub.publish('refresh_application_attachment_list'); break; - case 'Applicant': - PubSub.publish('refresh_applicant_attachment_list'); break; - case 'CHEFS': - PubSub.publish('refresh_chefs_attachment_list'); break; - default: break; - } -} - diff --git a/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg b/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg deleted file mode 100644 index 98e7013ba9..0000000000 --- a/Submission_files/BCID_UnityGrantManagement_RGB_pos.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Submission_files/ChefsAttachments.css b/Submission_files/ChefsAttachments.css deleted file mode 100644 index cb02550ca9..0000000000 --- a/Submission_files/ChefsAttachments.css +++ /dev/null @@ -1,116 +0,0 @@ -#ChefsAttachmentsTable a { - text-decoration: none; - --bs-btn-active-color: var(--bc-colors-white-primary-500); - --bs-btn-active-bg: var(--bc-colors-blue-primary-500); -} - -.attachments__title-button-split { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: stretch; - gap: 8px; - margin-bottom: 8px; -} - -.submission-title-and-actions { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - gap: 8px; - flex-wrap: nowrap; -} - -.sorting_disabled:before, -.sorting_disabled:after { - content: '' !important; -} - -.submission-title { - display: flex; - align-items: center; - height: 36px; - padding-top: 0; - flex: 0 0 auto; -} - -.submission-button-section { - display: flex; - flex: 1 1 auto; - flex-wrap: nowrap; - align-items: center; - align-content: center; - justify-content: flex-end; - gap: 6px; - min-width: 0; - overflow-x: auto; - overflow-y: hidden; -} - -.submission-button-section--top { - justify-content: flex-end; -} - -.submission-button-section--bottom { - justify-content: flex-end; -} - -.submission-button-section .btn { - flex: 0 0 auto; - height: 36px; - display: inline-flex; - align-items: center; - justify-content: center; - line-height: 1; - white-space: nowrap; -} - -.submission-button-section .btn + .btn { - margin-left: 0; -} - -.submission-button-section .button-content { - display: inline-flex; - align-items: center; - gap: 0.5rem; - white-space: nowrap; -} - -#ChefsAttachmentsTable_paginate { - display: block !important; - padding-top: 35px; -} - -/* AI Summary Row Styles */ -.ai-summary-row { - border-left: 4px solid var(--bc-colors-blue-primary); - background: #faf9f8; - padding: 10px 15px; -} - -#ChefsAttachmentsTable td.ai-summary-cell { - padding: 0; -} - -#ChefsAttachmentsTable .ai-summary-content { - color: #292929; - padding: 8px 12px; -} - -#ChefsAttachmentsTable .ai-summary-content strong { - color: var(--bc-colors-blue-primary); - font-weight: 600; - font-size: 13px; -} - -#ChefsAttachmentsTable .ai-summary-content p { - margin-bottom: 0; - color: #495057; - white-space: pre-wrap; - word-wrap: break-word; -} - -#ChefsAttachmentsTable tr.shown { - background-color: rgba(13, 110, 253, 0.05); -} diff --git a/Submission_files/ChefsAttachments.js.download b/Submission_files/ChefsAttachments.js.download deleted file mode 100644 index 969a7e5382..0000000000 --- a/Submission_files/ChefsAttachments.js.download +++ /dev/null @@ -1,558 +0,0 @@ -// Note: File depends on Unity.GrantManager.Web\Views\Shared\Components\_Shared\Attachments.js -$(function () { - globalThis.queueAttachmentSummary = function (triggerButton = null) { - $('#generateAiSummaries') - .data('trigger-button', triggerButton || null) - .trigger('click'); - }; - - const downloadAll = $('#downloadAll'); - const dt = $('#ChefsAttachmentsTable'); - let chefsDataTable; - let selectedAttachmentIds = []; - const nullPlaceholder = '—'; - - let inputAction = function (requestData, dataTableSettings) { - const urlParams = new URL(globalThis.location.toLocaleString()).searchParams; - const applicationId = urlParams.get('ApplicationId'); - return applicationId; - }; - - let responseCallback = function (result) { - if (result.length <= 0) { - $('.dataTables_paginate').hide(); - } - - if (result) { - setTimeout(function () { - PubSub.publish('update_application_attachment_count', { - chefs: result.length, - }); - }, 10); - - $(downloadAll).prop('disabled', result.length === 0); - selectedAttachmentIds = []; - setGenerateSummariesEnabled(); - - const hasAISummaries = result.some( - (item) => item.aiSummary && item.aiSummary.trim() !== '' - ); - const $toggleButton = $('#toggleAllAISummaries'); - if ($toggleButton.length > 0) { - $toggleButton.prop('disabled', !hasAISummaries); - if (!hasAISummaries) { - $toggleButton.attr('title', 'No AI summaries available'); - } else { - $toggleButton.attr('title', 'Show AI Summaries'); - } - } - } - return { - data: formatItems(result), - }; - }; - - function getColumns() { - return [ - getSelectColumn('Select Attachment', 'rowCount', 'chefs-files'), - getChefsFileNameColumn(), - getChefsLabelColumn(), - getChefsFileDownloadColumn(), - ]; - } - - function setGenerateSummariesEnabled() { - $('#generateAiSummaries').prop('disabled', selectedAttachmentIds.length === 0); - } - - function setSelectAllState() { - const totalCheckboxes = $('#ChefsAttachmentsTable .chkbox').length; - const selectedCheckboxes = $('#ChefsAttachmentsTable .chkbox:checked').length; - $('.select-all-chefs-files').prop( - 'checked', - totalCheckboxes > 0 && selectedCheckboxes === totalCheckboxes - ); - } - - function resetAttachmentSelection() { - selectedAttachmentIds = []; - chefsDataTable.rows().deselect(); - chefsDataTable.$('.chkbox').prop('checked', false); - $('.select-all-chefs-files').prop('checked', false); - setGenerateSummariesEnabled(); - } - - function setAllAttachmentSelections(isSelected) { - if (isSelected) { - chefsDataTable.rows({ page: 'current' }).select(); - } else { - chefsDataTable.rows({ page: 'current' }).deselect(); - } - } - - function getChefsFileNameColumn() { - return { - title: 'Document Name', - name: 'chefsFileName', - data: 'fileName', - className: 'data-table-header text-break', - index: 1, - orderable: false, - width: '40%', - }; - } - - function getChefsLabelColumn() { - return { - title: 'Label', - data: 'displayName', - className: 'data-table-header text-break', - width: '35%', - render: function (data) { - return data ?? nullPlaceholder; - }, - }; - } - - let formatItems = function (items) { - const newData = items.map((item, index) => { - return { - ...item, - rowCount: index, - }; - }); - return newData; - }; - - chefsDataTable = dt.DataTable( - abp.libs.datatables.normalizeConfiguration({ - serverSide: false, - paging: true, - order: [[1, 'desc']], - searching: true, - iDisplayLength: 25, - lengthMenu: [10, 25, 50, 100], - scrollX: true, - scrollCollapse: false, - processing: true, - autoWidth: true, - select: { - style: 'multiple', - selector: 'td:not(:nth-child(4))', - }, - ajax: abp.libs.datatables.createAjax( - unity.grantManager.attachments.attachment - .getApplicationChefsFileAttachments, - inputAction, - responseCallback - ), - columnDefs: getColumns(), - externalFilterButtonId: 'btn-toggle-filter-submissions', - }) - ); - - initializeFilterRowPlugin(chefsDataTable, 'btn-toggle-filter-submissions'); - - PubSub.subscribe('refresh_chefs_attachment_list', (msg, data) => { - chefsDataTable.ajax.reload(); - }); - - // Generate AI summaries for the current application attachments. - const $generateAISummariesButton = $('#generateAiSummaries'); - if ($generateAISummariesButton.length > 0) { - $generateAISummariesButton.on('click', function () { - const $button = $(this); - const triggerButton = $button.data('trigger-button'); - const $activeButton = triggerButton ? $(triggerButton) : $button; - const rows = triggerButton - ? chefsDataTable.rows().data().toArray() - : chefsDataTable.rows({ selected: true }).data().toArray(); - const summaryAttachmentIds = rows.map((row) => row.id); - - $button.removeData('trigger-button'); - - if (summaryAttachmentIds.length === 0) { - abp.message.warn( - triggerButton - ? 'No attachments were found to generate summaries.' - : 'Select at least one attachment to generate summaries.' - ); - return; - } - - const existingHTML = $activeButton.html(); - - $activeButton - .html( - 'Generating...' - ) - .prop('disabled', true); - globalThis.AIGenerationButtonState?.setGenerating($activeButton); - - $.ajax({ - url: '/api/app/attachment-summary/generate-attachment-summaries', - data: JSON.stringify(summaryAttachmentIds), - contentType: 'application/json', - type: 'POST', - success: function () { - resetAttachmentSelection(); - chefsDataTable.ajax.reload(); - abp.notify.success('AI summaries generated successfully.'); - globalThis.AIGenerationButtonState?.restore($activeButton); - $activeButton.html(existingHTML).prop('disabled', false); - }, - error: function (error) { - console.error('Error generating AI summaries:', error); - abp.message.error('An error occurred while generating AI summaries. Please try again.'); - globalThis.AIGenerationButtonState?.restore($activeButton); - $activeButton.html(existingHTML).prop('disabled', false); - setGenerateSummariesEnabled(); - }, - }); - }); - } - - // Toggle all AI summaries (only if feature is enabled) - const $toggleAllAISummariesButton = $('#toggleAllAISummaries'); - let allAISummariesExpanded = false; - - if ($toggleAllAISummariesButton.length > 0) { - $toggleAllAISummariesButton.on('click', function () { - const $button = $(this); - const $icon = $button.find('i'); - const $label = $button.find('.toggle-ai-summaries-label'); - - if ($button.prop('disabled')) { - return; - } - - if (allAISummariesExpanded) { - chefsDataTable.rows().every(function () { - const row = this; - if (row.child.isShown()) { - const $childRow = $(row.child()); - const $summaryRow = $childRow.find('.ai-summary-row'); - - $summaryRow.removeClass('fade-in').addClass('fade-out'); - - setTimeout(function () { - row.child.hide(); - $(row.node()).removeClass('shown'); - $summaryRow.removeClass('fade-out'); - }, 500); - } - }); - $icon.removeClass('fa-chevron-up').addClass('fa-chevron-down'); - $label.text('Show Summaries'); - $button.attr('title', 'Show AI Summaries'); - allAISummariesExpanded = false; - } else { - chefsDataTable.rows().every(function () { - const row = this; - const rowData = row.data(); - - if (rowData.aiSummary && rowData.aiSummary.trim() !== '') { - const summaryHtml = formatAISummary(rowData); - - row.child(summaryHtml, 'ai-summary-cell').show(); - $(row.node()).addClass('shown'); - - setTimeout(function () { - const $childRow = $(row.child()); - $childRow.find('.ai-summary-row').addClass('fade-in'); - }, 10); - } - }); - $icon.removeClass('fa-chevron-down').addClass('fa-chevron-up'); - $label.text('Hide Summaries'); - $button.attr('title', 'Hide AI Summaries'); - allAISummariesExpanded = true; - } - }); - } - - chefsDataTable.on('draw.dt', function () { - if (allAISummariesExpanded) { - const $button = $('#toggleAllAISummaries'); - const $icon = $button.find('i'); - const $label = $button.find('.toggle-ai-summaries-label'); - $icon.removeClass('fa-chevron-up').addClass('fa-chevron-down'); - $label.text('Show Summaries'); - $button.attr('title', 'Show AI Summaries'); - allAISummariesExpanded = false; - } - }); - - function formatAISummary(data) { - const safeSummary = escapeHtml(data.aiSummary || 'No summary available'); - return ( - '
' + - '
' + - ' Summary: ' + - '

' + - safeSummary + - '

' + - '
' + - '
' - ); - } - - $(document).on('click', '.select-all-chefs-files', function () { - setAllAttachmentSelections($(this).is(':checked')); - }); - - chefsDataTable.on('select', function (e, dt, type, indexes) { - if (type !== 'row') { - return; - } - - indexes.forEach((index) => { - const data = chefsDataTable.row(index).data(); - $('#row_' + index).prop('checked', true); - - if (data?.id && !selectedAttachmentIds.includes(data.id)) { - selectedAttachmentIds.push(data.id); - } - }); - setGenerateSummariesEnabled(); - setSelectAllState(); - }); - - chefsDataTable.on('deselect', function (e, dt, type, indexes) { - if (type !== 'row') { - return; - } - - indexes.forEach((index) => { - const data = chefsDataTable.row(index).data(); - $('#row_' + index).prop('checked', false); - - if (data?.id) { - selectedAttachmentIds = selectedAttachmentIds.filter((id) => id !== data.id); - } - }); - setGenerateSummariesEnabled(); - setSelectAllState(); - }); - - $('#resyncSubmissionAttachments').on('click', function () { - let applicationId = document.getElementById( - 'AssessmentResultViewApplicationId' - ).value; - try { - unity.grantManager.attachments.attachment - .resyncSubmissionAttachments(applicationId) - .done(function () { - abp.notify.success('Submission Attachment/s has been resynced.'); - chefsDataTable.ajax.reload(); - chefsDataTable.columns.adjust(); - }); - } catch (error) { - console.log(error); - } - }); - - $('#attachments-tab').on('click', function () { - chefsDataTable.columns.adjust(); - }); - - $(downloadAll).on('click', function () { - const refNo = - document.getElementsByClassName('reference-no')[0].textContent; - const _this = $(this); - const existingHTML = _this.html(); - const zip = new JSZip(); - const tempFiles = chefsDataTable.rows().data().toArray().map((row) => ({ - FormSubmissionId: row.chefsSubmissionId, - ChefsFileId: row.chefsFileId, - Filename: row.fileName, - })); - - if (tempFiles.length > 0) { - $.ajax({ - url: '/api/app/attachment/chefs/download-all', - data: JSON.stringify(tempFiles), - contentType: 'application/json', - type: 'POST', - beforeSend: function () { - $(_this) - .html( - '
Downloading...
' - ) - .prop('disabled', true); - }, - success: function (data) { - data.forEach((file) => { - zip.file(file.fileDownloadName, file.fileContents, { - base64: true, - }); - }); - - zip.generateAsync({ type: 'blob' }).then(function (content) { - const link = document.createElement('a'); - link.href = URL.createObjectURL(content); - link.download = `${refNo}-All_Attachments.zip`; - link.click(); - }); - - abp.notify.success( - '', - 'The files have been downloaded successfully.' - ); - $(_this).html(existingHTML).prop('disabled', false); - }, - error: function (error) { - if (error.status === 403) { - showChefsAPIAccessError(); - } else { - abp.notify.error( - '', - 'The selected files exceed more than 80MB download limit. Please deselect some files and try again.' - ); - } - - $(_this).html(existingHTML).prop('disabled', false); - }, - }); - } - }); -}); - -function getChefsFileDownloadColumn() { - return { - title: '', - name: 'chefsFileDownload', - data: 'chefsFileId', - width: '60px', - className: 'text-nowrap', - render: function (data, type, full, meta) { - let submissionId = encodeURIComponent(full.chefsSubmissionId); - let fileId = encodeURIComponent(data); - let fileName = full.fileName; - let displayName = full.displayName || full.fileName; - let html = - ''; - return html; - }, - orderable: false, - index: 2, - }; -} - -function escapeHtml(text) { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} - -function downloadChefsFile(event) { - const button = event.currentTarget; - const chefsFileId = button.getAttribute('chefs-data'); - const chefsSubmissionId = button.getAttribute('chefs-submission-id'); - const chefsFileName = button.getAttribute('chefs-file-name'); - console.log('Downloading CHEFS file:', { - chefsFileId, - chefsSubmissionId, - chefsFileName, - }); - - $.ajax({ - url: - '/api/app/attachment/chefs/' + - chefsSubmissionId + - '/download/' + - chefsFileId + - '/' + - chefsFileName, - type: 'GET', - success: function (data) { - const downloadUrl = - '/api/app/attachment/chefs/' + - encodeURIComponent(chefsSubmissionId) + - '/download/' + - encodeURIComponent(chefsFileId) + - '/' + - encodeURIComponent(chefsFileName); - - const link = document.createElement('a'); - link.href = downloadUrl; - link.download = chefsFileName; - link.style.display = 'none'; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - abp.notify.success('', 'The file has been downloaded successfully.'); - }, - error: function (error) { - console.log('Error downloading CHEFS file:', error); - if (error.responseText?.includes('You do not have access')) { - showChefsAPIAccessError(); - } else { - abp.notify.error( - '', - error.responseText || - 'An error occurred while downloading the file.' - ); - } - }, - }); -} - -function previewChefsFile(event) { - const button = event.currentTarget; - const chefsFileId = button.getAttribute('chefs-data'); - const chefsSubmissionId = button.getAttribute('chefs-submission-id'); - const chefsFileName = button.getAttribute('chefs-file-name'); - const chefsDisplayName = button.getAttribute('chefs-display-name'); - - let previewModal = new abp.ModalManager({ - viewUrl: '../Attachments/PreviewAttachmentModal' - }); - previewModal.open({ - attachmentType: 'chefs', - ownerId: chefsSubmissionId, - chefsFileId: chefsFileId, - fileName: chefsFileName, - displayName: chefsDisplayName - }); -} - -function showChefsAPIAccessError() { - const message = - 'Please check that the CHEFS checkbox is enabled for: ' + - "'Allow this API key to access submitted files' in the related CHEFS form"; - - Swal.fire({ - title: 'CHEFS is not allowing Unity access to the File Download', - text: message, - confirmButtonText: 'Ok', - customClass: { - confirmButton: 'btn btn-primary', - }, - }); -} diff --git a/Submission_files/DateUtils.js.download b/Submission_files/DateUtils.js.download deleted file mode 100644 index 651e25ebc5..0000000000 --- a/Submission_files/DateUtils.js.download +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Date utility functions for Grant Manager application - */ -const DateUtils = (function () { - 'use strict'; - - /** - * Formats a UTC date string to local date format - * @param {string|Date} dateUtc - The UTC date to format - * @param {string} type - The type of formatting (for DataTables compatibility) - * @param {object} options - Additional formatting options - * @returns {string|number|null} Formatted date string or timestamp for sorting, null if input is invalid - */ - function formatUtcDateToLocal(dateUtc, type, options) { - if (!dateUtc) { - return null; - } - - const date = new Date(dateUtc); - - // Required for DataTables sorting & filtering - if (type === 'sort' || type === 'type') { - return date.getTime(); - } - - return date.toLocaleDateString( - abp.localization.currentCulture.name, - { - year: 'numeric', - month: '2-digit', - day: '2-digit', - ...options - } - ); - } - - // Public API - return { - formatUtcDateToLocal: formatUtcDateToLocal - }; -})(); \ No newline at end of file diff --git a/Submission_files/Default(1).css b/Submission_files/Default(1).css deleted file mode 100644 index 5ccbfa7afb..0000000000 --- a/Submission_files/Default(1).css +++ /dev/null @@ -1,53 +0,0 @@ -.spinner-loader { - display: flex; - align-items: center; - justify-content: center; -} - -.action-bar__drop-down-icon-link { - cursor: pointer; - display: flex; - gap: 0.5rem; -} - - -.search-action-bar { - display: flex; - justify-content: flex-end; - align-items: center; -} - -.search-action-bar_search-wrapper { - flex: 1; -} - -.action-bar-btn-unavailable { - display: none; -} - -.margin-left-auto { - margin-left: auto; -} - -.date-input-filter-div { - display: inline-block; - padding: 10px; - padding-top: 0px; - margin-top: -10px; - margin-bottom: -10px; - padding-bottom: 0px !important; -} - -.custom-date-range-container-div { - display: inline-block; - padding: 0px; - margin: 0px; -} - -.quick-date-input { - font-size: var(--bc-font-size); - color: var(--bc-colors-grey-text-500); - border-radius: var(--bc-layout-margin-small) !important; - border: 2px solid var(--bc-colors-blue-primary); - text-overflow: ellipsis; -} diff --git a/Submission_files/Default(1).js.download b/Submission_files/Default(1).js.download deleted file mode 100644 index 80b1dc11f9..0000000000 --- a/Submission_files/Default(1).js.download +++ /dev/null @@ -1,261 +0,0 @@ -$(function () { - let selectedApplicationIds = decodeURIComponent($("#DetailsViewApplicationId").val()); - - let approveApplicationsModal = new abp.ModalManager({ - viewUrl: '../Approve/ApproveApplicationsModal' - }); - - let dontApproveApplicationsModal = new abp.ModalManager({ - viewUrl: '../Approve/ApproveApplicationsModal' - }); - - let tagApplicationModal = new abp.ModalManager({ - viewUrl: '../ApplicationTags/ApplicationTagsSelectionModal', - }); - - approveApplicationsModal.onResult(function () { - abp.notify.success( - 'This application has been successfully approved', - 'Approve Application' - ); - }); - dontApproveApplicationsModal.onResult(function () { - abp.notify.success( - 'This application has now been disapproved', - 'Not Approve Application' - ); - }); - - $('#approveApplications').on('click', function () { - approveApplicationsModal.open({ - applicationIds: JSON.stringify(new Array(selectedApplicationIds)), - operation: 'GRANT_APPROVED', - message: 'Are you sure you want to approve this application?', - title: 'Approve Applications', - }); - }); - - let startAssessmentModal = new abp.ModalManager({ - viewUrl: '../Approve/ApproveApplicationsModal' - }); - - startAssessmentModal.onResult(function () { - abp.notify.success( - 'Assessment is now started for this application', - 'Start Assessment' - ); - }); - - $('#startAssessment').on('click', function () { - startAssessmentModal.open({ - applicationIds: JSON.stringify(new Array(selectedApplicationIds)), - operation: 'UNDER_ASSESSMENT', - message: 'Are you sure you want to start assessment for this application?', - title: 'Start Assessment', - }); - }); - - let completeAssessmentModal = new abp.ModalManager({ - viewUrl: '../Approve/ApproveApplicationsModal' - }); - - completeAssessmentModal.onResult(function () { - abp.notify.success( - 'Assessment is now completed for this application', - 'Completed Assessment' - ); - }); - - // Helper function to process tag items and group them by application ID - function processTagItems(tags, groupedTags) { - tags.forEach(function (item) { - if (!item.tag) return; - let appId = item.applicationId; - - if (!groupedTags[appId]) { - groupedTags[appId] = []; - } - - let exists = groupedTags[appId].some(t => t.id === item.tag.id); - if (!exists) { - groupedTags[appId].push(item.tag); - } - }); - } - - // Helper function to ensure all application IDs have entries in groupedTags - function initializeApplicationEntries(applicationIds, groupedTags) { - applicationIds.forEach(function (id) { - if (!groupedTags.hasOwnProperty(id)) { - groupedTags[id] = []; - } - }); - } - - // Helper function to check if tag exists in application tags - function tagExistsInApp(tag, appTags) { - return appTags.some(n => n.id === tag.id); - } - - // Helper function to filter common tags between two applications - function filterCommonTags(prevTags, nextTags) { - return prevTags.filter(p => tagExistsInApp(p, nextTags)); - } - - // Helper function to calculate common tags across all applications - function calculateCommonTags(groupedTags) { - let groupedValues = Object.values(groupedTags); - if (groupedValues.length === 0) return []; - - return groupedValues.reduce(filterCommonTags); - } - - // Helper function to check if tag is common - function isCommonTag(tag, commonTags) { - return commonTags.some(ct => ct.id === tag.id); - } - - // Helper function to sort tags by name - function sortTagsByName(tags) { - return [...tags].sort((a, b) => a.name.localeCompare(b.name)); - } - - // Helper function to create application tag summary - function createAppTagSummary(appId, tagList, commonTags) { - let uncommonTags = tagList.filter(tag => !isCommonTag(tag, commonTags)); - - return { - applicationId: appId, - commonTags: sortTagsByName(commonTags), - uncommonTags: sortTagsByName(uncommonTags) - }; - } - - // Helper function to create tag summary data - function createTagSummary(groupedTags, commonTags) { - return Object.entries(groupedTags).map(([appId, tagList]) => - createAppTagSummary(appId, tagList, commonTags) - ); - } - - // Helper function to collect uncommon tags - function collectUncommonTags(groupedTags, commonTags) { - let uncommonTags = []; - Object.entries(groupedTags).forEach(([appId, tagList]) => { - let uncommon = tagList.filter(tag => !isCommonTag(tag, commonTags)); - uncommonTags = uncommonTags.concat(uncommon); - }); - return uncommonTags; - } - - // Helper function to build tag input array - function buildTagInputArray(commonTags, uncommonTags) { - let tagInputArray = []; - - if (uncommonTags.length > 0) { - tagInputArray.unshift({ - tagId: '00000000-0000-0000-0000-000000000000', - name: 'Uncommon Tags', - class: 'tags-uncommon', - id: '00000000-0000-0000-0000-000000000000' - }); - } - - commonTags.forEach(function (tag) { - tagInputArray.push({ - tagId: tag.id, - name: tag.name, - class: 'tags-common', - id: tag.id - }); - }); - - return tagInputArray; - } - - tagApplicationModal.onOpen(async function () { - let tagInput = new TagsInput({ - selector: 'SelectedTags', - duplicate: false, - max: 50 - }); - - let cacheKey = $('#CacheKey').val(); - let applicationIds = []; - - if (!cacheKey) { - console.error("Cache key is missing"); - abp.notify.error('Failed to load application tags. Please try again.'); - return; - } - - // Retrieve application IDs from hidden field (populated by modal code-behind) - let selectedIds = $('#SelectedApplicationIds').val(); - applicationIds = JSON.parse(selectedIds); - - if (!applicationIds || applicationIds.length === 0) return; - - try { - let groupedTags = {}; - - let allTags = await unity.grantManager.globalTag.tags.getList(); - let tags = await unity.grantManager.grantApplications.applicationTags.getListWithCacheKey(cacheKey); - - processTagItems(tags, groupedTags); - initializeApplicationEntries(applicationIds, groupedTags); - - let commonTags = calculateCommonTags(groupedTags); - let alltags = createTagSummary(groupedTags, commonTags); - let uncommonTags = collectUncommonTags(groupedTags, commonTags); - - $('#TagsJson').val(JSON.stringify(alltags)); - - let tagInputArray = buildTagInputArray(commonTags, uncommonTags); - - tagInput.setSuggestions( - (allTags || []).filter((value, index, self) => - index === self.findIndex(t => t.id === value.id) - ).sort((a, b) => a.name.localeCompare(b.name)) - ); - - tagInput.addData(tagInputArray); - } catch (error) { - console.error("Error loading tag select list", error); - } - }); - - tagApplicationModal.onResult(function () { - abp.notify.success( - 'The application tags have been successfully updated.', - 'Application Tags' - ); - PubSub.publish("ApplicationTags_refresh"); - PubSub.publish("refresh_application_list"); - - }); - - $('#completeAssessment').on('click', function () { - completeAssessmentModal.open({ - applicationIds: JSON.stringify(new Array(selectedApplicationIds)), - operation: 'ASSESSMENT_COMPLETED', - message: 'Are you sure you want to complete assessment for this application?', - title: 'Complete Assessment', - }); - }); - - $('#tagApplication').on('click', function () { - // Store application IDs in distributed cache to avoid URL length limits - unity.grantManager.applications.applicationBulkActions - .storeApplicationIds({ applicationIds: new Array(selectedApplicationIds) }) - .then(function(response) { - tagApplicationModal.open({ - cacheKey: response.cacheKey, - actionType: 'Add' - }); - }) - .catch(function(error) { - abp.notify.error('Failed to prepare tag selection. Please try again.'); - console.error('Error storing application IDs:', error); - }); - }); -}); diff --git a/Submission_files/Default(10).css b/Submission_files/Default(10).css deleted file mode 100644 index 9cc85b1d6d..0000000000 --- a/Submission_files/Default(10).css +++ /dev/null @@ -1 +0,0 @@ -/* Placeholder file required by the component structure */ \ No newline at end of file diff --git a/Submission_files/Default(10).js.download b/Submission_files/Default(10).js.download deleted file mode 100644 index d7ab43374f..0000000000 --- a/Submission_files/Default(10).js.download +++ /dev/null @@ -1,196 +0,0 @@ -$(function () { - let selectedPaymentIds = []; - let tagPaymentModal = new abp.ModalManager({ - viewUrl: 'PaymentTags/PaymentTagsSelectionModal', - }); - - tagPaymentModal.onOpen(async function () { - let tagInput = new TagsInput({ - selector: 'SelectedTags', - duplicate: false, - max: 50 - }); - let selectedIds = $('#SelectedPaymentRequestIds').val(); - let paymentRequestIds = JSON.parse(selectedIds); - let cacheKey = $('#CacheKey').val(); - - if (!paymentRequestIds || paymentRequestIds.length === 0) return; - if (!cacheKey) { - console.error("Cache key is missing"); - abp.notify.error('Failed to load payment tags. Please try again.'); - return; - } - - try { - let commonTags = []; - let uncommonTags = []; - let allTags = []; - let groupedTags = {}; - - - allTags = await unity.grantManager.globalTag.tags.getList(); - - // Use cache key to avoid URL length limits with many payment IDs - let tags = await unity.payments.paymentTags.paymentTag.getListWithCacheKey(cacheKey); - - - tags.forEach(function (item) { - if (!item.tag) return; - let paymentId = item.paymentRequestId; - if (!groupedTags[paymentId]) { - groupedTags[paymentId] = []; - } - - let exists = groupedTags[paymentId].some(t => t.id === item.tag.id); - if (!exists) { - groupedTags[paymentId].push(item.tag); - } - }); - - paymentRequestIds.forEach(function (id) { - if (!groupedTags.hasOwnProperty(id)) { - groupedTags[id] = []; - } - }); - - // Helper functions to reduce nesting depth - function hasMatchingId(tagA, tagB) { - return tagA.id === tagB.id; - } - - function tagExistsInList(tag, tagList) { - return tagList.some(t => hasMatchingId(t, tag)); - } - - function filterCommonTags(prev, next) { - return prev.filter(p => tagExistsInList(p, next)); - } - - function getUncommonTags(tagList) { - return tagList.filter(tag => !tagExistsInList(tag, commonTags)); - } - - function sortByName(a, b) { - return a.name.localeCompare(b.name); - } - - let groupedValues = Object.values(groupedTags); - if (groupedValues.length > 0) { - commonTags = groupedValues.reduce(filterCommonTags); - } - - let allTagEntries = Object.entries(groupedTags).map(([paymentId, tagList]) => { - let uncommon = getUncommonTags(tagList); - - return { - paymentRequestId : paymentId, - commonTags: [...commonTags].sort(sortByName), - uncommonTags: uncommon.sort(sortByName) - }; - }); - - - $('#TagsJson').val(JSON.stringify(allTagEntries)); - - let tagInputArray = []; - - - Object.entries(groupedTags).forEach(function ([paymentId, tagList]) { - let uncommon = getUncommonTags(tagList); - uncommonTags = uncommonTags.concat(uncommon); - }); - - if (uncommonTags.length > 0) { - tagInputArray.unshift({ - tagId: '00000000-0000-0000-0000-000000000000', - name: 'Uncommon Tags', - class: 'tags-uncommon', - id: '00000000-0000-0000-0000-000000000000' - }); - } - - - if (commonTags.length > 0) { - commonTags.forEach(function (tag) { - tagInputArray.push({ - tagId: tag.id, - name: tag.name, - class: 'tags-common', - id: tag.id - }); - }); - } - - tagInput.setSuggestions( - (allTags || []).filter((value, index, self) => - index === self.findIndex(t => t.id === value.id) - ).sort((a, b) => a.name.localeCompare(b.name)) - ); - - tagInput.addData(tagInputArray); - } catch (error) { - console.error("Error loading tag select list", error); - } - - }); - - PubSub.subscribe("select_batchpayment_application", (msg, data) => { - if (!selectedPaymentIds.includes(data.id)) { - selectedPaymentIds.push(data.id); - } - manageActionButtons(); - }); - - PubSub.subscribe("deselect_batchpayment_application", (msg, data) => { - if (data === "reset_data") { - selectedPaymentIds = []; - } else { - selectedPaymentIds = selectedPaymentIds.filter(item => item !== data.id); - } - manageActionButtons(); - }); - - function manageActionButtons() { - if (selectedPaymentIds.length == 0) { - $('*[data-selector="batch-payment-table-actions"]').prop('disabled', true); - $('*[data-selector="batch-payment-table-actions"]').addClass('action-bar-btn-unavailable'); - $('.action-bar').addClass('disabled'); - $('#tagPayment').prop('disabled', true); - } - else { - $('*[data-selector="batch-payment-table-actions"]').prop('disabled', false); - $('*[data-selector="batch-payment-table-actions"]').removeClass('action-bar-btn-unavailable'); - $('.action-bar').addClass('active'); - $('#tagPayment').removeClass('disabled'); - $('#tagPayment').prop('disabled', false); - } - } - - $('#tagPayment').on('click', function () { - // Store payment IDs in distributed cache to avoid URL length limits - unity.payments.paymentRequests.paymentBulkActions - .storePaymentIds({ paymentRequestIds: selectedPaymentIds }) - .then(function(response) { - tagPaymentModal.open({ - cacheKey: response.cacheKey, - actionType: 'Add' - }); - }) - .catch(function(error) { - abp.notify.error('Failed to prepare tag selection. Please try again.'); - console.error('Error storing payment IDs:', error); - }); - }); - - - tagPaymentModal.onResult(function () { - abp.notify.success( - 'The payment tags have been successfully updated.', - 'Payment Tags' - ); - selectedPaymentIds = []; - manageActionButtons(); - PubSub.publish("refresh_payment_list"); - }); -}); - diff --git a/Submission_files/Default(11).css b/Submission_files/Default(11).css deleted file mode 100644 index 97c7876681..0000000000 --- a/Submission_files/Default(11).css +++ /dev/null @@ -1,2 +0,0 @@ -/* Intentionally left blank */ - diff --git a/Submission_files/Default(11).js.download b/Submission_files/Default(11).js.download deleted file mode 100644 index 0ab5b2c64d..0000000000 --- a/Submission_files/Default(11).js.download +++ /dev/null @@ -1,2 +0,0 @@ -$(function () { -}); diff --git a/Submission_files/Default(12).css b/Submission_files/Default(12).css deleted file mode 100644 index d96a3fce6c..0000000000 --- a/Submission_files/Default(12).css +++ /dev/null @@ -1,59 +0,0 @@ -.summary-container .form-label { - font-size: var(--bc-font-size-sm); - color: var(--bc-colors-grey-text-300); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 0; -} - -.display-input-label { - font-size: var(--bc-font-size-sm); - color: var(--bc-colors-grey-text-300); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 0; -} - -.display-input { - color: var(--bc-colors-grey-text-200); - pointer-events: none; - background-color: var(--bc-colors-grey-hover) !important; - opacity: var(--bs-btn-disabled-opacity); - background-blend-mode: difference; - border: var(--bs-border-width) solid var(--bs-border-color); - padding: 0.4rem; - border-radius: var(--bc-layout-margin-small) !important; - min-height: 2rem; -} - -.display-input-currency { - /*text-align: right; -check if right alignment require */ -} - -.summary-table { - width: 100%; - border-collapse: separate; - border-spacing: 5px 5px; -} -.tag-wrap { - flex-wrap: wrap; - padding-right: 0px; -} - -.full-length-tag { - width: 100%; -} -.empty-user-role{ - color : gray; -} - - -.user-tags-details-input-wrapper { - border: 0px; -} - -.currency-display { - text-align: right; -} diff --git a/Submission_files/Default(12).js.download b/Submission_files/Default(12).js.download deleted file mode 100644 index 0ab5b2c64d..0000000000 --- a/Submission_files/Default(12).js.download +++ /dev/null @@ -1,2 +0,0 @@ -$(function () { -}); diff --git a/Submission_files/Default(13).css b/Submission_files/Default(13).css deleted file mode 100644 index 9cc85b1d6d..0000000000 --- a/Submission_files/Default(13).css +++ /dev/null @@ -1 +0,0 @@ -/* Placeholder file required by the component structure */ \ No newline at end of file diff --git a/Submission_files/Default(13).js.download b/Submission_files/Default(13).js.download deleted file mode 100644 index 72d6b2e036..0000000000 --- a/Submission_files/Default(13).js.download +++ /dev/null @@ -1,5 +0,0 @@ -$(function () { - // SummaryWidget initialization - // Contact modal and widget management moved to ApplicationContactsWidget component -}); - diff --git a/Submission_files/Default(14).css b/Submission_files/Default(14).css deleted file mode 100644 index 17cc777f35..0000000000 --- a/Submission_files/Default(14).css +++ /dev/null @@ -1,152 +0,0 @@ -.scores-block label, -input { - display: block; -} - -.scores-block { - display: flex; - flex-wrap: wrap; - align-content: center; - justify-content: flex-start; - align-items: center; - gap: 5px; -} - -.scores-block-save { - flex-basis: 100%; - display: flex; - justify-content: flex-end; - margin: 5px 0px 5px 0px; -} - -.scores-block-wrapper { - display: inline-block; -} - -.assessment-scores-container .form-label { - font-size: var(--bc-font-size-sm); - color: var(--bc-colors-grey-text-300); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 0; -} -.assessment-sum { - margin-top: 2px; -} - -#assessment-scoresheet #section-button::after { - -webkit-filter: grayscale(1) invert(0); - filter: grayscale(1) invert(0); -} - -#assessment-scoresheet #section-button:not(.collapsed)::after { - -webkit-filter: grayscale(1); - filter: grayscale(1); -} - -#assessment-scoresheet .preview-btn:not(.collapsed) { - background-color: #3470b1; - color: #ffffff; -} - -.scoresheet-top-btn-group { - margin-top: 0; -} - -/* AI-generated answer styling (blue text) */ -.ai-generated-answer { - color: #0066cc !important; - background-color: rgba(0, 102, 204, 0.05); - border: 1px solid rgba(0, 102, 204, 0.2); -} - -.ai-generated-answer::placeholder { - color: #0066cc; - opacity: 0.7; -} - -/* Human-confirmed answer styling (black text) */ -.human-confirmed-answer { - color: #000000 !important; - background-color: #ffffff; - border: 1px solid #ced4da; -} - -/* AI indicator label */ -.ai-answer-indicator { - font-size: 0.75rem; - color: #0066cc; - font-style: italic; - margin-top: 2px; - display: flex; - align-items: center; - gap: 4px; -} - -.ai-confidence-score { - font-weight: bold; - padding: 2px 6px; - border-radius: 3px; - background-color: rgba(0, 102, 204, 0.1); - font-size: 0.7rem; -} - -/* AI citation styling */ -.ai-citation { - margin-top: 4px; - padding: 6px 8px; - background-color: rgba(0, 102, 204, 0.08); - border-left: 3px solid #0066cc; - border-radius: 0 4px 4px 0; - font-size: 0.8rem; - color: #004080; - line-height: 1.3; -} - -/* Low confidence answer styling */ -.low-confidence-answer { - border: 2px solid #f3c736 !important; - background-color: #fff3e0 !important; -} - -.low-confidence-indicator { - display: inline-block; - margin-left: 8px; - color: #f3c736; - font-size: 0.875rem; - font-weight: 600; -} - -.low-confidence-indicator i { - margin-right: 4px; -} - -/* Low confidence question styling (for accordion items) */ -.low-confidence-question { - border-left: 4px solid #f3c736 !important; - background-color: #fff8e1; -} - -.low-confidence-question .accordion-button { - background-color: #fff8e1 !important; -} - -.low-confidence-question .accordion-button:not(.collapsed) { - background-color: #ffe0b2 !important; -} - -.low-confidence-badge { - display: inline-flex; - align-items: center; - padding: 2px 8px; - background-color: #f3c736; - color: white; - border-radius: 4px; - font-size: 0.75rem; - font-weight: 600; -} - -.low-confidence-badge i { - margin-right: 4px; -} diff --git a/Submission_files/Default(14).js.download b/Submission_files/Default(14).js.download deleted file mode 100644 index 46971d8639..0000000000 --- a/Submission_files/Default(14).js.download +++ /dev/null @@ -1,3 +0,0 @@ -$(function () { - -}); diff --git a/Submission_files/Default(15).css b/Submission_files/Default(15).css deleted file mode 100644 index 895457a279..0000000000 --- a/Submission_files/Default(15).css +++ /dev/null @@ -1,203 +0,0 @@ - -.single-comment { - position: relative; - border-radius: 4px; - overflow: hidden; - border-left: 0.50px #D6D6D6 solid; - border-top: 0.50px #D6D6D6 solid; - border-right: 0.50px #D6D6D6 solid; - border-bottom: 1px #D6D6D6 solid; - padding: 10px 5px 5px 5px; - flex: 1; -} - -.single-comment.edit-mode { - width: 100%; -} - -.comment-input { - outline: 0; -} - - .comment-input:hover { - box-shadow: none !important; - } - - .comment-input.selected { - border: 0 !important; - outline: 0 !important; - border-bottom: 0.5px solid #D6D6D6 !important; - border-radius: 0px !important; - } - -.comment-button-container { - display: flex; - align-items: flex-end; - justify-content: right; - gap: 8px; -} - -.add-comment { - display: none; -} - -.edit-button { - cursor: pointer; - text-decoration: none; -} - -.comment-dropdown-toggle { - cursor: pointer; - padding: 0 0.5rem; - margin-top: -5px; - font-size: 1.25rem; - color: #666; - text-decoration: none; - line-height: 1; -} - -.comment-dropdown-toggle:hover, -.comment-dropdown-toggle:focus { - color: #333; - text-decoration: none; -} - -.dropdown-item.pin-button, -.dropdown-item.unpin-button { - padding: 0.5rem 1rem; - margin-left: 0; - color: #212529; -} - -.dropdown-item.pin-button:hover, -.dropdown-item.unpin-button:hover { - background-color: #f8f9fa; - color: #212529; -} - -.dropdown-item i { - font-size: 0.875rem; -} - -.comment-input-multiple:hover { - box-shadow: none !important; - border-bottom: 1.5px solid var(--bc-colors-grey-text-500) !important; -} - -.comment-input-multiple { - border-left: 0.50px #D6D6D6 solid; - border-top: 0.50px #D6D6D6 solid; - border-right: 0.50px #D6D6D6 solid; - border-bottom: 1px #D6D6D6 solid; - padding: 10px 5px 5px 5px; - flex: 1; -} - -.comment-time { - padding-top: 0.1rem; - font-size: 0.7rem; - font-style: normal; - font-weight: 400; - line-height: normal; - word-wrap: break-word; - color: var(--bc-colors-grey-text-300, #666); -} - -.comment-btn { - margin-top: 10px; - padding-left: 14px; - padding-right: 14px; - padding-top: 6px; - padding-bottom: 6px; - background: #E6EFF7; - border-radius: 3px; - cursor: pointer; - transition: box-shadow .3s; -} - - .comment-btn:hover { - box-shadow: -3px 3px 11px -3px rgba(33,33,33,.2); - } - -.comment-lbl { - display: block; - margin-top: 0.25rem; - width: 99%; - max-height: 180px; - overflow-y: scroll; - overflow-x: hidden; - position: relative; - font-size: var(--bc-font-size); -} - -.comment-edit-btn-wrapper { - display: flex; - justify-content: right; - align-items: start; - gap: 8px; -} - -.comment-lbl-wrapper { - color: #666666; - font-size: 0.89rem; - font-weight: 400; - word-wrap: break-word; -} - -.unity-comment-block { - background: var(--bc-surface--color--brand--gold--20); - padding: 0.75rem 0.5rem 0.5rem 1rem; - border-radius: 0.25rem; - font-size: var(--bc-font-size-xs); - color: var(--bc-colors-grey-text-300); - flex: 1; - width: 90%; -} - - .unity-comment-block .commented-time { - font-size: 0.875rem; - } - -.comment-read-mode { - display: flex; -} - - .comment-read-mode > .unity-user-initials { - margin-top: 0.5rem; - padding: 5px; - width: 22px; - height: 22px; - font-size: 0.45rem; - } - -.commenter-name { - font-size: var(--bc-font-size); -} - -.comment-with-mention { - min-height:120px; -} - -/* Pinned comment styles */ -.pinned-comment { - border-left: 4px solid var(--bs-primary-border-subtle); -} - -.pinned-comment.unity-comment-block { - background-color: var(--bs-primary-bg-subtle); - color: var(--bs-primary-text-emphasis); - border-radius: 0; -} - -.pinned-icon { - color: var(--bs-info-text-emphasis); - margin-right: 0.5rem; - font-size: 1rem; - vertical-align: middle; -} - -.pinned-time { - font-size: 0.75rem; - color: #92400e; - font-style: italic; -} diff --git a/Submission_files/Default(15).js.download b/Submission_files/Default(15).js.download deleted file mode 100644 index 23f509ab45..0000000000 --- a/Submission_files/Default(15).js.download +++ /dev/null @@ -1,625 +0,0 @@ -function saveScoresSection(formId, sectionId) { - const assessmentId = $('#AssessmentId').val(); - const secSaveButton = document.getElementById( - 'scoresheet-section-save-' + sectionId - ); - const secDiscardButton = document.getElementById( - 'scoresheet-section-discard-' + sectionId - ); - - const assessmentAnswersArr = []; - const inputFieldArr = []; - const origAnswersArr = []; - const formData = $(`#${formId}`).serializeArray(); - - //Handle form object data - $.each(formData, function (_, inputData) { - buildFormData( - assessmentAnswersArr, - inputData, - inputFieldArr, - origAnswersArr - ); - }); - - const data = { - AssessmentId: assessmentId, - AssessmentAnswers: assessmentAnswersArr.map( - ({ questionId, questionType, answer }) => ({ - questionId, - questionType, - answer, - }) - ), - }; - - //Calls an enpoint and disabled buttons - secSaveButton.disabled = true; - secDiscardButton.disabled = true; - unity.grantManager.assessments.assessment - .saveScoresheetSectionAnswers(data) - .done(function () { - abp.notify.success( - 'The answers have been saved successfully.', - 'Save Answers' - ); - - if (inputFieldArr.length > 0) { - for (let item of inputFieldArr) { - const inputField = document.getElementById(item); - inputField.setAttribute( - 'data-original-value', - inputField.value - ); - } - } - - updateSubtotal(); - PubSub.publish( - 'refresh_review_list_without_sidepanel', - assessmentId - ); - }) - .fail(function () { - secSaveButton.disabled = false; - secDiscardButton.disabled = false; - }); -} - -function markAsHumanConfirmed(inputElement) { - console.log('markAsHumanConfirmed inputElement', inputElement); - // Check if this was an AI-generated answer - const isHumanConfirmed = - inputElement.getAttribute('data-is-human-confirmed') === 'true'; - - if (!isHumanConfirmed) { - // Mark as human confirmed - inputElement.setAttribute('data-is-human-confirmed', 'true'); - - // Update styling from AI-generated to human-confirmed - inputElement.classList.remove('ai-generated-answer'); - inputElement.classList.add('human-confirmed-answer'); - - // Remove AI indicator if it exists - const aiIndicator = inputElement.parentElement.querySelector( - '.ai-answer-indicator' - ); - - if (aiIndicator) { - aiIndicator.remove(); - } - - // Remove low-confidence-badge from the question header (accordion button) - const questionAccordion = inputElement.closest('.accordion-item'); - if (questionAccordion) { - const lowConfidenceBadge = questionAccordion.querySelector( - '.low-confidence-badge' - ); - if (lowConfidenceBadge) { - lowConfidenceBadge.remove(); - } - - // Also remove the low-confidence-question class from the accordion item - questionAccordion.classList.remove('low-confidence-question'); - } - - // Log the change for potential tracking - console.log( - 'Answer marked as human-confirmed for element:', - inputElement.id - ); - } -} - -// Utility function to help debug AI answer integration -function debugAIAnswers() { - const aiAnswers = document.querySelectorAll( - '[data-is-human-confirmed="false"]' - ); - const humanAnswers = document.querySelectorAll( - '[data-is-human-confirmed="true"]' - ); - - console.log('=== AI Answer Integration Debug ==='); - console.log(`Found ${aiAnswers.length} AI-generated answers`); - console.log(`Found ${humanAnswers.length} human-confirmed answers`); - - // Focus on select lists specifically - const aiSelectLists = Array.from(aiAnswers).filter( - (el) => el.tagName === 'SELECT' - ); - const brokenSelectLists = aiSelectLists.filter( - (el) => el.value === '' || el.value === null - ); - - console.log( - `AI Select Lists: ${aiSelectLists.length} total, ${brokenSelectLists.length} broken` - ); - - brokenSelectLists.forEach((select) => { - console.log('Broken Select List:', { - id: select.id, - value: select.value, - selectedIndex: select.selectedIndex, - optionCount: select.options.length, - options: Array.from(select.options).map((opt) => ({ - value: opt.value, - text: opt.text, - })), - }); - }); - - aiAnswers.forEach((element) => { - console.log('AI Answer:', { - id: element.id, - tagName: element.tagName, - value: element.value, - hasAiClass: element.classList.contains('ai-generated-answer'), - hasIndicator: !!element.parentElement.querySelector( - '.ai-answer-indicator' - ), - }); - }); - - return { - aiCount: aiAnswers.length, - humanCount: humanAnswers.length, - brokenSelectCount: brokenSelectLists.length, - aiAnswers: Array.from(aiAnswers).map((el) => ({ - id: el.id, - tagName: el.tagName, - value: el.value, - })), - humanAnswers: Array.from(humanAnswers).map((el) => ({ - id: el.id, - tagName: el.tagName, - value: el.value, - })), - }; -} -function discardChangesScoresSection(formId, sectionId) { - const secSaveButton = document.getElementById( - 'scoresheet-section-save-' + sectionId - ); - const secDiscardButton = document.getElementById( - 'scoresheet-section-discard-' + sectionId - ); - - const assessmentAnswersArr = []; - const inputFieldArr = []; - const origAnswersArr = []; - const formData = $(`#${formId}`).serializeArray(); - - $.each(formData, function (_, inputData) { - buildFormData( - assessmentAnswersArr, - inputData, - inputFieldArr, - origAnswersArr - ); - }); - - //Handle dynamic data to bring back original values - if (inputFieldArr.length > 0) { - for (let item of inputFieldArr) { - let questionId = item.split('-').slice(2).join('-'); - const inputField = document.getElementById(item); - const originalValue = inputField.getAttribute( - 'data-original-value' - ); - inputField.value = originalValue; - - if ( - item.includes('answer-number-') || - item.includes('answer-text-') - ) { - const errorMessage = document.getElementById( - 'error-message-' + questionId - ); - errorMessage.textContent = ''; - } - } - } - - secSaveButton.disabled = true; - secDiscardButton.disabled = true; -} - -function buildFormData( - assessmentAnswersArr, - inputData, - inputFieldArr, - origAnswersArr -) { - const questionTypes = { - Number: 1, - Text: 2, - YesNo: 6, - SelectList: 12, - Textarea: 14, - }; - const n = 2; - const formAnsObj = {}; - const origAnsObj = {}; - const inputName = inputData.name.split('-'); - - if (formAnsObj[inputData.name.split('-')[0]] == '') { - formAnsObj['answer'] = null; - } - - if (inputName[0] === 'Answer') { - let answerValue = inputData.value; - let inputFieldValue = inputName.slice(0, n).join('-'); - let questionIdValue = inputName.slice(n).join('-'); - const questionTypeValue = - questionTypes[inputName.slice(1, n).join('-')]; - - if (questionTypeValue === 1 && !answerValue) { - answerValue = 0; - } - - let tempInputField = `${inputFieldValue.toLowerCase()}-${questionIdValue}`; - - origAnsObj['questionId'] = inputName.slice(n).join('-'); - origAnsObj['questionType'] = questionTypeValue; - origAnsObj['answer'] = $(`#${tempInputField}`).attr( - 'data-original-value' - ); - origAnsObj['isValid'] = true; - origAnsObj['isSame'] = true; - - formAnsObj['questionId'] = inputName.slice(n).join('-'); - formAnsObj['questionType'] = questionTypeValue; - formAnsObj['answer'] = answerValue; - formAnsObj['isValid'] = true; - formAnsObj['isSame'] = true; - - inputFieldArr.push(tempInputField); - origAnswersArr.push(origAnsObj); - assessmentAnswersArr.push(formAnsObj); - } -} - -function saveAssessmentScores() { - try { - let data = { - financialAnalysis: parseScoreValueInput('financialAnalysis'), - economicImpact: parseScoreValueInput('economicImpact'), - inclusiveGrowth: parseScoreValueInput('inclusiveGrowth'), - cleanGrowth: parseScoreValueInput('cleanGrowth'), - assessmentId: $('#AssessmentId').val(), - }; - unity.grantManager.assessments.assessment - .updateAssessmentScore(data) - .done(function () { - abp.notify.success('Assessment scores has been updated.'); - PubSub.publish('refresh_assessment_scores', null); - PubSub.publish( - 'refresh_review_list_without_sidepanel', - $('#AssessmentId').val() - ); - }); - } catch (error) { - console.log(error); - } -} - -function parseScoreValueInput(name) { - let control = '#' + name; - return $(control).val() == '' - ? 0 - : Math.min($(control).attr('max'), $(control).val()); -} - -function enableSaveButton(inputText) { - if (inputText.value.trim() != '') { - $('#saveAssessmentScoresBtn').prop('disabled', false); - } else { - $('#saveAssessmentScoresBtn').prop('disabled', true); - } - updateSum(); -} - -function updateSum() { - let financialAnalysis = $('#financialAnalysis').val() || 0; - let inclusiveGrowth = $('#inclusiveGrowth').val() || 0; - let cleanGrowth = $('#cleanGrowth').val() || 0; - let economicImpact = $('#economicImpact').val() || 0; - let sum = - parseInt(financialAnalysis) + - parseInt(inclusiveGrowth) + - parseInt(cleanGrowth) + - parseInt(economicImpact); - $('#subTotal').val(sum); -} - -function positiveIntegersOnly(e) { - if ( - e.keyCode === 9 || - e.keyCode === 8 || - e.keyCode === 37 || - e.keyCode === 39 - ) { - return true; - } - if (e.target?.value?.length >= 2) { - return false; - } - if ( - !( - (e.keyCode > 95 && e.keyCode < 106) || - (e.keyCode > 47 && e.keyCode < 58) || - e.keyCode == 8 - ) - ) { - return false; - } -} - -function compareObj(objA, objB) { - let res = true; - Object.keys(objB).forEach((key) => { - if (!objA.hasOwnProperty(key) || objA[key] !== objB[key]) { - res = false; - } - }); - return res; -} - -function handleInputChange(questionId, inputFieldPrefix) { - const sectionFormId = $(`#${inputFieldPrefix + questionId}`) - .closest('form') - .attr('id'); - let sectionId = - sectionFormId !== null - ? sectionFormId?.split('-').slice(2).join('-') - : null; - const secSaveButton = document.getElementById( - 'scoresheet-section-save-' + sectionId - ); - const secDiscardButton = document.getElementById( - 'scoresheet-section-discard-' + sectionId - ); - - const assessmentAnswersArr = []; - const inputFieldArr = []; - const origAnswersArr = []; - const formData = $(`#${sectionFormId}`).serializeArray(); - - $.each(formData, function (_, inputData) { - buildFormData( - assessmentAnswersArr, - inputData, - inputFieldArr, - origAnswersArr - ); - }); - - //Handle values and objects comparison - for (let x = 0; x < assessmentAnswersArr.length; x++) { - if (assessmentAnswersArr[x].questionType === 1) { - let inputNumberField = document.getElementById( - 'answer-number-' + assessmentAnswersArr[x].questionId - ); - let numberErrorMessage = document.getElementById( - 'error-message-' + assessmentAnswersArr[x].questionId - ); - assessmentAnswersArr[x].isValid = validateNumericField( - inputNumberField, - numberErrorMessage - ); - } else if (assessmentAnswersArr[x].questionType === 2) { - let inputTextField = document.getElementById( - 'answer-text-' + assessmentAnswersArr[x].questionId - ); - let textErrorMessage = document.getElementById( - 'error-message-' + assessmentAnswersArr[x].questionId - ); - - if (inputTextField.required) { - assessmentAnswersArr[x].isValid = validateTextField( - inputTextField, - textErrorMessage - ); - } - } - assessmentAnswersArr[x].isSame = compareObj( - assessmentAnswersArr[x], - origAnswersArr[x] - ); - } - - //Handle button events - let isNotSame = assessmentAnswersArr.some((item) => item.isSame === false); - let isInValid = assessmentAnswersArr.some((item) => item.isValid === false); - - if (isNotSame && isInValid) { - secSaveButton.disabled = true; - secDiscardButton.disabled = false; - } - - if (isNotSame && !isInValid) { - secSaveButton.disabled = false; - secDiscardButton.disabled = false; - } else { - secSaveButton.disabled = true; - } -} - -function validateTextField(textInputField, errorMessage) { - if ( - textInputField.validity.tooShort || - textInputField.validity.valueMissing - ) { - errorMessage.textContent = - 'The answer is too short. Minimum length is ' + - textInputField.minLength + - ' characters.'; - return false; - } else if (textInputField.validity.tooLong) { - errorMessage.textContent = - 'The answer is too long. Maximum length is ' + - textInputField.maxLength + - ' characters.'; - return false; - } else { - errorMessage.textContent = ''; - return true; - } -} - -function validateNumericField(numericInputField, errorMessage) { - if (numericInputField.validity.rangeOverflow) { - errorMessage.textContent = `Value must be less than or equal to ${numericInputField.max}.`; - return false; - } else if (numericInputField.validity.rangeUnderflow) { - errorMessage.textContent = `Value must be greater than or equal to ${numericInputField.min}.`; - return false; - } else { - errorMessage.textContent = ''; - return true; - } -} - -function updateSubtotal() { - setTimeout(function () { - let subtotal = 0; - - // Handle number inputs - const numberInputs = document.querySelectorAll('.answer-number-input'); - numberInputs.forEach((input) => { - subtotal += parseFloat(input.value) || 0; - }); - - // Handle Yes/No inputs - const yesNoInputs = document.querySelectorAll('.answer-yesno-input'); - yesNoInputs.forEach((input) => { - let value = 0; - if (input.value === 'Yes') { - value = - parseFloat(input.getAttribute('data-yes-numeric-value')) || - 0; - } else if (input.value === 'No') { - value = - parseFloat(input.getAttribute('data-no-numeric-value')) || - 0; - } - subtotal += value; - }); - - // Handle select list inputs - const selectListInputs = document.querySelectorAll( - '.answer-selectlist-input' - ); - selectListInputs.forEach((select) => { - const selectedOption = select.options[select.selectedIndex]; - const numericValue = - parseFloat(selectedOption.getAttribute('data-numeric-value')) || - 0; - subtotal += numericValue; - }); - - // Update the subtotal field - const subTotalField = document.getElementById('scoresheetSubtotal'); - if (subTotalField) { - subTotalField.value = subtotal; - } - }, 500); -} - -function discardChanges( - questionId, - inputFieldPrefix, - saveButtonPrefix, - discardButtonPrefix -) { - const inputField = document.getElementById(inputFieldPrefix + questionId); - const saveButton = document.getElementById(saveButtonPrefix + questionId); - const discardButton = document.getElementById( - discardButtonPrefix + questionId - ); - - const originalValue = inputField.getAttribute('data-original-value'); - inputField.value = originalValue; - - saveButton.disabled = true; - discardButton.disabled = true; - - if ( - inputFieldPrefix == 'answer-number-' || - inputFieldPrefix == 'answer-text-' - ) { - const errorMessage = document.getElementById( - 'error-message-' + questionId - ); - errorMessage.textContent = ''; - } -} - -function expandAllAccordions(divId) { - const accordions = document.querySelectorAll( - '#' + divId + ' .accordion-collapse' - ); - accordions.forEach((accordion) => { - accordion.classList.add('show'); - accordion.previousElementSibling - .querySelector('.accordion-button') - .classList.remove('collapsed'); - }); -} - -function collapseAllAccordions(divId) { - const accordions = document.querySelectorAll( - '#' + divId + ' .accordion-collapse' - ); - accordions.forEach((accordion) => { - accordion.classList.remove('show'); - accordion.previousElementSibling - .querySelector('.accordion-button') - .classList.add('collapsed'); - }); -} - -function queueApplicationScoring(triggerButton = null) { - const applicationId = $('#DetailsViewApplicationId').val(); - const $button = triggerButton ? $(triggerButton) : $('#regenerateAiScoresheetBtn'); - const existingHtml = $button.html(); - - if (!applicationId || $button.prop('disabled')) { - return; - } - - globalThis.AIGenerationButtonState?.setGenerating($button); - - const monitorScoring = () => globalThis.AIGenerationButtonState.monitor({ - $button, - originalHtml: existingHtml, - getStatus: () => unity.grantManager.grantApplications.grantApplication - .getAIGenerationStatus(applicationId, 'application-scoring'), - onComplete: () => PubSub.publish('refresh_assessment_scores', null), - onFailed: (request) => abp.message.error(request?.failureReason || 'AI scoring failed.') - }); - - unity.grantManager.grantApplications.grantApplication - .queueApplicationScoring(applicationId) - .done(function (request) { - const status = globalThis.AIGenerationButtonState?.resolveStatus(request?.status) ?? ''; - - if (status === 'Completed') { - globalThis.AIGenerationButtonState?.restore($button); - $button.html(existingHtml).prop('disabled', false); - PubSub.publish('refresh_assessment_scores', null); - globalThis.refreshAIRateLimitState?.(); - return; - } - - monitorScoring(); - }) - .fail(function () { - abp.message.error( - 'Failed to queue AI scoring. Please try again.' - ); - globalThis.AIGenerationButtonState?.restore($button); - $button.html(existingHtml).prop('disabled', false); - }); -} diff --git a/Submission_files/Default(16).css b/Submission_files/Default(16).css deleted file mode 100644 index 8d852c7702..0000000000 --- a/Submission_files/Default(16).css +++ /dev/null @@ -1,270 +0,0 @@ -#applicationEmailsWidget .single-email { - position: relative; - border-radius: 4px; - overflow: hidden; - border-left: 0.50px #D6D6D6 solid; - border-top: 0.50px #D6D6D6 solid; - border-right: 0.50px #D6D6D6 solid; - border-bottom: 1px #D6D6D6 solid; - padding: 10px 5px 5px 5px; - flex: 1; -} - -#applicationEmailsWidget .single-email.edit-mode { - width: 100%; -} - -#applicationEmailsWidget .email-input { - outline: 0; - margin-right: 8px; - margin-left: 8px; - margin-top: 2px; - margin-bottom: 2px; -} - - -#applicationEmailsWidget .email-form label { - color: var(--bc-colors-grey-text-300); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-left: 8px; - margin-bottom: 0; -} - -#applicationEmailsWidget .email-input:hover { - box-shadow: none !important; -} - -#applicationEmailsWidget .email-input.selected { - border: 0 !important; - outline: 0 !important; - border-bottom: 0.5px solid #D6D6D6 !important; - border-radius: 0px !important; -} - -#applicationEmailsWidget .email-button-container { - display: flex; - align-items: flex-end; - justify-content: right; - gap: 8px; -} - -#applicationEmailsWidget .email-input-multiple:hover { - box-shadow: none !important; - border-bottom: 1.5px solid var(--bc-colors-grey-text-500) !important; -} - -#applicationEmailsWidget .email-input::placeholder { - color: #b9b9b9 !important; -} - -#applicationEmailsWidget textarea::placeholder { - color: #b9b9b9 !important; -} - - -#applicationEmailsWidget .email-btn { - margin-top: 10px; - padding-left: 14px; - padding-right: 14px; - padding-top: 6px; - padding-bottom: 6px; - background: #E6EFF7; - border-radius: 3px; - cursor: pointer; - transition: box-shadow .3s; -} - -#applicationEmailsWidget .email-btn:hover { - box-shadow: -3px 3px 11px -3px rgba(33, 33, 33, .2); -} - -#applicationEmailsWidget .email-lbl { - display: block; - margin-top: 0.25rem; - width: 99%; - max-height: 180px; - overflow-y: scroll; - overflow-x: hidden; - position: relative; - font-size: var(--bc-font-size); -} - -#applicationEmailsWidget .email-lbl-wrapper { - color: #666666; - font-size: 0.89rem; - font-weight: 400; - word-wrap: break-word; -} - -#applicationEmailsWidget .unity-email-block { - background: var(--bc-surface--color--brand--gold--20); - padding: 0.75rem 0.5rem 0.5rem 1rem; - border-radius: 0.25rem; - font-size: var(--bc-font-size-xs); - color: var(--bc-colors-grey-text-300); - flex: 1; - width: 90%; -} - -#applicationEmailsWidget .field-validation-error { - margin-left: 8px; -} - -#applicationEmailsWidget .confirmation-label { - font-size: 19px; - font-weight: 600; - text-align: center; - align-content: center; - margin: 30px; - display: flex; - max-width: fit-content; - margin-left: auto; - margin-right: auto; - color: inherit; -} - -#confirmation-modal { - z-index: 1; - justify-content: center; - margin: 1em 1.6em .3em; - padding: 0; - overflow: auto; - color: inherit; - font-size: 1.125em; - font-weight: normal; - line-height: normal; - text-align: center; - word-wrap: break-word; - word-break: break-word; -} - -#btn-cancel-email { - border: 0; - border-radius: .25em; - background: initial; - background-color: #6e7881; - color: #fff; - font-size: 1em; - margin: 4px; -} - -#applicationEmailsWidget .btn-send-close { - margin: 4px; -} - -#applicationEmailsWidget #modal-background { - display: none; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, .8); - opacity: .50; - -webkit-opacity: .5; - -moz-opacity: .5; - filter: alpha(opacity=50); - z-index: 1000; -} - -#applicationEmailsWidget #modal-content { - display: none; -} - -#applicationEmailsWidget #spinner-modal { - display: none; -} - -#applicationEmailsWidget .modal-footer { - justify-content: center; -} - -#applicationEmailsWidget .modal-content { - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - height: fit-content; - left: 50%; - margin: -120px 0 0 -160px; - position: fixed; - top: 50%; - z-index: 1000; - box-sizing: border-box; - grid-template-columns: minmax(0, 100%); - width: 32em; - max-width: 100%; - padding: 1.25em; - border: none; - background: #fff; - color: #545454; - font-family: inherit; - font-size: 1rem; - justify-content: center; -} - - - -#EmailForm { - display: none; -} - -#EmailForm.active { - display: block; -} - -#applicationEmailsWidget .hide { - display: none; -} - -#applicationEmailsWidget .toast-top-center { - top: 220px; - margin: 0 auto; - left: 50%; - margin-left: -450px; -} - - -#applicationEmailsWidget #modal-background.active, -#applicationEmailsWidget #modal-content.active { - display: block; -} - -#applicationEmailsWidget #email-spinner { - width: 40px; - height: 40px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -20px; - margin-left: 40px; - border-radius: 50%; - border: 5px solid #eaf5fe; - border-right-color: #5597d4; - animation: rotateSpinner 800ms linear infinite; -} - -#applicationEmailsWidget .email-spinner-text { - display: flex; - padding-right: 100px; -} - -#applicationEmailsWidget button { - margin: 2px; - border: 1px solid var(--bc-colors-blue-primary); -} - -#applicationEmailsWidget .fl-cancel { - color: var(--bc-colors-blue-primary); -} - -#applicationEmailsWidget .btn-delete-draft { - background-color: white !important; -} - -@keyframes rotateSpinner { - to { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/Submission_files/Default(16).js.download b/Submission_files/Default(16).js.download deleted file mode 100644 index 83a614c099..0000000000 --- a/Submission_files/Default(16).js.download +++ /dev/null @@ -1,244 +0,0 @@ -// Fetch raw markdown for comment editing -async function fetchRawCommentMarkdown(commentId, ownerId, commentType) { - try { - const result = await unity.grantManager.comments.comment.get(commentId, { - ownerId: ownerId, - commentType: commentType - }); - return result.comment; - } catch (error) { - console.error('Error fetching raw comment:', error); - return null; - } -} - -$(function () { - const assigneeListElement = document.getElementById("assigneeListData"); - const assigneeList = JSON.parse(assigneeListElement.dataset.assignees); - const mentionDataList = assigneeList.map(item => ({ - key: item.FullName, - value: item.FullName, - email: item.Email, - })); - - initTribute(mentionDataList); - - $('body').on('click', '.edit-button', async function (e) { - e.preventDefault(); - let itemId = $(this).data('id'); - let ownerId = $(this).data('ownerid'); - let commentType = $(this).data('type'); - - // Fetch raw markdown from API for editing - const rawMarkdown = await fetchRawCommentMarkdown(itemId, ownerId, commentType); - if (rawMarkdown !== null) { - $(".comment-input-multiple[data-id='" + itemId + "']").val(rawMarkdown); - } - toggleEditMode(itemId); - }); - - $('body').on('focus', '.comment-input', function () { - $('#addCommentContainer' + $(this).data('ownerid')).css('display', 'flex'); - }); - - $('body').on('click', '.edit-comment-cancel-button', function () { - let itemId = $(this).data('id'); - toggleEditMode(itemId); - $(".comment-input-multiple[data-id='" + itemId + "']").val($(".comment-lbl[data-id='" + itemId + "']").text()); - }); - - $('body').on('click', '.edit-comment-save-button', function () { - const isEdit = true; - let itemId = $(this).data('id'); - const tempOwnerId = $(this).data('ownerid'); - const tempType = $(this).data('type'); - let editedValue = $(".comment-input-multiple[data-id='" + itemId + "']").val(); - const mentions = mentionDataList.filter(person => editedValue.includes(`@${person.value}`)); - - if (mentions.length > 0) { - const mentionedNamesEmail = mentions.map(m => m.email); - sendComment(isEdit, tempOwnerId, tempType, editedValue, mentionedNamesEmail, itemId, mentionDataList); - } else { - updateComment(tempOwnerId, itemId, editedValue, tempType, mentionDataList); - } - }); - - $('body').on('click', '.add-comment-save-button', function () { - const isEdit = false; - const tempOwnerId = $(this).data('ownerid'); - const tempType = $(this).data('type'); - const tempComment = $('#addCommentTextArea' + tempOwnerId).val(); - const mentions = mentionDataList.filter(person => tempComment.includes(`${person.value}`)); - - if (mentions.length > 0) { - const mentionedNamesEmail = mentions.map(m => m.email); - sendComment(isEdit, tempOwnerId, tempType, tempComment, mentionedNamesEmail, null, mentionDataList) - } else { - saveComment(tempOwnerId, tempComment, tempType, mentionDataList); - } - }); - - $('body').on('click', '.add-comment-cancel-button', function () { - let text = $('#addCommentTextArea' + $(this).data('ownerid')).val(); - if (text.length === 0) { - $('#addCommentContainer' + $(this).data('ownerid')).css('display', 'none'); - } - $('#addCommentTextArea' + $(this).data('ownerid')).val(''); - }); - - $('body').on('click', '.pin-button', function (e) { - e.preventDefault(); - let itemId = $(this).data('id'); - let ownerId = $(this).data('ownerid'); - let commentType = $(this).data('type'); - - pinComment(itemId, ownerId, commentType); - }); - - $('body').on('click', '.unpin-button', function (e) { - e.preventDefault(); - let itemId = $(this).data('id'); - let ownerId = $(this).data('ownerid'); - let commentType = $(this).data('type'); - - unpinComment(itemId, ownerId, commentType); - }); -}); - - -function toggleEditMode(itemId) { - $(".edit-mode[data-id='" + itemId + "']").toggle(); - let editedValue = $(".comment-input-multiple[data-id='" + itemId + "']").val(); - $(".comment-input-multiple[data-id='" + itemId + "']").val(editedValue.trim()); - $(".read-mode[data-id='" + itemId + "']").toggle(); -} - -function updateComment(ownerId, commentId, comment, commentType, mentionList) { - if (comment.length < 1) return; - try { - unity.grantManager.comments.comment - .update({ ownerId: ownerId, commentId: commentId, comment: comment, commentType: commentType }) - .done(function () { - abp.notify.success( - 'The comment has been updated.' - ); - toggleEditMode(commentId); - $(".comment-lbl[data-id='" + commentId + "']").text(comment); - PubSub.publish(commentType + '_refresh'); - setTimeout(() => { - initTribute(mentionList); - }, 500); - }); - } - catch (error) { - console.log(error); - } -} - -function saveComment(ownerId, comment, commentType, mentionList) { - if (comment.length < 1) return; - try { - unity.grantManager.comments.comment - .create({ ownerId: ownerId, comment: comment, commentType: commentType }) - .then((response) => { - return response; - }) - .done(function () { - abp.notify.success( - 'The comment has been created.' - ); - PubSub.publish(commentType + '_refresh'); - setTimeout(() => { - initTribute(mentionList); - }, 500); - }); - } - catch (error) { - console.log(error); - } -} - -function sendComment(tempIsEdit, tempOwnerId, tempCommentType, tempComment, tempMentionedNamesEmail, tempItemId, mentionList) { - const submissionNo = $(".reference-no").first().text().trim(); - const applicantName = $(".applicant-name").first().text().trim(); - const subject = submissionNo ? `${submissionNo}-${applicantName}` : applicantName; - - const requestData = { - subject: subject, - body: tempComment, - ownerId: tempOwnerId, - commentType: tempCommentType, - mentionNamesEmail: tempMentionedNamesEmail - }; - - return $.ajax({ - url: `/api/app/email-notification/send-comment-notification`, - type: "POST", - contentType: "application/json", - data: JSON.stringify(requestData), - }).then(response => { - if (tempIsEdit) { - updateComment(tempOwnerId, tempItemId, tempComment, tempCommentType, mentionList); - } else { - saveComment(tempOwnerId, tempComment, tempCommentType, mentionList); - } - }).catch(error => { - console.error('There was a problem with the post operation:', error); - }); -} - -function initTribute(mentionData) { - //Tributejs getting textarea dynamic id - const areaWithMentions = document.querySelectorAll('.comment-with-mention'); - - let tribute = new Tribute({ - values: mentionData, - selectTemplate: function (item) { - if (typeof item === 'undefined') return null; - if (this.range.isContentEditable(this.current.element)) { - return (`${item.original.value}`); - } - return `@${item.original.value}`; - }, - requireLeadingSpace: false, - }) - - areaWithMentions.forEach(item => { - tribute.attach(document.getElementById(item.id)); - }); -} -function pinComment(commentId, ownerId, commentType) { - abp.message.confirm( - 'Are you sure you want to pin this comment?', - 'Pin Comment', - function (confirmed) { - if (confirmed) { - unity.grantManager.comments.comment.pin(commentId, { - ownerId: ownerId, - commentType: commentType - }).then(function () { - abp.notify.success('Comment pinned successfully'); - - PubSub.publish(commentType + '_refresh'); - }).catch(function (error) { - abp.notify.error('Failed to pin comment'); - console.error(error); - }); - } - } - ); -} - -function unpinComment(commentId, ownerId, commentType) { - unity.grantManager.comments.comment.unpin(commentId, { - ownerId: ownerId, - commentType: commentType - }).then(function () { - abp.notify.success('Comment unpinned successfully'); - - PubSub.publish(commentType + '_refresh'); - }).catch(function (error) { - abp.notify.error('Failed to unpin comment'); - console.error(error); - }); -} diff --git a/Submission_files/Default(17).css b/Submission_files/Default(17).css deleted file mode 100644 index f5b40122c8..0000000000 --- a/Submission_files/Default(17).css +++ /dev/null @@ -1,60 +0,0 @@ -/* Fix for DataTables alignment with scrollX enabled */ -#ApplicationLinksTable_wrapper { - width: 100%; -} - -#ApplicationLinksTable_wrapper .dt-scroll { - overflow: visible; -} - -#ApplicationLinksTable_wrapper .dt-scroll-head .dt-scroll-headInner, -#ApplicationLinksTable_wrapper .dt-scroll-head .dt-scroll-headInner table { - width: 100% !important; -} - -#ApplicationLinksTable_wrapper .dt-scroll-body { - overflow: visible !important; -} - -#ApplicationLinksTable_wrapper .dt-scroll-body table { - width: 100% !important; -} - -/* Ensure table uses full width */ -#ApplicationLinksTable { - width: 100% !important; -} - -/* Column alignment */ -.links-table th, -.links-table td { - text-align: left; - vertical-align: middle; -} - -/* Delete button column */ -.links-table th:last-child, -.links-table td:last-child { - text-align: center; - width: 40px !important; - min-width: 40px !important; - max-width: 40px !important; -} - -/* Delete button styling */ -.links-table .delete-link-btn { - font-size: 1.2rem; - padding: 0.25rem 0.5rem; - text-decoration: none !important; -} - -.links-table .delete-link-btn:hover { - opacity: 0.7; - text-decoration: none !important; -} - -/* Ensure proper text wrapping in category column */ -.links-table td:first-child { - white-space: normal; - word-wrap: break-word; -} diff --git a/Submission_files/Default(17).js.download b/Submission_files/Default(17).js.download deleted file mode 100644 index 7a51887572..0000000000 --- a/Submission_files/Default(17).js.download +++ /dev/null @@ -1,1005 +0,0 @@ -$(function () { - const emptyGuid = '00000000-0000-0000-0000-000000000000'; - const UIElements = { - applicationId: $('#DetailsViewApplicationId')[0].value, - btnSend: $('#btn-send'), - btnSave: $('#btn-save'), - btnDiscard: $('#btn-send-discard'), - btnConfirmSend: $('#btn-confirm-send'), - btnCancelEmail: $('#btn-cancel-email'), - btnNewEmail: $('#btn-new-email'), - btnSendClose: $('#btn-send-close'), - emailForm: $('#EmailForm'), - inputEmailId: $('#EmailId'), - inputEmailTo: $($('#EmailTo')[0]), - inputEmailToField: $('#EmailTo')[0], - inputEmailCC: $($('#EmailCC')[0]), - inputEmailBCC: $($('#EmailBCC')[0]), - inputEmailFrom: $($('#EmailFrom')[0]), - inputEmailSubject: $($('#EmailSubject')[0]), - inputEmailBody: $($('#EmailBody')[0]), - inputOriginalEmailTo: $($('#OriginalDraftEmailTo')[0]), - inputOriginalEmailCC: $($('#OriginalDraftEmailCC')[0]), - inputOriginalEmailBCC: $($('#OriginalDraftEmailBCC')[0]), - inputOriginalEmailFrom: $($('#OriginalDraftEmailFrom')[0]), - inputOriginalEmailSubject: $($('#OriginalDraftEmailSubject')[0]), - inputOriginalEmailBody: $($('#OriginalDraftEmailBody')[0]), - emailSpinner: $('#spinner-modal'), - confirmationModal: $('#confirmation-modal'), - alertEmailReadonly: $('#email-alert-readonly') - }; - - let defaultValues = { - emailTo: '', - emailFrom: '', - emailCC: '', - emailBCC: '' - }; - let applicationDetails; - let mappingConfig; - let editorInstance; - let isNewEmailDraft = false; - let newDraftId = null; - let emailAttachmentsTable = null; - function bindUIEvents() { - UIElements.btnNewEmail.on('click', handleNewEmail); - UIElements.btnSend.on('click', handleSendEmail); - UIElements.btnSave.on('click', handleSaveEmail); - UIElements.btnDiscard.on('click', handleDiscardEmail); - UIElements.btnConfirmSend.on('click', handleConfirmSendEmail); - UIElements.btnCancelEmail.on('click', handleCancelEmailSend); - UIElements.btnSendClose.on('click', handleCloseEmail); - UIElements.inputEmailSubject.on('change', handleKeyUpTrim); - UIElements.inputEmailFrom.on('change', handleKeyUpTrim); - UIElements.inputEmailCC.on('change', handleKeyUpTrim); - UIElements.inputEmailBCC.on('change', handleKeyUpTrim); - UIElements.inputEmailBody.on('change', handleKeyUpTrim); - UIElements.inputEmailTo.on('change', validateEmailTo); - UIElements.inputEmailCC.on('change', validateEmailCC); - UIElements.inputEmailBCC.on('change', validateEmailBCC); - - UIElements.inputEmailTo.on('input', handleDraftChange); - UIElements.inputEmailCC.on('input', handleDraftChange); - UIElements.inputEmailBCC.on('input', handleDraftChange); - UIElements.inputEmailFrom.on('input', handleDraftChange); - UIElements.inputEmailSubject.on('input', handleDraftChange); - UIElements.inputEmailBody.on('input', handleDraftChange); - - $('.details-scrollable').on('scroll.emailWidget', function () { - $('.tox-toolbar__overflow').hide(); - }); - } - - init(); - - function init() { - bindUIEvents(); - defaultValues.emailTo = UIElements.inputOriginalEmailTo.val(); - defaultValues.emailFrom = UIElements.inputOriginalEmailFrom.val(); - defaultValues.emailCC = UIElements.inputOriginalEmailCC.val() || ''; - defaultValues.emailBCC = UIElements.inputOriginalEmailBCC.val() || ''; - if (window.toastr) { toastr.options.positionClass = 'toast-top-center'; } - initTemplateDetails(); - $('#templateTextContainer').hide(); - UIElements.btnSave.hide(); - UIElements.btnSend.hide(); - UIElements.btnDiscard.hide(); - UIElements.btnSendClose.hide(); - } - - async function initTemplateDetails() { - applicationDetails = await loadApplicationDetails(); - mappingConfig = await getTemplateVariables(); - } - - function disableEmail() { - UIElements.btnSend.attr('disabled', true); - UIElements.btnSave.attr('disabled', true); - UIElements.btnDiscard.attr('disabled', true); - UIElements.inputEmailTo.attr('disabled', true); - UIElements.inputEmailCC.attr('disabled', true); - UIElements.inputEmailBCC.attr('disabled', true); - UIElements.inputEmailFrom.attr('disabled', true); - UIElements.inputEmailSubject.attr('disabled', true); - UIElements.inputEmailBody.attr('disabled', true); - } - - function enableEmail() { - UIElements.btnSend.attr('disabled', false); - UIElements.btnSave.attr('disabled', false); - UIElements.btnDiscard.attr('disabled', false); - UIElements.inputEmailTo.attr('disabled', false); - UIElements.inputEmailCC.attr('disabled', false); - UIElements.inputEmailBCC.attr('disabled', false); - UIElements.inputEmailFrom.attr('disabled', false); - UIElements.inputEmailSubject.attr('disabled', false); - UIElements.inputEmailBody.attr('disabled', false); - } - - function handleKeyUpTrim(e) { - let trimmedString = e.currentTarget.value.trim(); - e.currentTarget.value = trimmedString; - } - - function closeEmailFormUI() { - $('#modal-content, #modal-background').removeClass('active'); - UIElements.emailForm.removeClass('active'); - UIElements.btnNewEmail.removeClass('hide'); - UIElements.alertEmailReadonly.removeClass('hide'); - UIElements.emailForm.trigger("reset"); - $('#email-attachments-section').hide(); - enableEmail(); - UIElements.btnSave.hide(); - UIElements.btnSend.hide(); - UIElements.btnDiscard.hide(); - UIElements.btnSendClose.hide(); - } - - function handleCloseEmail() { - if (isNewEmailDraft && newDraftId) { - $.ajax({ url: `/api/app/email-notification/${newDraftId}/email`, type: 'DELETE' }) - .catch(e => console.warn('Failed to delete draft on close:', e)); - isNewEmailDraft = false; - newDraftId = null; - } - closeEmailFormUI(); - } - - function handleDiscardEmail() { - UIElements.inputEmailTo.val(UIElements.inputOriginalEmailTo.val()); - UIElements.inputEmailCC.val(UIElements.inputOriginalEmailCC.val()); - UIElements.inputEmailBCC.val(UIElements.inputOriginalEmailBCC.val()); - UIElements.inputEmailFrom.val(UIElements.inputOriginalEmailFrom.val()); - UIElements.inputEmailSubject.val(UIElements.inputOriginalEmailSubject.val()); - UIElements.inputEmailBody.val(UIElements.inputOriginalEmailBody.val()); - } - - function handleCancelEmailSend() { - $('#modal-content, #modal-background').removeClass('active'); - } - - function getToolbarOptions() { - return 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist | link image | code preview'; - } - - function getPlugins() { - return 'lists link image preview code'; - } - function resetEmailBody() { - const id = 'EmailBody'; - - // 1. Remove any existing editor instance - if (tinymce.get(id)) { - tinymce.get(id).remove(); - } - - // 2. Clear the underlying ",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0=0;u--)f=t[u],n.type(f)==="string"&&r.transports[f]||(i.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(i.log("No transports remain within the specified transport array."),t=null)}else if(r.transports[t]||t==="auto"){if(t==="auto"&&r._.ieVersion<=8)return["longPolling"]}else i.log("Invalid transport: "+t.toString()+"."),t=null;return t}function b(n){return n==="http:"?80:n==="https:"?443:void 0}function a(n,t){return t.match(/:\d+$/)?t:t+":"+b(n)}function k(t,i){var u=this,r=[];u.tryBuffer=function(i){return t.state===n.signalR.connectionState.connecting?(r.push(i),!0):!1};u.drain=function(){if(t.state===n.signalR.connectionState.connected)while(r.length>0)i(r.shift())};u.clear=function(){r=[]}}var f={nojQuery:"jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.",noTransportOnInit:"No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.",errorOnNegotiate:"Error during negotiation request.",stoppedWhileLoading:"The connection was stopped during page load.",stoppedWhileNegotiating:"The connection was stopped during the negotiate request.",errorParsingNegotiateResponse:"Error parsing negotiate response.",errorRedirectionExceedsLimit:"Negotiate redirection limit exceeded.",errorDuringStartRequest:"Error during start request. Stopping the connection.",errorFromServer:"Error message received from the server: '{0}'.",stoppedDuringStartRequest:"The connection was stopped during the start request.",errorParsingStartResponse:"Error parsing start response: '{0}'. Stopping the connection.",invalidStartResponse:"Invalid start response: '{0}'. Stopping the connection.",protocolIncompatible:"You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.",aspnetCoreSignalrServer:"Detected a connection attempt to an ASP.NET Core SignalR Server. This client only supports connecting to an ASP.NET SignalR Server. See https://aka.ms/signalr-core-differences for details.",sendFailed:"Send failed.",parseFailed:"Failed at parsing response: {0}",longPollFailed:"Long polling request failed.",eventSourceFailedToConnect:"EventSource failed to connect.",eventSourceError:"Error raised by EventSource",webSocketClosed:"WebSocket closed.",pingServerFailedInvalidResponse:"Invalid ping response when pinging server: '{0}'.",pingServerFailed:"Failed to ping server.",pingServerFailedStatusCode:"Failed to ping server. Server responded with status code {0}, stopping the connection.",pingServerFailedParse:"Failed to parse ping server response, stopping the connection.",noConnectionTransport:"Connection is in an invalid state, there is no transport active.",webSocketsInvalidState:"The Web Socket transport is in an invalid state, transitioning into reconnecting.",reconnectTimeout:"Couldn't reconnect within the configured timeout of {0} ms, disconnecting.",reconnectWindowTimeout:"The client has been inactive since {0} and it has exceeded the inactivity timeout of {1} ms. Stopping the connection.",jsonpNotSupportedWithAccessToken:"The JSONP protocol does not support connections that require a Bearer token to connect, such as the Azure SignalR Service."};if(typeof n!="function")throw new Error(f.nojQuery);var r,h,o=t.document.readyState==="complete",e=n(t),c="__Negotiate Aborted__",u={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},v=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(t,i,r){return i===t.state?(t.state=r,n(t).triggerHandler(u.onStateChanged,[{oldState:i,newState:r}]),!0):!1},y=function(n){return n.state===r.connectionState.disconnected},l=function(n){return n._.keepAliveData.activated&&n.transport.supportsKeepAlive(n)},p=function(i){var f,e;i._.configuredStopReconnectingTimeout||(e=function(t){var i=r._.format(r.resources.reconnectTimeout,t.disconnectTimeout);t.log(i);n(t).triggerHandler(u.onError,[r._.error(i,"TimeoutException")]);t.stop(!1,!1)},i.reconnecting(function(){var n=this;n.state===r.connectionState.reconnecting&&(f=t.setTimeout(function(){e(n)},n.disconnectTimeout))}),i.stateChanged(function(n){n.oldState===r.connectionState.reconnecting&&t.clearTimeout(f)}),i._.configuredStopReconnectingTimeout=!0)};if(r=function(n,t,i){return new r.fn.init(n,t,i)},r._={defaultContentType:"application/x-www-form-urlencoded; charset=UTF-8",ieVersion:function(){var i,n;return t.navigator.appName==="Microsoft Internet Explorer"&&(n=/MSIE ([0-9]+\.[0-9]+)/.exec(t.navigator.userAgent),n&&(i=t.parseFloat(n[1]))),i}(),error:function(n,t,i){var r=new Error(n);return r.source=t,typeof i!="undefined"&&(r.context=i),r},transportError:function(n,t,r,u){var f=this.error(n,r,u);return f.transport=t?t.name:i,f},format:function(){for(var t=arguments[0],n=0;n<\/script>.");}},typeof e.on=="function")e.on("load",function(){o=!0});else e.load(function(){o=!0});r.fn=r.prototype={init:function(t,i,r){var f=n(this);this.url=t;this.qs=i;this.lastError=null;this._={keepAliveData:{},connectingMessageBuffer:new k(this,function(n){f.triggerHandler(u.onReceived,[n])}),lastMessageAt:(new Date).getTime(),lastActiveAt:(new Date).getTime(),beatInterval:5e3,beatHandle:null,totalTransportConnectTimeout:0,redirectQs:null};typeof r=="boolean"&&(this.logging=r)},_parseResponse:function(n){var t=this;return n?typeof n=="string"?t.json.parse(n):n:n},_originalJson:t.JSON,json:t.JSON,isCrossDomain:function(i,r){var u;return(i=n.trim(i),r=r||t.location,i.indexOf("http")!==0)?!1:(u=t.document.createElement("a"),u.href=i,u.protocol+a(u.protocol,u.host)!==r.protocol+a(r.protocol,r.host))},ajaxDataType:"text",contentType:"application/json; charset=UTF-8",logging:!1,state:r.connectionState.disconnected,clientProtocol:"2.1",supportedProtocols:["1.5","2.0","2.1"],negotiateRedirectSupportedProtocols:["2.0","2.1"],reconnectDelay:2e3,transportConnectTimeout:0,disconnectTimeout:3e4,reconnectWindow:3e4,keepAliveWarnAt:2/3,start:function(i,h){var a=this,v={pingInterval:3e5,waitForPageLoad:!0,transport:"auto",jsonp:!1},g,y=a._deferral||n.Deferred(),b=t.document.createElement("a"),nt=function(i,u){i.url===u&&i.baseUrl||(i.url=u,b.href=i.url,b.protocol&&b.protocol!==":"?(i.protocol=b.protocol,i.host=b.host):(i.protocol=t.document.location.protocol,i.host=b.host||t.document.location.host),i.baseUrl=i.protocol+"//"+i.host,i.wsProtocol=i.protocol==="https:"?"wss://":"ws://",i.url.indexOf("//")===0&&(i.url=t.location.protocol+i.url,i.log("Protocol relative URL detected, normalizing it to '"+i.url+"'.")),i.isCrossDomain(i.url)&&(i.log("Auto detected cross domain url."),v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]),typeof i.withCredentials=="undefined"&&(i.withCredentials=!0),n.support.cors||(i.ajaxDataType="jsonp",i.log("Using jsonp because this browser doesn't support CORS.")),i.contentType=r._.defaultContentType))},d,k;if(a.lastError=null,a._deferral=y,!a.json)throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.");if(n.type(i)==="function"?h=i:n.type(i)==="object"&&(n.extend(v,i),n.type(v.callback)==="function"&&(h=v.callback)),v.transport=w(v.transport,a),!v.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return(a._.config=v,!o&&v.waitForPageLoad===!0)?(a._.deferredStartHandler=function(){a.start(i,h)},e.bind("load",a._.deferredStartHandler),y.promise()):a.state===r.connectionState.connecting?y.promise():s(a,r.connectionState.disconnected,r.connectionState.connecting)===!1?(y.resolve(a),y.promise()):(p(a),v.transport==="auto"&&v.jsonp===!0&&(v.transport="longPolling"),a.withCredentials=v.withCredentials,a._originalUrl=a.url,a.ajaxDataType=v.jsonp?"jsonp":"text",nt(a,a.url),n(a).bind(u.onStart,function(){n.type(h)==="function"&&h.call(a);y.resolve(a)}),a._.initHandler=r.transports._logic.initHandler(a),g=function(i,o){var c=r._.error(f.noTransportOnInit);if(o=o||0,o>=i.length){o===0?a.log("No transports supported by the server were selected."):o===1?a.log("No fallback transports were selected."):a.log("Fallback transports exhausted.");n(a).triggerHandler(u.onError,[c]);y.reject(c);a.stop();return}if(a.state!==r.connectionState.disconnected){var p=i[o],h=r.transports[p],v=function(){g(i,o+1)};a.transport=h;try{a._.initHandler.start(h,function(){var f=r._.firefoxMajorVersion(t.navigator.userAgent)>=11,i=!0;a.log("The start request succeeded. Transitioning to the connected state.");l(a)&&r.transports._logic.monitorKeepAlive(a);a._.keepAliveData.activated&&r.transports._logic.startHeartbeat(a);r._.configurePingInterval(a);s(a,r.connectionState.connecting,r.connectionState.connected)||a.log("WARNING! The connection was not in the connecting state.");a._.connectingMessageBuffer.drain();n(a).triggerHandler(u.onStart);e.bind("unload",function(){a.log("Window unloading, stopping the connection.");a.stop(i)});f&&e.bind("beforeunload",function(){t.setTimeout(function(){a.stop(i)},0)})},v)}catch(w){a.log(h.name+" transport threw '"+w.message+"' when attempting to start.");v()}}},d=a.url+"/negotiate",k=function(t,i){var e=r._.error(f.errorOnNegotiate,t,i._.negotiateRequest);n(i).triggerHandler(u.onError,e);y.reject(e);i.stop()},n(a).triggerHandler(u.onStarting),d=r.transports._logic.prepareQueryString(a,d),a.log("Negotiating with '"+d+"'."),a._.negotiateRequest=function(){var t,h=0,w=100,i,e,o=[],s=[],l=function(n,t){var u=r.transports._logic.prepareQueryString(n,n.url+"/negotiate"),i;return n.log("Negotiating with '"+u+"'."),i={url:u,error:function(t,i){i!==c?k(t,n):y.reject(r._.error(f.stoppedWhileNegotiating,null,n._.negotiateRequest))},success:t},n.accessToken&&(i.headers={Authorization:"Bearer "+n.accessToken}),r.transports._logic.ajax(n,i)},p=function(c){try{t=a._parseResponse(c)}catch(d){k(r._.error(f.errorParsingNegotiateResponse,d),a);return}if(t.availableTransports){e=r._.error(f.aspnetCoreSignalrServer);n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(!t.ProtocolVersion||a.supportedProtocols.indexOf(t.ProtocolVersion)===-1){e=r._.error(r._.format(f.protocolIncompatible,a.clientProtocol,t.ProtocolVersion));n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(a.negotiateRedirectSupportedProtocols.indexOf(t.ProtocolVersion)!==-1){if(t.Error){e=r._.error(r._.format(f.errorFromServer,t.Error));n(a).triggerHandler(u.onError,[e]);y.reject(e);return}if(t.RedirectUrl){if(h===w){k(r._.error(f.errorRedirectionExceedsLimit),a);return}v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]);a.log("Received redirect to: "+t.RedirectUrl);a.accessToken=t.AccessToken;var b=t.RedirectUrl.split("?",2);if(nt(a,b[0]),a._.redirectQs=b.length===2?b[1]:null,a.ajaxDataType==="jsonp"&&a.accessToken){k(r._.error(f.jsonpNotSupportedWithAccessToken),a);return}h++;l(a,p);return}}i=a._.keepAliveData;a.appRelativeUrl=t.Url;a.id=t.ConnectionId;a.token=t.ConnectionToken;a.webSocketServerUrl=t.WebSocketServerUrl;a._.pollTimeout=t.ConnectionTimeout*1e3+1e4;a.disconnectTimeout=t.DisconnectTimeout*1e3;a._.totalTransportConnectTimeout=a.transportConnectTimeout+t.TransportConnectTimeout*1e3;t.KeepAliveTimeout?(i.activated=!0,i.timeout=t.KeepAliveTimeout*1e3,i.timeoutWarning=i.timeout*a.keepAliveWarnAt,a._.beatInterval=(i.timeout-i.timeoutWarning)/3):i.activated=!1;a.reconnectWindow=a.disconnectTimeout+(i.timeout||0);n.each(r.transports,function(n){if(n.indexOf("_")===0||n==="webSockets"&&!t.TryWebSockets)return!0;s.push(n)});n.isArray(v.transport)?n.each(v.transport,function(t,i){n.inArray(i,s)>=0&&o.push(i)}):v.transport==="auto"?o=s:n.inArray(v.transport,s)>=0&&o.push(v.transport);g(o)};return l(a,p)}(),y.promise())},starting:function(t){var i=this;return n(i).bind(u.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===r.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===r.connectionState.connecting)throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.");return t.transport.send(t,n),t},received:function(t){var i=this;return n(i).bind(u.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(u.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(u.onError,function(n,r,u){i.lastError=r;t.call(i,r,u)}),i},disconnected:function(t){var i=this;return n(i).bind(u.onDisconnect,function(){t.call(i)}),i},connectionSlow:function(t){var i=this;return n(i).bind(u.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(u.onReconnecting,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(u.onReconnect,function(){t.call(i)}),i},stop:function(i,h){var a=this,v=a._deferral;if(a._.deferredStartHandler&&e.unbind("load",a._.deferredStartHandler),delete a._.config,delete a._.deferredStartHandler,!o&&(!a._.config||a._.config.waitForPageLoad===!0)){a.log("Stopping connection prior to negotiate.");v&&v.reject(r._.error(f.stoppedWhileLoading));return}if(a.state!==r.connectionState.disconnected)return a.log("Stopping connection."),t.clearTimeout(a._.beatHandle),t.clearInterval(a._.pingIntervalId),a.transport&&(a.transport.stop(a),h!==!1&&a.transport.abort(a,i),l(a)&&r.transports._logic.stopMonitoringKeepAlive(a),a.transport=null),a._.negotiateRequest&&(a._.negotiateRequest.abort(c),delete a._.negotiateRequest),a._.initHandler&&a._.initHandler.stop(),delete a._deferral,delete a.messageId,delete a.groupsToken,delete a.id,delete a._.pingIntervalId,delete a._.lastMessageAt,delete a._.lastActiveAt,a._.connectingMessageBuffer.clear(),n(a).unbind(u.onStart),delete a.accessToken,delete a.protocol,delete a.host,delete a.baseUrl,delete a.wsProtocol,delete a.contentType,a.url=a._originalUrl,a._.redirectQs=null,s(a,a.state,r.connectionState.disconnected),n(a).triggerHandler(u.onDisconnect),a},log:function(n){v(n,this.logging)}};r.fn.init.prototype=r.fn;r.noConflict=function(){return n.connection===r&&(n.connection=h),r};n.connection&&(h=n.connection);n.connection=n.signalR=r})(window.jQuery,window),function(n,t,i){function s(n){n._.keepAliveData.monitoring&&l(n);u.markActive(n)&&(n._.beatHandle=t.setTimeout(function(){s(n)},n._.beatInterval))}function l(t){var i=t._.keepAliveData,u;t.state===r.connectionState.connected&&(u=(new Date).getTime()-t._.lastMessageAt,u>=i.timeout?(t.log("Keep alive timed out. Notifying transport that connection has been lost."),t.transport.lostConnection(t)):u>=i.timeoutWarning?i.userNotified||(t.log("Keep alive has been missed, connection may be dead/slow."),n(t).triggerHandler(f.onConnectionSlow),i.userNotified=!0):i.userNotified=!1)}function e(n,t){var i=n.url+t;return n.transport&&(i+="?transport="+n.transport.name),u.prepareQueryString(n,i)}function h(n){this.connection=n;this.startRequested=!1;this.startCompleted=!1;this.connectionStopped=!1}var r=n.signalR,f=n.signalR.events,c=n.signalR.changeState,o="__Start Aborted__",u;r.transports={};h.prototype={start:function(n,r,u){var f=this,e=f.connection,o=!1;if(f.startRequested||f.connectionStopped){e.log("WARNING! "+n.name+" transport cannot be started. Initialization ongoing or completed.");return}e.log(n.name+" transport starting.");n.start(e,function(){o||f.initReceived(n,r)},function(t){return o||(o=!0,f.transportFailed(n,t,u)),!f.startCompleted||f.connectionStopped});f.transportTimeoutHandle=t.setTimeout(function(){o||(o=!0,e.log(n.name+" transport timed out when trying to connect."),f.transportFailed(n,i,u))},e._.totalTransportConnectTimeout)},stop:function(){this.connectionStopped=!0;t.clearTimeout(this.transportTimeoutHandle);r.transports._logic.tryAbortStartRequest(this.connection)},initReceived:function(n,i){var u=this,f=u.connection;if(u.startRequested){f.log("WARNING! The client received multiple init messages.");return}u.connectionStopped||(u.startRequested=!0,t.clearTimeout(u.transportTimeoutHandle),f.log(n.name+" transport connected. Initiating start request."),r.transports._logic.ajaxStart(f,function(){u.startCompleted=!0;i()}))},transportFailed:function(i,u,e){var o=this.connection,h=o._deferral,s;this.connectionStopped||(t.clearTimeout(this.transportTimeoutHandle),this.startRequested?this.startCompleted||(s=r._.error(r.resources.errorDuringStartRequest,u),o.log(i.name+" transport failed during the start request. Stopping the connection."),n(o).triggerHandler(f.onError,[s]),h&&h.reject(s),o.stop()):(i.stop(o),o.log(i.name+" transport failed to connect. Attempting to fall back."),e()))}};u=r.transports._logic={ajax:function(t,i){return n.ajax(n.extend(!0,{},n.signalR.ajaxDefaults,{type:"GET",data:{},xhrFields:{withCredentials:t.withCredentials},contentType:t.contentType,dataType:t.ajaxDataType},i))},pingServer:function(t){var e,f,i=n.Deferred();return t.transport?(e=t.url+"/ping",e=u.addQs(e,t.qs),f=u.ajax(t,{url:e,headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},success:function(n){var u;try{u=t._parseResponse(n)}catch(e){i.reject(r._.transportError(r.resources.pingServerFailedParse,t.transport,e,f));t.stop();return}u.Response==="pong"?i.resolve():i.reject(r._.transportError(r._.format(r.resources.pingServerFailedInvalidResponse,n),t.transport,null,f))},error:function(n){n.status===401||n.status===403?(i.reject(r._.transportError(r._.format(r.resources.pingServerFailedStatusCode,n.status),t.transport,n,f)),t.stop()):i.reject(r._.transportError(r.resources.pingServerFailed,t.transport,n,f))}})):i.reject(r._.transportError(r.resources.noConnectionTransport,t.transport)),i.promise()},prepareQueryString:function(n,i){var r;return r=u.addQs(i,"clientProtocol="+n.clientProtocol),r=typeof n._.redirectQs=="string"?u.addQs(r,n._.redirectQs):u.addQs(r,n.qs),n.token&&(r+="&connectionToken="+t.encodeURIComponent(n.token)),n.data&&(r+="&connectionData="+t.encodeURIComponent(n.data)),r},addQs:function(t,i){var r=t.indexOf("?")!==-1?"&":"?",u;if(!i)return t;if(typeof i=="object")return t+r+n.param(i);if(typeof i=="string")return u=i.charAt(0),(u==="?"||u==="&")&&(r=""),t+r+i;throw new Error("Query string property must be either a string or object.");},getUrl:function(n,i,r,f,e){var h=i==="webSockets"?"":n.baseUrl,o=h+n.appRelativeUrl,s="transport="+i;return!e&&n.groupsToken&&(s+="&groupsToken="+t.encodeURIComponent(n.groupsToken)),r?(o+=f?"/poll":"/reconnect",!e&&n.messageId&&(s+="&messageId="+t.encodeURIComponent(n.messageId))):o+="/connect",o+="?"+s,o=u.prepareQueryString(n,o),n.transport&&n.accessToken&&(n.transport.name==="serverSentEvents"||n.transport.name==="webSockets")&&(o+="&access_token="+t.encodeURIComponent(n.accessToken)),e||(o+="&tid="+Math.floor(Math.random()*11)),o},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Initialized:typeof n.S!="undefined"?!0:!1,ShouldReconnect:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,GroupsToken:n.G,Error:n.E}},updateGroups:function(n,t){t&&(n.groupsToken=t)},stringifySend:function(n,t){return typeof t=="string"||typeof t=="undefined"||t===null?t:n.json.stringify(t)},ajaxSend:function(t,i){var h=u.stringifySend(t,i),c=e(t,"/send"),o,s=function(t,u){n(u).triggerHandler(f.onError,[r._.transportError(r.resources.sendFailed,u.transport,t,o),i])};return o=u.ajax(t,{url:c,type:t.ajaxDataType==="jsonp"?"GET":"POST",contentType:r._.defaultContentType,headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},data:{data:h},success:function(n){var i;if(n){try{i=t._parseResponse(n)}catch(r){s(r,t);t.stop();return}u.triggerReceived(t,i)}},error:function(n,i){i!=="abort"&&i!=="parsererror"&&s(n,t)}})},ajaxAbort:function(n,i){if(typeof n.transport!="undefined"){i=typeof i=="undefined"?!0:i;var r=e(n,"/abort"),f=n.accessToken?{Authorization:"Bearer "+n.accessToken}:{};t.fetch?t.fetch(r,{method:"POST",keepalive:!0,headers:f,credentials:n.withCredentials===!0?"include":"same-origin"}):u.ajax(n,{url:r,async:i,timeout:1e3,type:"POST",headers:f,dataType:"text"});n.log("Fired ajax abort async = "+i+".")}},ajaxStart:function(t,i){var h=function(n){var i=t._deferral;i&&i.reject(n)},s=function(i){t.log("The start request failed. Stopping the connection.");n(t).triggerHandler(f.onError,[i]);h(i);t.stop()};t._.startRequest=u.ajax(t,{url:e(t,"/start"),headers:t.accessToken?{Authorization:"Bearer "+t.accessToken}:{},success:function(n,u,f){var e;try{e=t._parseResponse(n)}catch(o){s(r._.error(r._.format(r.resources.errorParsingStartResponse,n),o,f));return}e.Response==="started"?i():s(r._.error(r._.format(r.resources.invalidStartResponse,n),null,f))},error:function(n,i,u){i!==o?s(r._.error(r.resources.errorDuringStartRequest,u,n)):(t.log("The start request aborted because connection.stop() was called."),h(r._.error(r.resources.stoppedDuringStartRequest,null,n)))}})},tryAbortStartRequest:function(n){n._.startRequest&&(n._.startRequest.abort(o),delete n._.startRequest)},tryInitialize:function(n,t,i){t.Initialized&&i?i():t.Initialized&&n.log("WARNING! The client received an init message after reconnecting.")},triggerReceived:function(t,i){t._.connectingMessageBuffer.tryBuffer(i)||n(t).triggerHandler(f.onReceived,[i])},processMessages:function(t,i,f){var e;if(i&&typeof i.I!="undefined"){u.triggerReceived(t,i);return}if(u.markLastMessage(t),i){if(e=u.maximizePersistentResponse(i),e.Error){t.log("Received an error message from the server: "+i.E);n(t).triggerHandler(r.events.onError,[r._.error(i.E,"ServerError")]);t.stop(!1,!1);return}u.updateGroups(t,e.GroupsToken);e.MessageId&&(t.messageId=e.MessageId);e.Messages&&(n.each(e.Messages,function(n,i){u.triggerReceived(t,i)}),u.tryInitialize(t,e,f))}},monitorKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring?t.log("Tried to monitor keep alive but it's already being monitored."):(i.monitoring=!0,u.markLastMessage(t),t._.keepAliveData.reconnectKeepAliveUpdate=function(){u.markLastMessage(t)},n(t).bind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+i.timeoutWarning+", keep alive timeout of "+i.timeout+" and disconnecting timeout of "+t.disconnectTimeout))},stopMonitoringKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring&&(i.monitoring=!1,n(t).unbind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t._.keepAliveData={},t.log("Stopping the monitoring of the keep alive."))},startHeartbeat:function(n){n._.lastActiveAt=(new Date).getTime();s(n)},markLastMessage:function(n){n._.lastMessageAt=(new Date).getTime();n._.lastActiveAt=n._.lastMessageAt},markActive:function(n){return u.verifyLastActive(n)?(n._.lastActiveAt=(new Date).getTime(),!0):!1},isConnectedOrReconnecting:function(n){return n.state===r.connectionState.connected||n.state===r.connectionState.reconnecting},ensureReconnectingState:function(t){return c(t,r.connectionState.connected,r.connectionState.reconnecting)===!0&&n(t).triggerHandler(f.onReconnecting),t.state===r.connectionState.reconnecting},clearReconnectTimeout:function(n){n&&n._.reconnectTimeout&&(t.clearTimeout(n._.reconnectTimeout),delete n._.reconnectTimeout)},verifyLastActive:function(t){if(!t._.keepAliveData.activated||(new Date).getTime()-t._.lastActiveAt0&&n--}}}();r.transports.foreverFrame={name:"foreverFrame",supportsKeepAlive:function(){return!0},iframeClearThreshold:50,start:function(n,r,e){if(n.accessToken){e&&(n.log("Forever Frame does not support connections that require a Bearer token to connect, such as the Azure SignalR Service."),e());return}var l=this,s=i.foreverFrame.count+=1,h,o=u(),c=function(){n.log("Forever frame iframe finished loading and is no longer receiving messages.");e&&e()||l.reconnect(n)};if(t.EventSource){e&&(n.log("Forever Frame is not supported by SignalR on browsers with SSE support."),e());return}o.setAttribute("data-signalr-connection-id",n.id);f.prevent();h=i.getUrl(n,this.name);h+="&frameId="+s;t.document.documentElement.appendChild(o);n.log("Binding to iframe's load event.");o.addEventListener?o.addEventListener("load",c,!1):o.attachEvent&&o.attachEvent("onload",c);o.src=h;i.foreverFrame.connections[s]=n;n.frame=o;n.frameId=s;r&&(n.onSuccess=function(){n.log("Iframe transport started.");r()})},reconnect:function(n){var r=this;i.isConnectedOrReconnecting(n)&&i.verifyLastActive(n)&&t.setTimeout(function(){if(i.verifyLastActive(n)&&n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'.");u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,u){var f,e,o;if(t.json!==t._originalJson&&(u=t._originalJson.stringify(u)),o=t._parseResponse(u),i.processMessages(t,o,t.onSuccess),t.state===n.signalR.connectionState.connected&&(t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>r.transports.foreverFrame.iframeClearThreshold&&(t.frameMessageCount=0,f=t.frame.contentWindow||t.frame.contentDocument,f&&f.document&&f.document.body)))for(e=f.document.body;e.firstChild;)e.removeChild(e.firstChild)},stop:function(n){var r=null;if(f.cancel(),n.frame){if(n.frame.stop)n.frame.stop();else try{r=n.frame.contentWindow||n.frame.contentDocument;r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(u){n.log("Error occurred when stopping foreverFrame transport. Message = "+u.message+".")}n.frame.parentNode===t.document.documentElement&&t.document.documentElement.removeChild(n.frame);delete i.foreverFrame.connections[n.frameId];n.frame=null;n.frameId=null;delete n.frame;delete n.frameId;delete n.onSuccess;delete n.frameMessageCount;n.log("Stopping forever frame.")}},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){o(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).triggerHandler(e.onReconnect)}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,e=n.signalR.changeState,f=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:function(){return!1},reconnectDelay:3e3,start:function(o,s,h){var a=this,v=function(){v=n.noop;o.log("LongPolling connected.");s?s():o.log("WARNING! The client received an init message after reconnecting.")},y=function(n){return h(n)?(o.log("LongPolling failed to connect."),!0):!1},c=o._,l=0,p=function(i){t.clearTimeout(c.reconnectTimeoutId);c.reconnectTimeoutId=null;e(i,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(i.log("Raising the reconnect event"),n(i).triggerHandler(u.onReconnect))},w=36e5;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop());o.messageId=null;c.reconnectTimeoutId=null;c.pollTimeoutId=t.setTimeout(function(){(function e(s,h){var g=s.messageId,nt=g===null,k=!nt,tt=!h,d=i.getUrl(s,a.name,k,tt,!0),b={};(s.messageId&&(b.messageId=s.messageId),s.groupsToken&&(b.groupsToken=s.groupsToken),f(s)!==!0)&&(o.log("Opening long polling request to '"+d+"'."),s.pollXhr=i.ajax(o,{xhrFields:{onprogress:function(){i.markLastMessage(o)}},url:d,type:"POST",contentType:r._.defaultContentType,data:b,timeout:o._.pollTimeout,headers:o.accessToken?{Authorization:"Bearer "+o.accessToken}:{},success:function(r){var h,w=0,u,a;o.log("Long poll complete.");l=0;try{h=o._parseResponse(r)}catch(b){i.handleParseFailure(s,r,b,y,s.pollXhr);return}(c.reconnectTimeoutId!==null&&p(s),h&&(u=i.maximizePersistentResponse(h)),i.processMessages(s,h,v),u&&n.type(u.LongPollDelay)==="number"&&(w=u.LongPollDelay),f(s)!==!0)&&(a=u&&u.ShouldReconnect,!a||i.ensureReconnectingState(s))&&(w>0?c.pollTimeoutId=t.setTimeout(function(){e(s,a)},w):e(s,a))},error:function(f,h){var v=r._.transportError(r.resources.longPollFailed,o.transport,f,s.pollXhr);if(t.clearTimeout(c.reconnectTimeoutId),c.reconnectTimeoutId=null,h==="abort"){o.log("Aborted xhr request.");return}if(!y(v)){if(l++,o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+h+". Response = "+f.responseText+"."),n(s).triggerHandler(u.onError,[v])),(o.state===r.connectionState.connected||o.state===r.connectionState.reconnecting)&&!i.verifyLastActive(o))return;if(!i.ensureReconnectingState(s))return;c.pollTimeoutId=t.setTimeout(function(){e(s,!0)},a.reconnectDelay)}}}),k&&h===!0&&(c.reconnectTimeoutId=t.setTimeout(function(){p(s)},Math.min(1e3*(Math.pow(2,l)-1),w))))})(o)},250)},lostConnection:function(n){n.pollXhr&&n.pollXhr.abort("lostConnection")},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){t.clearTimeout(n._.pollTimeoutId);t.clearTimeout(n._.reconnectTimeoutId);delete n._.pollTimeoutId;delete n._.reconnectTimeoutId;n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n){function r(n){return n+s}function c(n,t,i){for(var f=n.length,u=[],r=0;r=0}function i(n,t){return new i.fn.init(n,t)}function t(i,r){var u={qs:null,logging:!1,useDefaultPath:!0};return n.extend(u,r),(!i||u.useDefaultPath)&&(i=(i||"")+"/signalr"),new t.fn.init(i,u)}var o=0,s=".hubProxy",h=n.signalR;i.fn=i.prototype={init:function(n,t){this.state={};this.connection=n;this.hubName=t;this._={callbackMap:{}}},constructor:i,hasSubscriptions:function(){return u(this._.callbackMap)},on:function(t,i,u){var c=this,l=c._.callbackMap,v=!u&&e(i),f,h,s,a;for(u=u||i,u._signalRGuid||(u._signalRGuid=o++),t=t.toLowerCase(),f=l[t],f||(f=[],l[t]=f),s=0;s=0&&(t&&typeof t.then=="function"&&typeof t.catch=="function"?t.then(function(t){f(n,t)}).catch(function(t){s(n,t)}):t&&t.continueWith?t.continueWith(function(t){f(n,t)}):i.invoke("sys.callback",!1,[n,t]))},s=function(n,t){i.invoke("sys.callbackException",!1,[n,t])},e,o,i;typeof Promise=="function"?(o=function(n){n.continueWith=function(t){var i=n.then(t);return o(i),i}},e=function(){var n={id:i.generateId()};return n.promise=new Promise(function(t,i){n.setResult=t;n.setException=i}),o(n.promise),n}):e=function(){var n={id:i.generateId(),callback:null,promise:{continueWith:function(t){if(typeof t=="function")if(n.callback){var i=n.callback;n.callback=function(n){return t(i(n))}}else n.callback=t;return n.promise}},setResult:function(n){this.callback!==null&&this.callback(n)},setException:function(){}};return n};i={extensions:[],inits:[],callbackTable:[],nextId:0,connection:null,isReconnecting:!1,isUnloading:!1,extractName:function(n){var t=n.lastIndexOf("."),i=null,r=null;return t>0&&(i=n.substr(0,t).toLowerCase(),r=n.substr(t+1)),{factoryName:i,methodName:r}},log:function(){typeof console!="undefined"&&(window.console.debug?window.console.debug.apply(null,arguments):window.console.log&&window.console.log.apply(null,arguments))},invoke:function(n,i,r){var u={},h,f,c,o,l,s,a;u.name=n;u.args=r;u.callbackId=-1;i&&(f=e(),c=f.promise,this.callbackTable[f.id]=f,u.callbackId=f.id);h=t.stringify(u);try{for(o=this.breakIntoSegments(h),l=o.length>1?this.generateId():0,s=0;s0;)i=t>u?u:t,f.push(n.substring(r,r+i)),r+=i,t-=i;return f},dispatchCallback:function(n,t,i){var r=this.extractName(n),e,u,o,c;if(r.factoryName&&r.methodName){if(r.factoryName==="sys"){if(r.methodName==="callback"){e=t[0];u=t[1];try{this.callbackTable[e].setResult(u)}catch(h){this.log("Failed to invoke return value callback:\n"+h.toString())}this.removeTask(e)}if(r.methodName==="callbackException"){e=t[0];u=t[1];try{this.callbackTable[e].setException(new Error(u).toString())}catch(h){this.log("Failed to invoke exception handler callback:\n"+h.toString())}this.removeTask(e)}return}if(o=this.extensions[r.factoryName],!o||!o[r.methodName]){this.log("Failed to match method call "+n);return}for(c=t.length;c<15;c++)t[c]=null;try{u=o[r.methodName](t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14])}catch(h){u=undefined;this.log("Exception thrown in callback method "+r.methodName+": %o",h);s(i,h.toString())}typeof u!="undefined"&&f(i,u)}},addExtensions:function(){try {{ var extension = -(function(n){"use strict";return{log:function(t){n.log(t)}}});; -this.addExtension("Microsoft.WebTools.BrowserLink.CoreExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.CoreExtensionFactory'."); return; }} -try {{ var extension = -(function(n,t){"use strict";var f=[],i=[],h=function(n){for(var i,t=0;t=i.originalStart&&t<=i.originalStart+i.originalLength},o=function(n,t){return e(n,function(n){return n.type!=1?!1:y(n,t)})},it=function(n,t,i){return e(n,function(n){var u=r(n);return u&&typeof u.originalStart!="undefined"&&u.originalStart==t&&u.originalLength==i})},p=function(n){var t=s(n);return{index:t.length,source:n,collection:t}},w=function(n,t){var r=n.index-1,i;return r>=0&&(i=n.collection[r],i.type==4&&y(i,t))?(n=p(i),w(n,t)):n},rt=function(n,t){var i=e(n,function(n){var i=r(n);return i&&typeof i.originalStart!="undefined"&&t=0;r--)if(f=t.children[r],u=n(f,i),u)return u;return t.getDomNode()===i?{logicalNode:t}:t.getDomNode()?{foundOtherDomNode:!0}:null},u=function(t,r){for(var o,f,e=t.parent,s=e.children.indexOf(t),u=s-1;u>=0;u--)if(o=e.children[u],f=n(o,r),i,f)return f;return null},t=function(n,i){var r=u(n,i);return r?r:n.parent?n.parent.getDomNode()===i?{logicalNode:n.parent}:n.parent.getDomNode()?{foundOtherDomNode:!0}:t(n.parent,i):null},r=function(n){return o.innerHTML=n,o.innerHTML},f=function(n){for(var f,t=n.__browserLink_LogicalNodes.slice(),u="",i=0;i1&&u==n.textContent?!0:!1},e=function(n){for(var f,e,t=n.__browserLink_LogicalNodes.slice(),i=n,u=0;u0&&(t=n.indexOf(this),t>=0&&n.splice(t,1))};this.setupRelatedDomNode=function(){var n,i;this.domNode.__browserLink_LogicalNodes?(n=t(this,this.domNode),n&&n.logicalNode?(i=this.domNode.__browserLink_LogicalNodes.indexOf(n.logicalNode),this.domNode.__browserLink_LogicalNodes.splice(i+1,0,this)):this.domNode.__browserLink_LogicalNodes.splice(0,0,this),this.domNode.nodeType===Node.TEXT_NODE&&f(this.domNode)&&e(this.domNode)):this.domNode.__browserLink_LogicalNodes=[this]};this.setDomNode=function(n){this.domNode!==n&&(this.domNode&&this.disconnectRelatedDomNode(),this.domNode=n,this.domNode&&this.setupRelatedDomNode())}}function ht(){var f,e;this.root={};var u="\0",s=1,h={},k=this;this.createNewLogicalNode=function(n,t,i,r){var u=new d,f,e;return n&&(u.type=n),t&&u.setDomNode(t),i&&(u.parent=i,n===st.Attribute?i.attributes.push(u):(f=r?i.children.indexOf(r):-1,f>=0?(e=f+1,i.children.splice(e,0,u)):i.children.splice(0,0,u))),u};var c=function(n){var r=t.extend(new d,n),i,u,f;if(n.children)for(i=0;i0&&(r=h[i],n.setDomNode(r)),n.children)for(t=0;t=i?e>=o?(u=i,f=0,s=0):e>u?(u=i,f=o-e,s=e>=h?0:h-e):u+=r:h>i?(e>h?s=i-u:s+=r,e>o?f=i-u:f+=r):o>i&&(e>o?f=i-u:f+=r);n.start.position=u;n.length=f;n.startTagLength&&(n.startTagLength=s);w(n,t,i,r)}};this.buildDocumentBlockList=function(){var t=[];y(document,t);n.invoke("UpdateBlockListFromDOM",n.initializationData.requestId,t)};this.initialize=function(t){o==null&&(o=document.createElement("textarea"));this.root=c(t.root);v(this.root);g();a=!0;n.sourceMapping.ensureUpToDateAsync(null)};this.applyChangesInFile=function(n,t){while(t.length>=2){var i=t.shift(),r=t.shift();b(this.root,n,i,r)}};this.getLogicalNodesFromDomNode=function(n){return n&&n.__browserLink_LogicalNodes?n.__browserLink_LogicalNodes:[]};this.getFirstLogicalNodeFromDomNode=function(n){var t=this.getLogicalNodesFromDomNode(n);return t&&t.length>0?t[0]:null};this.getAllNodesStartingAtPosition=function(n,t){var i=[];return f(n,t,this.root,i),i};f=function(n,t,i,r){var e,u,o;if(i){if(i.start&&t===i.start.position&&n===i.start.path&&r.push(i),i.children)for(u=0;u=i.start.position&&t=f.length)&&(r=f);if(i.attributes)for(u=0;u=f.length)&&(r=f);return r}}function ct(){var o=this,l=function(n){return w(n)},v=function(n,t,r){if(n0)return i.Task;for(u=c,c=[],t=0;t0?t.Task:f.length==0?t.Task:(ot(function(){var t=f,n;for(f=[],n=0;n=t-u.start)return i.cssRules[r];break}return null};this.getAllSourcePaths=function(){return i};this.internal={addMappingRangeForObject:function(n,t){var r=e(t.sourcePath||t.sourceUrl),i={sourceIndex:r,start:t.startPosition,length:t.length};b(n,i);u.push(i)}};t=7e3;s=[];this.validateStyleSheet=function(i){var u=s.indexOf(i.href)>=0,r;return u?!1:(r=function(n){var u=0,f,e;try{if(n&&n.cssRules&&(u+=i.cssRules.length,u>t))return u;for(f=0;ft))break;return u}catch(o){return t+1}},r(i)>t)?(s.push(i.href),n.log(`CSS Hot Reload ignoring ${i.href} because it was inaccessible or had more than ${t} rules.`),!1):!0}}var i=[],s={},h=!1,a=!1,r=0,f=[],c=[],u=[],v={},y=function(){var n=[];this.complete=function(){for(var t=null;n.length;)t=n.shift()(t)};this.Task={continueWith:function(t){n.push(t)}}},rt=function(n){return n.selectorText||n.media},p=function(n){var r=rt(n),t,i,u;if(!r)return{value:null};for(t=v[r],t||(t=[],v[r]=t),i=0;i=t?f>=o?(r=t,u=0,e=0):f>r?(u=o-f,r=t,e=f>=s?0:s-f):r+=i:s>t?(f>s?e=t-r:e+=i,f>o?u=t-r:u+=i):o>t&&(f>o?u=t-r:u+=i);n.start=r;n.length=u;n.startTag&&(n.startTag=e)},et=function(n,t){for(var f,e,i,r;t.length>=2;)for(f=t.shift(),e=t.shift(),i=0;i=2?s[1]:{},i={selectorData:r,sourceIndex:f[0]+t,start:f[1],length:f[2],isLiteral:f[3],startTag:f.length>=5?f[4]:null,children:g(l.children,t),ancestors:g(l.ancestors,t)},l.templateLike&&o.length==2&&(r.isTemplateLike=!0,r.isInTemplateLike=!0),e=0;e0))for(i=document.styleSheets,t=0;t=0?(et(r,t),!0):!1},applyChangesInFileToLogicalTree:function(t,i){n.logicalTree.applyChangesInFile(t,i)},onConnected:function(){Array.prototype.indexOf&&(n.logicalTree.buildDocumentBlockList(),n.sourceMapping.ensureUpToDateAsync(null))},setLogicalTree:function(t,r){i=i.concat(r);n.logicalTree.initialize(t)}}});; -this.addExtension("Microsoft.WebTools.BrowserLink.SourceMappingExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.SourceMappingExtensionFactory'."); return; }} -try {{ var extension = -(function(){"use strict";return{refresh:function(){location.reload(!0)},navigate:function(n){location.href=n}}});; -this.addExtension("Microsoft.WebTools.BrowserLink.Package.RefreshExtensionFactory", extension); }} catch(e) {{ this.log("Invalid extension script encountered for extension 'Microsoft.WebTools.BrowserLink.Package.RefreshExtensionFactory'."); return; }} -},generateId:function(){return this.nextId++,this.nextId<0&&(this.nextId=0),this.nextId},removeTask:function(n){delete this.callbackTable[n]},addExtension:function(f,e){var o={},s,h,c,l;if(typeof e!="function"){this.log("Extension function definition was not defined as a function object.");return}h=function(n,t){if(typeof n=="undefined")throw new Error("Browser Link: Method call failed, missing method name argument.");if(!t)throw new Error('Method call failed, missing class name. Use the format "namespace."methodName"');return t+"."+n};c=function(n){for(var i=[],t=1;t=0||navigator.userAgent.search(/trident/i)>=0?!0:!1},r()&&(u=window.location,t=window.document.createElement("a"),t.href=n,i=function(n){return n&&n.indexOf(".")<0?!0:!1},i(t.hostname)&&!i(u.hostname)))return!1;try{return f=new XMLHttpRequest,f.open("get",n),!0}catch(e){return!1}};o(i.connection.url)?i.connection.start().done(f):i.connection.start({transport:"longPolling",jsonp:!0}).done(f)}};n(window).on("beforeunload",function(){i.isUnloading=!0});if(i.initialize(),window._vwdonbeforeunload)n(window).on("beforeunload",window._vwdonbeforeunload)})($.noConflict(!0),JSON);window._vwdJSON&&(JSON=window._vwdJSON);window._vwdDefine&&(define=window._vwdDefine); \ No newline at end of file diff --git a/Submission_files/buttons.bootstrap5.js.download b/Submission_files/buttons.bootstrap5.js.download deleted file mode 100644 index b5e5ce494d..0000000000 --- a/Submission_files/buttons.bootstrap5.js.download +++ /dev/null @@ -1,122 +0,0 @@ -/*! Bootstrap integration for DataTables' Buttons - * © SpryMedia Ltd - datatables.net/license - */ - -(function( factory ){ - if ( typeof define === 'function' && define.amd ) { - // AMD - define( ['jquery', 'datatables.net-bs5', 'datatables.net-buttons'], function ( $ ) { - return factory( $, window, document ); - } ); - } - else if ( typeof exports === 'object' ) { - // CommonJS - var jq = require('jquery'); - var cjsRequires = function (root, $) { - if ( ! $.fn.dataTable ) { - require('datatables.net-bs5')(root, $); - } - - if ( ! $.fn.dataTable.Buttons ) { - require('datatables.net-buttons')(root, $); - } - }; - - if (typeof window === 'undefined') { - module.exports = function (root, $) { - if ( ! root ) { - // CommonJS environments without a window global must pass a - // root. This will give an error otherwise - root = window; - } - - if ( ! $ ) { - $ = jq( root ); - } - - cjsRequires( root, $ ); - return factory( $, root, root.document ); - }; - } - else { - cjsRequires( window, jq ); - module.exports = factory( jq, window, window.document ); - } - } - else { - // Browser - factory( jQuery, window, document ); - } -}(function( $, window, document ) { -'use strict'; -var DataTable = $.fn.dataTable; - - - -$.extend(true, DataTable.Buttons.defaults, { - dom: { - container: { - className: 'dt-buttons btn-group flex-wrap' - }, - button: { - className: 'btn btn-secondary', - active: 'active', - dropHtml: '', - dropClass: 'dropdown-toggle' - }, - collection: { - container: { - tag: 'div', - className: 'dt-button-collection', - content: { - tag: 'ul', - className: 'dropdown-menu show' - } - }, - closeButton: false, - button: { - tag: 'li', - className: 'dt-button', - active: 'dt-button-active-a', - disabled: 'disabled', - liner: { - tag: 'a', - className: 'dropdown-item' - }, - spacer: { - className: 'divider', - tag: 'li' - } - } - }, - split: { - action: { - tag: 'a', - className: 'btn btn-secondary dt-button-split-drop-button', - closeButton: false - }, - dropdown: { - tag: 'button', - className: - 'btn btn-secondary dt-button-split-drop dropdown-toggle-split', - closeButton: false, - align: 'split-left', - splitAlignClass: 'dt-button-split-left' - }, - wrapper: { - tag: 'div', - className: 'dt-button-split btn-group', - closeButton: false - } - } - }, - buttonCreated: function (config, button) { - return config.buttons ? $('
').append(button) : button; - } -}); - -DataTable.ext.buttons.collection.rightAlignClassName = 'dropdown-menu-right'; - - -return DataTable; -})); diff --git a/Submission_files/buttons.bootstrap5.min.css b/Submission_files/buttons.bootstrap5.min.css deleted file mode 100644 index 6c0c20c93c..0000000000 --- a/Submission_files/buttons.bootstrap5.min.css +++ /dev/null @@ -1 +0,0 @@ -@keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dataTables_wrapper{position:relative}div.dt-buttons{position:initial}div.dt-buttons .dt-button{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border-radius:.75em;box-shadow:3px 4px 10px 1px rgba(0, 0, 0, 0.8);text-align:center;z-index:2003;overflow:hidden}div.dt-button-info h2{padding:2rem 2rem 1rem 2rem;margin:0;font-weight:normal}div.dt-button-info>div{padding:1em 2em 2em 2em}div.dtb-popover-close{position:absolute;top:6px;right:6px;width:22px;height:22px;text-align:center;border-radius:3px;cursor:pointer;z-index:2003}button.dtb-hide-drop{display:none !important}div.dt-button-collection-title{text-align:center;padding:.3em .5em .5em;margin-left:.5em;margin-right:.5em;font-size:.9em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}div.dt-button-collection-title:empty{display:none}span.dt-button-spacer{display:inline-block;margin:.5em;white-space:nowrap}span.dt-button-spacer.bar{border-left:1px solid rgba(0, 0, 0, 0.3);vertical-align:middle;padding-left:.5em}span.dt-button-spacer.bar:empty{height:1em;width:1px;padding-left:0}div.dt-button-collection .dt-button-active{padding-right:3em}div.dt-button-collection .dt-button-active:after{position:absolute;top:50%;margin-top:-10px;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection .dt-button-active.dt-button-split{padding-right:0}div.dt-button-collection .dt-button-active.dt-button-split:after{display:none}div.dt-button-collection .dt-button-active.dt-button-split>*:first-child{padding-right:3em}div.dt-button-collection .dt-button-active.dt-button-split>*:first-child:after{position:absolute;top:50%;margin-top:-10px;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection .dt-button-active-a a{padding-right:3em}div.dt-button-collection .dt-button-active-a a:after{position:absolute;right:1em;display:inline-block;content:"✓";color:inherit}div.dt-button-collection span.dt-button-spacer{width:100%;font-size:.9em;text-align:center;margin:.5em 0}div.dt-button-collection span.dt-button-spacer:empty{height:0;width:100%}div.dt-button-collection span.dt-button-spacer.bar{border-left:none;border-bottom:1px solid rgba(0, 0, 0, 0.1);padding-left:0}@media print{table.dataTable tr>*{box-shadow:none !important}}div.dt-buttons div.btn-group{position:initial}div.dt-buttons span.dt-button-spacer.empty{margin:1px}div.dt-buttons span.dt-button-spacer.bar:empty{height:inherit}div.dt-buttons .btn.processing{color:rgba(0, 0, 0, 0.2)}div.dt-buttons .btn.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:" ";border:2px solid rgb(40, 40, 40);border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear}div.dt-button-collection{position:absolute;min-width:200px;margin-top:4px;z-index:2002;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);box-shadow:var(--bs-box-shadow)}div.dt-button-collection div.dt-button-collection-title{padding:.75em 0 .25em}div.dt-button-collection .dropdown-menu{position:relative;display:block;width:100%;background-color:transparent;border:none;border-radius:0;box-shadow:none}div.dt-button-collection .dt-button{position:relative}div.dt-button-collection .dt-button.dropdown-toggle::after{position:absolute;right:12px;top:14px}div.dt-button-collection div.dt-button-split{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:stretch}div.dt-button-collection div.dt-button-split>*:first-child{min-width:auto;flex:1 0 50px}div.dt-button-collection div.dt-button-split button:last-child{min-width:33px;flex:0;background:transparent;border:none;line-height:1rem;color:var(--bs-dropdown-link-color);padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);overflow:visible}div.dt-button-collection div.dt-button-split button:last-child:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}div.dt-button-collection.fixed{position:fixed;display:block;top:50%;left:50%;margin-left:-75px;border-radius:5px;background-color:white;padding:.5em}div.dt-button-collection.fixed.two-column{margin-left:-200px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection.fixed.columns{margin-left:-409px}@media screen and (max-width: 1024px){div.dt-button-collection.fixed.columns{margin-left:-308px}}@media screen and (max-width: 640px){div.dt-button-collection.fixed.columns{margin-left:-203px}}@media screen and (max-width: 460px){div.dt-button-collection.fixed.columns{margin-left:-100px}}div.dt-button-collection.fixed>:last-child{max-height:100vh;overflow:auto}div.dt-button-collection.two-column>:last-child,div.dt-button-collection.three-column>:last-child,div.dt-button-collection.four-column>:last-child{display:block !important;column-gap:8px}div.dt-button-collection.two-column>:last-child>*,div.dt-button-collection.three-column>:last-child>*,div.dt-button-collection.four-column>:last-child>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:400px}div.dt-button-collection.two-column>:last-child{padding-bottom:1px;column-count:2}div.dt-button-collection.three-column{width:450px}div.dt-button-collection.three-column>:last-child{padding-bottom:1px;column-count:3}div.dt-button-collection.four-column{width:600px}div.dt-button-collection.four-column>:last-child{padding-bottom:1px;column-count:4}div.dt-button-collection .dt-button{border-radius:0}div.dt-button-collection.columns{width:auto}div.dt-button-collection.columns>:last-child{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:6px;width:818px;padding-bottom:1px}div.dt-button-collection.columns>:last-child .dt-button{min-width:200px;flex:0 1;margin:0}div.dt-button-collection.columns.dtb-b3>:last-child,div.dt-button-collection.columns.dtb-b2>:last-child,div.dt-button-collection.columns.dtb-b1>:last-child{justify-content:space-between}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:1 1 32%}div.dt-button-collection.columns.dtb-b2 .dt-button{flex:1 1 48%}div.dt-button-collection.columns.dtb-b1 .dt-button{flex:1 1 100%}@media screen and (max-width: 1024px){div.dt-button-collection.columns>:last-child{width:612px}}@media screen and (max-width: 640px){div.dt-button-collection.columns>:last-child{width:406px}div.dt-button-collection.columns.dtb-b3 .dt-button{flex:0 1 32%}}@media screen and (max-width: 460px){div.dt-button-collection.columns>:last-child{width:200px}}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999}@media screen and (max-width: 767px){div.dt-buttons{float:none;width:100%;text-align:center;margin-bottom:.5em}div.dt-buttons a.btn{float:none}}div.dt-button-info{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color-translucent)}:root[data-bs-theme=dark] div.dt-button-collection.fixed{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color-translucent)} diff --git a/Submission_files/buttons.colVis.min.js.download b/Submission_files/buttons.colVis.min.js.download deleted file mode 100644 index b4a0642cb3..0000000000 --- a/Submission_files/buttons.colVis.min.js.download +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Column visibility buttons for Buttons and DataTables. - * © SpryMedia Ltd - datatables.net/license - */ -(i=>{var o,e;"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(n){return i(n,window,document)}):"object"==typeof exports?(o=require("jquery"),e=function(n,t){t.fn.dataTable||require("datatables.net")(n,t),t.fn.dataTable.Buttons||require("datatables.net-buttons")(n,t)},"undefined"==typeof window?module.exports=function(n,t){return n=n||window,t=t||o(n),e(n,t),i(t,0,n.document)}:(e(window,o),module.exports=i(o,window,window.document))):i(jQuery,window,document)})(function(n,t,i){var e=n.fn.dataTable;return n.extend(e.ext.buttons,{colvis:function(n,t){var i=null,o={extend:"collection",init:function(n,t){i=t},text:function(n){return n.i18n("buttons.colvis","Column visibility")},className:"buttons-colvis",closeButton:!1,buttons:[{extend:"columnsToggle",columns:t.columns,columnText:t.columnText}]};return n.on("column-reorder.dt"+t.namespace,function(){n.button(null,n.button(null,i).node()).collectionRebuild([{extend:"columnsToggle",columns:t.columns,columnText:t.columnText}])}),o},columnsToggle:function(n,t){return n.columns(t.columns).indexes().map(function(n){return{extend:"columnToggle",columns:n,columnText:t.columnText}}).toArray()},columnToggle:function(n,t){return{extend:"columnVisibility",columns:t.columns,columnText:t.columnText}},columnsVisibility:function(n,t){return n.columns(t.columns).indexes().map(function(n){return{extend:"columnVisibility",columns:n,visibility:t.visibility,columnText:t.columnText}}).toArray()},columnVisibility:{columns:void 0,text:function(n,t,i){return i._columnText(n,i)},className:"buttons-columnVisibility",action:function(n,t,i,o){var t=t.columns(o.columns),e=t.visible();t.visible(void 0!==o.visibility?o.visibility:!(e.length&&e[0]))},init:function(e,n,t){var u=this,l=e.column(t.columns);n.attr("data-cv-idx",t.columns),e.on("column-visibility.dt"+t.namespace,function(n,t,i,o){l.index()!==i||t.bDestroying||t.nTable!=e.settings()[0].nTable||u.active(o)}).on("column-reorder.dt"+t.namespace,function(){t.destroying||1===e.columns(t.columns).count()&&(l=e.column(t.columns),u.text(t._columnText(e,t)),u.active(l.visible()))}),this.active(l.visible())},destroy:function(n,t,i){n.off("column-visibility.dt"+i.namespace).off("column-reorder.dt"+i.namespace)},_columnText:function(n,t){var i,o;return"string"==typeof t.text?t.text:(o=n.column(t.columns).title(),i=n.column(t.columns).index(),o=o.replace(/\n/g," ").replace(//gi," ").replace(//gi,""),o=e.Buttons.stripHtmlComments(o),o=e.util.stripHtml(o).trim(),t.columnText?t.columnText(n,i,o):o)}},colvisRestore:{className:"buttons-colvisRestore",text:function(n){return n.i18n("buttons.colvisRestore","Restore visibility")},init:function(n,t,i){n.columns().every(function(){var n=this.init();void 0===n.__visOriginal&&(n.__visOriginal=this.visible())})},action:function(n,t,i,o){t.columns().every(function(n){var t=this.init();this.visible(t.__visOriginal)})}},colvisGroup:{className:"buttons-colvisGroup",action:function(n,t,i,o){t.columns(o.show).visible(!0,!1),t.columns(o.hide).visible(!1,!1),t.columns.adjust()},show:[],hide:[]}}),e}); \ No newline at end of file diff --git a/Submission_files/buttons.html5.min.js.download b/Submission_files/buttons.html5.min.js.download deleted file mode 100644 index 26eb324034..0000000000 --- a/Submission_files/buttons.html5.min.js.download +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * HTML5 export buttons for Buttons and DataTables. - * © SpryMedia Ltd - datatables.net/license - * - * FileSaver.js (1.3.3) - MIT license - * Copyright © 2016 Eli Grey - http://eligrey.com - */ -(o=>{var l,n;"function"==typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(t){return o(t,window,document)}):"object"==typeof exports?(l=require("jquery"),n=function(t,e){e.fn.dataTable||require("datatables.net")(t,e),e.fn.dataTable.Buttons||require("datatables.net-buttons")(t,e)},"undefined"==typeof window?module.exports=function(t,e){return t=t||window,e=e||l(t),n(t,e),o(e,t,t.document)}:(n(window,l),module.exports=o(l,window,window.document))):o(jQuery,window,document)})(function(S,C,u){var e,o,t=S.fn.dataTable;function T(){return e||C.JSZip}function m(){return o||C.pdfMake}t.Buttons.pdfMake=function(t){if(!t)return m();o=t},t.Buttons.jszip=function(t){if(!t)return T();e=t};function k(t){var e="Sheet1";return e=t.sheetName?t.sheetName.replace(/[\[\]\*\/\\\?\:]/g,""):e}function c(t,e){function o(t){for(var e="",o=0,l=t.length;o{var p,i,f,m,s,u,e,c,y,l,t;if(!(void 0===d||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent)))return t=d.document,p=function(){return d.URL||d.webkitURL||d},i=t.createElementNS("http://www.w3.org/1999/xhtml","a"),f="download"in i,m=/constructor/i.test(d.HTMLElement)||d.safari,s=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(d.setImmediate||d.setTimeout)(function(){throw t},0)},e=4e4,c=function(t){setTimeout(function(){"string"==typeof t?p().revokeObjectURL(t):t.remove()},e)},y=function(t){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob([String.fromCharCode(65279),t],{type:t.type}):t},t=(l=function(t,o,e){e||(t=y(t));var l,n,r=this,e="application/octet-stream"===t.type,a=function(){for(var t=r,e="writestart progress write writeend".split(" "),o=void 0,l=(e=[].concat(e)).length;l--;){var n=t["on"+e[l]];if("function"==typeof n)try{n.call(t,o||t)}catch(t){u(t)}}};r.readyState=r.INIT,f?(l=p().createObjectURL(t),setTimeout(function(){var t,e;i.href=l,i.download=o,t=i,e=new MouseEvent("click"),t.dispatchEvent(e),a(),c(l),r.readyState=r.DONE})):(s||e&&m)&&d.FileReader?((n=new FileReader).onloadend=function(){var t=s?n.result:n.result.replace(/^data:[^;]*;/,"data:attachment/file;");d.open(t,"_blank")||(d.location.href=t),r.readyState=r.DONE,a()},n.readAsDataURL(t),r.readyState=r.INIT):(l=l||p().createObjectURL(t),!e&&d.open(l,"_blank")||(d.location.href=l),r.readyState=r.DONE,a(),c(l))}).prototype,"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(t,e,o){return e=e||t.name||"download",o||(t=y(t)),navigator.msSaveOrOpenBlob(t,e)}:(t.abort=function(){},t.readyState=t.INIT=0,t.WRITING=1,t.DONE=2,t.error=t.onwritestart=t.onprogress=t.onwrite=t.onabort=t.onerror=t.onwriteend=null,function(t,e,o){return new l(t,e||t.name||"download",o)})})("undefined"!=typeof self&&self||void 0!==C&&C||this.content),y=(t.fileSave=N,function(t){return t.newline||(navigator.userAgent.match(/Windows/)?"\r\n":"\n")});function O(t){for(var e="A".charCodeAt(0),o="Z".charCodeAt(0)-e+1,l="";0<=t;)l=String.fromCharCode(t%o+e)+l,t=Math.floor(t/o)-1;return l}try{var z,E=new XMLSerializer}catch(t){}function A(t,e,o){var l=t.createElement(e);return o&&(o.attr&&S(l).attr(o.attr),o.children&&S.each(o.children,function(t,e){l.appendChild(e)}),null!=o.text)&&l.appendChild(t.createTextNode(o.text)),l}function D(t,e,o,l,n){var r=S("mergeCells",t);r[0].appendChild(A(t,"mergeCell",{attr:{ref:O(o)+e+":"+O(o+n-1)+(e+l-1)}})),r.attr("count",parseFloat(r.attr("count"))+1)}var R={"_rels/.rels":'',"xl/_rels/workbook.xml.rels":'',"[Content_Types].xml":'',"xl/workbook.xml":'',"xl/worksheets/sheet1.xml":'',"xl/styles.xml":''},$=[{match:/^\-?\d+\.\d%$/,style:60,fmt:function(t){return t/100}},{match:/^\-?\d+\.?\d*%$/,style:56,fmt:function(t){return t/100}},{match:/^\-?\$[\d,]+.?\d*$/,style:57},{match:/^\-?£[\d,]+.?\d*$/,style:58},{match:/^\-?€[\d,]+.?\d*$/,style:59},{match:/^\-?\d+$/,style:65},{match:/^\-?\d+\.\d{2}$/,style:66},{match:/^\([\d,]+\)$/,style:61,fmt:function(t){return-1*t.replace(/[\(\)]/g,"")}},{match:/^\([\d,]+\.\d{2}\)$/,style:62,fmt:function(t){return-1*t.replace(/[\(\)]/g,"")}},{match:/^\-?[\d,]+$/,style:63},{match:/^\-?[\d,]+\.\d{2}$/,style:64},{match:/^(19\d\d|[2-9]\d\d\d)\-(0\d|1[012])\-[0123][\d]$/,style:67,fmt:function(t){return Math.round(25569+Date.parse(t)/864e5)}}];return t.ext.buttons.copyHtml5={className:"buttons-copy buttons-html5",text:function(t){return t.i18n("buttons.copy","Copy")},action:function(t,e,o,l,n){var r=c(e,l),a=e.buttons.exportInfo(l),d=y(l),p=r.str,i=S("
").css({height:1,width:1,overflow:"hidden",position:"fixed",top:0,left:0}),d=(a.title&&(p=a.title+d+d+p),a.messageTop&&(p=a.messageTop+d+d+p),a.messageBottom&&(p=p+d+d+a.messageBottom),l.customize&&(p=l.customize(p,l,e)),S(""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (trac-13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (trac-12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (trac-13208) - // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (trac-13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", true ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, isSetup ) { - - // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add - if ( !isSetup ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - if ( !saved ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - this[ type ](); - result = dataPriv.get( this, type ); - dataPriv.set( this, type, false ); - - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - - return result; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering - // the native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved ) { - - // ...and capture the result - dataPriv.set( this, type, jQuery.event.trigger( - saved[ 0 ], - saved.slice( 1 ), - this - ) ); - - // Abort handling of the native event by all jQuery handlers while allowing - // native handlers on the same element to run. On target, this is achieved - // by stopping immediate propagation just on the jQuery event. However, - // the native event is re-wrapped by a jQuery one on each level of the - // propagation so the only way to stop it for jQuery is to stop it for - // everyone via native `stopPropagation()`. This is not a problem for - // focus/blur which don't bubble, but it does also stop click on checkboxes - // and radios. We accept this limitation. - event.stopPropagation(); - event.isImmediatePropagationStopped = returnTrue; - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (trac-504, trac-13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - which: true -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - - function focusMappedHandler( nativeEvent ) { - if ( document.documentMode ) { - - // Support: IE 11+ - // Attach a single focusin/focusout handler on the document while someone wants - // focus/blur. This is because the former are synchronous in IE while the latter - // are async. In other browsers, all those handlers are invoked synchronously. - - // `handle` from private data would already wrap the event, but we need - // to change the `type` here. - var handle = dataPriv.get( this, "handle" ), - event = jQuery.event.fix( nativeEvent ); - event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; - event.isSimulated = true; - - // First, handle focusin/focusout - handle( nativeEvent ); - - // ...then, handle focus/blur - // - // focus/blur don't bubble while focusin/focusout do; simulate the former by only - // invoking the handler at the lower level. - if ( event.target === event.currentTarget ) { - - // The setup part calls `leverageNative`, which, in turn, calls - // `jQuery.event.add`, so event handle will already have been set - // by this point. - handle( event ); - } - } else { - - // For non-IE browsers, attach a single capturing handler on the document - // while someone wants focusin/focusout. - jQuery.event.simulate( delegateType, nativeEvent.target, - jQuery.event.fix( nativeEvent ) ); - } - } - - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - var attaches; - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, true ); - - if ( document.documentMode ) { - - // Support: IE 9 - 11+ - // We use the same native handler for focusin & focus (and focusout & blur) - // so we need to coordinate setup & teardown parts between those events. - // Use `delegateType` as the key as `type` is already used by `leverageNative`. - attaches = dataPriv.get( this, delegateType ); - if ( !attaches ) { - this.addEventListener( delegateType, focusMappedHandler ); - } - dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); - } else { - - // Return false to allow normal processing in the caller - return false; - } - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - teardown: function() { - var attaches; - - if ( document.documentMode ) { - attaches = dataPriv.get( this, delegateType ) - 1; - if ( !attaches ) { - this.removeEventListener( delegateType, focusMappedHandler ); - dataPriv.remove( this, delegateType ); - } else { - dataPriv.set( this, delegateType, attaches ); - } - } else { - - // Return false to indicate standard teardown should be applied - return false; - } - }, - - // Suppress native focus or blur if we're currently inside - // a leveraged native-event stack - _default: function( event ) { - return dataPriv.get( event.target, type ); - }, - - delegateType: delegateType - }; - - // Support: Firefox <=44 - // Firefox doesn't have focus(in | out) events - // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 - // - // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 - // focus(in | out) events fire after focus & blur events, - // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order - // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 - // - // Support: IE 9 - 11+ - // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, - // attach a single handler for both events in IE. - jQuery.event.special[ delegateType ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - dataHolder = document.documentMode ? this : doc, - attaches = dataPriv.get( dataHolder, delegateType ); - - // Support: IE 9 - 11+ - // We use the same native handler for focusin & focus (and focusout & blur) - // so we need to coordinate setup & teardown parts between those events. - // Use `delegateType` as the key as `type` is already used by `leverageNative`. - if ( !attaches ) { - if ( document.documentMode ) { - this.addEventListener( delegateType, focusMappedHandler ); - } else { - doc.addEventListener( type, focusMappedHandler, true ); - } - } - dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - dataHolder = document.documentMode ? this : doc, - attaches = dataPriv.get( dataHolder, delegateType ) - 1; - - if ( !attaches ) { - if ( document.documentMode ) { - this.removeEventListener( delegateType, focusMappedHandler ); - } else { - doc.removeEventListener( type, focusMappedHandler, true ); - } - dataPriv.remove( dataHolder, delegateType ); - } else { - dataPriv.set( dataHolder, delegateType, attaches ); - } - } - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (trac-8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Re-enable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - - // Unwrap a CDATA section containing script contents. This shouldn't be - // needed as in XML documents they're already not visible when - // inspecting element contents and in HTML documents they have no - // meaning but we're preserving that logic for backwards compatibility. - // This will be removed completely in 4.0. See gh-4904. - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew jQuery#find here for performance reasons: - // https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var rcustomProp = /^--/; - - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (trac-8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - // - // Support: Firefox 70+ - // Only Firefox includes border widths - // in computed dimensions. (gh-4529) - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; - tr.style.cssText = "box-sizing:content-box;border:1px solid"; - - // Support: Chrome 86+ - // Height set through cssText does not get applied. - // Computed height then comes back as 0. - tr.style.height = "1px"; - trChild.style.height = "9px"; - - // Support: Android 8 Chrome 86+ - // In our bodyBackground.html iframe, - // display for all div elements is set to "inline", - // which causes a problem only in Android 8 Chrome 86. - // Ensuring the div is `display: block` - // gets around this issue. - trChild.style.display = "block"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + - parseInt( trStyle.borderTopWidth, 10 ) + - parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - isCustomProp = rcustomProp.test( name ), - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, trac-12537) - // .css('--customProperty) (gh-3144) - if ( computed ) { - - // Support: IE <=9 - 11+ - // IE only supports `"float"` in `getPropertyValue`; in computed styles - // it's only available as `"cssFloat"`. We no longer modify properties - // sent to `.css()` apart from camelCasing, so we need to check both. - // Normally, this would create difference in behavior: if - // `getPropertyValue` returns an empty string, the value returned - // by `.css()` would be `undefined`. This is usually the case for - // disconnected elements. However, in IE even disconnected elements - // with no styles return `"none"` for `getPropertyValue( "float" )` - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( isCustomProp && ret ) { - - // Support: Firefox 105+, Chrome <=105+ - // Spec requires trimming whitespace for custom properties (gh-4926). - // Firefox only trims leading whitespace. Chrome just collapses - // both leading & trailing whitespace to a single space. - // - // Fall back to `undefined` if empty string returned. - // This collapses a missing definition with property defined - // and set to an empty string but there's no standard API - // allowing us to differentiate them without a performance penalty - // and returning `undefined` aligns with older jQuery. - // - // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED - // as whitespace while CSS does not, but this is not a problem - // because CSS preprocessing replaces them with U+000A LINE FEED - // (which *is* CSS whitespace) - // https://www.w3.org/TR/css-syntax-3/#input-preprocessing - ret = ret.replace( rtrimCSS, "$1" ) || undefined; - } - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0, - marginDelta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - // Count margin delta separately to only add it after scroll gutter adjustment. - // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). - if ( box === "margin" ) { - marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta + marginDelta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - animationIterationCount: true, - aspectRatio: true, - borderImageSlice: true, - columnCount: true, - flexGrow: true, - flexShrink: true, - fontWeight: true, - gridArea: true, - gridColumn: true, - gridColumnEnd: true, - gridColumnStart: true, - gridRow: true, - gridRowEnd: true, - gridRowStart: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - scale: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related - fillOpacity: true, - floodOpacity: true, - stopOpacity: true, - strokeMiterlimit: true, - strokeOpacity: true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (trac-7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug trac-9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (trac-7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // Use proper attribute retrieval (trac-12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classNames, cur, curValue, className, i, finalValue; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classNames = classesToArray( value ); - - if ( classNames.length ) { - return this.each( function() { - curValue = getClass( this ); - cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - if ( cur.indexOf( " " + className + " " ) < 0 ) { - cur += className + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - this.setAttribute( "class", finalValue ); - } - } - } ); - } - - return this; - }, - - removeClass: function( value ) { - var classNames, cur, curValue, className, i, finalValue; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classNames = classesToArray( value ); - - if ( classNames.length ) { - return this.each( function() { - curValue = getClass( this ); - - // This expression is here for better compressibility (see addClass) - cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - - // Remove *all* instances - while ( cur.indexOf( " " + className + " " ) > -1 ) { - cur = cur.replace( " " + className + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - this.setAttribute( "class", finalValue ); - } - } - } ); - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var classNames, className, i, self, - type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - classNames = classesToArray( value ); - - return this.each( function() { - if ( isValidValue ) { - - // Toggle individual class names - self = jQuery( this ); - - for ( i = 0; i < classNames.length; i++ ) { - className = classNames[ i ]; - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (trac-14686, trac-14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (trac-2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml, parserErrorElem; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) {} - - parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; - if ( !xml || parserErrorElem ) { - jQuery.error( "Invalid XML: " + ( - parserErrorElem ? - jQuery.map( parserErrorElem.childNodes, function( el ) { - return el.textContent; - } ).join( "\n" ) : - data - ) ); - } - return xml; -}; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (trac-9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (trac-6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ).filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ).map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // trac-7653, trac-8125, trac-8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - -originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes trac-9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (trac-10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket trac-12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // trac-9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script but not if jsonp - if ( !isSuccess && - jQuery.inArray( "script", s.dataTypes ) > -1 && - jQuery.inArray( "json", s.dataTypes ) < 0 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (trac-11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // trac-1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see trac-8605, trac-14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // trac-14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( "