studiokit-scaffolding-js 7.0.12-next.1.4 → 7.0.12-next.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ActionList.js +170 -34
- package/lib/components/AlertDialog.js +133 -9
- package/lib/components/AlertWithIcon.js +92 -25
- package/lib/components/ConnectedModal.js +43 -13
- package/lib/components/Dropdowns/GroupsDropdown.js +69 -44
- package/lib/components/Dropdowns/ManagedNavDropdown.js +100 -67
- package/lib/components/Dropdowns/UserDropdown.js +111 -21
- package/lib/components/Dropdowns/index.js +27 -9
- package/lib/components/EntityOwnerList.js +52 -18
- package/lib/components/Error.js +106 -11
- package/lib/components/ErrorBoundary.js +134 -35
- package/lib/components/ErrorMessage.js +44 -9
- package/lib/components/Forms/DateField.js +61 -42
- package/lib/components/Forms/TimeField.js +81 -42
- package/lib/components/Forms/index.js +27 -4
- package/lib/components/Groups/CreateEditCopySaveButtons.js +114 -11
- package/lib/components/Groups/ExternalGroups/Attach.js +212 -148
- package/lib/components/Groups/ExternalGroups/Table.js +181 -45
- package/lib/components/Groups/GroupCreateOrEditCommonProps.js +5 -1
- package/lib/components/Groups/RosterSyncInfo.js +147 -20
- package/lib/components/HOC/AccessibleAppComponent.js +98 -73
- package/lib/components/HOC/ActivityRequiredComponent.js +92 -49
- package/lib/components/HOC/AsyncComponent.js +54 -39
- package/lib/components/HOC/AuthenticatedComponent.js +58 -38
- package/lib/components/HOC/CollectionComponent.js +170 -110
- package/lib/components/HOC/CollectionFirstItemComponent.js +51 -38
- package/lib/components/HOC/CollectionItemComponent.js +168 -106
- package/lib/components/HOC/ConnectedModalComponent.js +109 -80
- package/lib/components/HOC/DataDependentComponent.js +29 -21
- package/lib/components/HOC/EntityComponent.js +71 -57
- package/lib/components/HOC/FullscreenModalComponent.js +163 -123
- package/lib/components/HOC/GroupActivityRequiredComponent.js +45 -31
- package/lib/components/HOC/GuidComponent.js +29 -22
- package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +41 -31
- package/lib/components/HOC/ModelErrorRedirectComponent.js +51 -47
- package/lib/components/HOC/SearchPersistorComponent.js +240 -166
- package/lib/components/HOC/UnauthenticatedComponent.js +37 -25
- package/lib/components/HOC/UserComponent.js +12 -7
- package/lib/components/Icons/IconAlphaList.js +33 -5
- package/lib/components/Icons/IconExternalUser.js +33 -5
- package/lib/components/Icons/IconImpersonation.js +33 -5
- package/lib/components/Icons/IconStopImpersonating.js +33 -5
- package/lib/components/Icons/IconTable.js +35 -7
- package/lib/components/Icons/IconTableDeleteCol.js +33 -5
- package/lib/components/Icons/IconTableDeleteRow.js +33 -5
- package/lib/components/Icons/IconTableInsertCol.js +33 -5
- package/lib/components/Icons/IconTableInsertRow.js +33 -5
- package/lib/components/Impersonation/Button.js +77 -13
- package/lib/components/Impersonation/Link.js +77 -13
- package/lib/components/Impersonation/UserDetail.js +66 -9
- package/lib/components/Loading.js +26 -4
- package/lib/components/LockDownBrowser/Check.js +194 -49
- package/lib/components/LockDownBrowser/ExitButton.js +26 -9
- package/lib/components/LockDownBrowser/Launch.js +70 -62
- package/lib/components/Lti/Confirm.js +152 -11
- package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +170 -33
- package/lib/components/Lti/Launch.js +105 -24
- package/lib/components/Lti/LaunchGroup.js +85 -13
- package/lib/components/ManageTable.js +309 -87
- package/lib/components/ManageTableNoDataComponent.js +42 -4
- package/lib/components/NewVersionAlert.js +82 -46
- package/lib/components/NotFound.js +86 -10
- package/lib/components/Notifications.js +185 -126
- package/lib/components/PaginationNextButton.js +33 -6
- package/lib/components/PaginationPreviousButton.js +33 -6
- package/lib/components/Quill/CustomToolbar.js +432 -218
- package/lib/components/Quill/Formats/Image.js +73 -63
- package/lib/components/Quill/Formats/List.js +45 -45
- package/lib/components/Quill/Formats/Video.js +28 -24
- package/lib/components/Quill/ImageDropModule.js +147 -117
- package/lib/components/Quill/ImageWarning.js +47 -9
- package/lib/components/Quill/ImageWithAltTextModal.js +425 -86
- package/lib/components/Quill/Specs/CustomImageSpec.js +42 -34
- package/lib/components/Quill/Specs/CustomVideoSpec.js +34 -28
- package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +98 -98
- package/lib/components/Quill/TableModule/Blots/TableBlot.js +52 -47
- package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +53 -48
- package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +224 -221
- package/lib/components/Quill/TableModule/Blots/TableContainer.js +80 -83
- package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +75 -70
- package/lib/components/Quill/TableModule/constants.js +45 -41
- package/lib/components/Quill/TableModule/index.js +362 -301
- package/lib/components/Quill/TableModule/utils.js +42 -38
- package/lib/components/Quill/accessibilityFix.js +234 -232
- package/lib/components/Quill/index.js +34 -28
- package/lib/components/RefreshIndicator/Bordered.js +47 -6
- package/lib/components/RefreshIndicator/Inline.js +47 -8
- package/lib/components/RefreshIndicator/index.js +263 -59
- package/lib/components/SearchControls.js +216 -11
- package/lib/components/SentryRoute.js +11 -6
- package/lib/components/Tables/RoleFilter.js +69 -32
- package/lib/components/Tables/TextFilter.js +62 -13
- package/lib/components/UserRoles/Add.js +199 -96
- package/lib/components/UserRoles/Context.js +11 -7
- package/lib/components/UserRoles/RoleCell.js +181 -72
- package/lib/components/UserRoles/Select.js +157 -17
- package/lib/components/UserRoles/Table.js +221 -80
- package/lib/components/UserRoles/index.js +534 -384
- package/lib/config/eslint/index.js +32 -28
- package/lib/config/eslint/lib/order.js +26 -27
- package/lib/config/eslint/lib/prettier.js +20 -18
- package/lib/config/eslint/lib/typescript.js +93 -112
- package/lib/config/eslint/react.js +24 -14
- package/lib/constants/baseActivity.js +30 -26
- package/lib/constants/baseRole.js +14 -10
- package/lib/constants/configuration.js +33 -29
- package/lib/constants/externalProviderType.js +10 -6
- package/lib/constants/fetchErrorData.js +15 -11
- package/lib/constants/index.js +137 -14
- package/lib/constants/lockDownBrowser.js +28 -24
- package/lib/constants/mockData.js +382 -297
- package/lib/constants/modelStatus.js +15 -11
- package/lib/constants/notificationType.js +12 -8
- package/lib/constants/operatingSystem.js +12 -8
- package/lib/constants/shard.js +11 -7
- package/lib/constants/table.js +21 -21
- package/lib/constants/tier.js +12 -8
- package/lib/constants/userRole.js +15 -5
- package/lib/endpointMappings.js +197 -181
- package/lib/hooks/useCollection.js +82 -62
- package/lib/hooks/useCollectionConfiguration.js +228 -83
- package/lib/hooks/useCollectionItem.js +154 -54
- package/lib/hooks/useGuid.js +20 -8
- package/lib/hooks/usePrevious.js +19 -13
- package/lib/index.js +157 -25
- package/lib/redux/actionCreator.js +50 -28
- package/lib/redux/actions/AuthAction.js +44 -31
- package/lib/redux/actions/ModalAction.js +10 -6
- package/lib/redux/actions/ModelAction.js +77 -39
- package/lib/redux/actions/NotificationAction.js +10 -6
- package/lib/redux/actions/SearchAction.js +9 -5
- package/lib/redux/actions/index.js +60 -7
- package/lib/redux/configureReducers.js +60 -49
- package/lib/redux/configureStore.js +83 -87
- package/lib/redux/helpers.js +6 -2
- package/lib/redux/reducers/authReducer.js +50 -43
- package/lib/redux/reducers/index.js +41 -13
- package/lib/redux/reducers/modalsReducer.js +47 -29
- package/lib/redux/reducers/modelsReducer.js +178 -173
- package/lib/redux/reducers/notificationsReducer.js +24 -18
- package/lib/redux/reducers/searchReducer.js +25 -19
- package/lib/redux/sagas/appInsightsSaga.js +22 -18
- package/lib/redux/sagas/authSaga.js +253 -218
- package/lib/redux/sagas/caliperSaga.js +159 -143
- package/lib/redux/sagas/clockOffsetSaga.js +34 -31
- package/lib/redux/sagas/configurationSaga.js +11 -7
- package/lib/redux/sagas/downtimeApiErrorSaga.js +20 -17
- package/lib/redux/sagas/errorSaga.js +27 -21
- package/lib/redux/sagas/googleAnalyticsSaga.js +28 -24
- package/lib/redux/sagas/identityProviderSaga.js +22 -18
- package/lib/redux/sagas/initialDataLoadSaga.js +37 -28
- package/lib/redux/sagas/lockDownBrowserErrorSaga.js +29 -20
- package/lib/redux/sagas/modelFetchSaga.js +355 -322
- package/lib/redux/sagas/noStoreSaga.js +61 -48
- package/lib/redux/sagas/postLoginDataSaga.js +45 -34
- package/lib/redux/sagas/postLoginRedirectSaga.js +27 -27
- package/lib/redux/sagas/rootSaga.js +82 -57
- package/lib/redux/sagas/sentrySaga.js +29 -25
- package/lib/redux/sagas/userIdSaga.js +16 -12
- package/lib/services/codeProviderService.js +25 -19
- package/lib/services/dateService.js +12 -7
- package/lib/services/documentService.js +17 -12
- package/lib/services/fetchService.js +129 -112
- package/lib/services/persistenceService.js +33 -29
- package/lib/services/ticketProviderService.js +29 -23
- package/lib/services/tokenPersistenceService.js +12 -8
- package/lib/services/windowService.js +18 -14
- package/lib/startup.js +132 -114
- package/lib/types/AppConfiguration.js +5 -1
- package/lib/types/Artifact.js +11 -7
- package/lib/types/BaseReduxState.js +5 -1
- package/lib/types/Client.js +5 -1
- package/lib/types/Collection.js +5 -1
- package/lib/types/Configuration.js +5 -1
- package/lib/types/DeepLinkingResponseRequest.js +5 -1
- package/lib/types/DeletableModel.js +5 -1
- package/lib/types/Event.js +5 -1
- package/lib/types/ExternalGroup.js +5 -1
- package/lib/types/ExternalProvider.js +5 -1
- package/lib/types/ExternalTerm.js +5 -1
- package/lib/types/Group.js +5 -1
- package/lib/types/IdentityProvider.js +5 -1
- package/lib/types/LtiLaunch.js +5 -1
- package/lib/types/NameOnlyEntity.js +5 -1
- package/lib/types/Notification.js +5 -1
- package/lib/types/OptionalRecord.js +5 -1
- package/lib/types/OwnerSchedule.js +5 -1
- package/lib/types/PropertyOfType.js +5 -1
- package/lib/types/Quill.js +5 -1
- package/lib/types/RoleDescription.js +5 -1
- package/lib/types/Search.js +5 -1
- package/lib/types/SimpleLocation.js +5 -1
- package/lib/types/UniTime.js +5 -1
- package/lib/types/User.js +5 -1
- package/lib/types/UserRole.js +5 -1
- package/lib/types/auth/AuthState.js +5 -1
- package/lib/types/auth/CasV1LoginRequestBody.js +5 -1
- package/lib/types/auth/ClientCredentials.js +5 -1
- package/lib/types/auth/CodeProviderService.js +5 -1
- package/lib/types/auth/LocalLoginRequestBody.js +5 -1
- package/lib/types/auth/TicketProviderService.js +5 -1
- package/lib/types/auth/TokenPersistenceService.js +5 -1
- package/lib/types/auth/index.js +82 -9
- package/lib/types/externals.d.js +2 -0
- package/lib/types/index.js +313 -30
- package/lib/types/net/EndpointConfig.js +5 -1
- package/lib/types/net/EndpointMapping.js +5 -1
- package/lib/types/net/EndpointMappings.js +5 -1
- package/lib/types/net/ErrorHandler.js +5 -1
- package/lib/types/net/FetchConfig.js +5 -1
- package/lib/types/net/FetchErrorData.js +10 -6
- package/lib/types/net/FetchResult.js +5 -1
- package/lib/types/net/HTTPMethod.js +5 -1
- package/lib/types/net/HTTPStatusCode.js +16 -12
- package/lib/types/net/Metadata.js +5 -1
- package/lib/types/net/Model.js +5 -1
- package/lib/types/net/ModelCollection.js +5 -1
- package/lib/types/net/ModelsState.js +5 -1
- package/lib/types/net/OAuthToken.js +5 -1
- package/lib/types/net/OAuthTokenOrNull.js +5 -1
- package/lib/types/net/TokenAccessFunction.js +5 -1
- package/lib/types/net/index.js +181 -18
- package/lib/utils/baseActivity.js +133 -123
- package/lib/utils/baseRole.js +37 -33
- package/lib/utils/collection.js +425 -298
- package/lib/utils/cookies.js +22 -19
- package/lib/utils/date.js +303 -279
- package/lib/utils/dom.js +176 -165
- package/lib/utils/domainIdentifier.js +9 -5
- package/lib/utils/entityUserRole.js +6 -2
- package/lib/utils/error.js +17 -15
- package/lib/utils/events.js +40 -31
- package/lib/utils/externalGroup.js +22 -18
- package/lib/utils/externalProviders.js +8 -4
- package/lib/utils/externalTerms.js +10 -3
- package/lib/utils/fetch.js +179 -180
- package/lib/utils/group.js +18 -7
- package/lib/utils/groupDates.js +37 -33
- package/lib/utils/groupRoles.js +25 -21
- package/lib/utils/lockDownBrowser.js +15 -11
- package/lib/utils/logger.js +26 -22
- package/lib/utils/lti.js +9 -4
- package/lib/utils/model.js +36 -41
- package/lib/utils/number.js +21 -18
- package/lib/utils/promise.js +28 -21
- package/lib/utils/quill.js +65 -62
- package/lib/utils/route.js +58 -55
- package/lib/utils/search.js +76 -80
- package/lib/utils/shard.js +37 -37
- package/lib/utils/sort.js +50 -42
- package/lib/utils/string.js +13 -8
- package/lib/utils/table.js +38 -33
- package/lib/utils/timezone.js +10 -6
- package/lib/utils/url.js +142 -142
- package/lib/utils/user.js +58 -55
- package/lib/utils/userAgent.js +10 -10
- package/lib/utils/userRole.js +57 -49
- package/package.json +17 -3
package/lib/utils/sort.js
CHANGED
|
@@ -1,65 +1,73 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sortByNames = exports.sortByNameNatural = exports.sortByAttributeNumeric = exports.sortByAttribute = exports.sort = void 0;
|
|
7
|
+
const sortByAttribute = function (attributeName) {
|
|
8
|
+
let shouldSortAscending = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
9
|
+
return (a, b) => {
|
|
5
10
|
const attrA = a[attributeName] ? a[attributeName].toUpperCase() : '';
|
|
6
11
|
const attrB = b[attributeName] ? b[attributeName].toUpperCase() : '';
|
|
7
12
|
let sortResult = 0;
|
|
8
13
|
if (attrA === '') {
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
else if (attrA === attrB) {
|
|
15
|
-
return 0;
|
|
14
|
+
sortResult = 1;
|
|
15
|
+
} else if (attrB === '') {
|
|
16
|
+
sortResult = -1;
|
|
17
|
+
} else if (attrA === attrB) {
|
|
18
|
+
return 0;
|
|
16
19
|
}
|
|
17
20
|
if (attrA < attrB) {
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
sortResult = 1;
|
|
21
|
+
sortResult = -1;
|
|
22
|
+
} else if (attrA > attrB) {
|
|
23
|
+
sortResult = 1;
|
|
22
24
|
}
|
|
23
25
|
return shouldSortAscending ? sortResult : -1 * sortResult;
|
|
26
|
+
};
|
|
24
27
|
};
|
|
25
28
|
exports.sortByAttribute = sortByAttribute;
|
|
26
|
-
const sortByAttributeNumeric =
|
|
27
|
-
|
|
28
|
-
return 0;
|
|
29
|
-
}
|
|
30
|
-
if (a[attribute] > b[attribute]) {
|
|
31
|
-
return 1;
|
|
32
|
-
}
|
|
33
|
-
if (a[attribute] < b[attribute]) {
|
|
34
|
-
return -1;
|
|
35
|
-
}
|
|
29
|
+
const sortByAttributeNumeric = attribute => (a, b) => {
|
|
30
|
+
if (a[attribute] === b[attribute]) {
|
|
36
31
|
return 0;
|
|
32
|
+
}
|
|
33
|
+
if (a[attribute] > b[attribute]) {
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
if (a[attribute] < b[attribute]) {
|
|
37
|
+
return -1;
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
37
40
|
};
|
|
38
|
-
|
|
41
|
+
|
|
39
42
|
// Requires at least last name or email address for each user
|
|
43
|
+
exports.sortByAttributeNumeric = sortByAttributeNumeric;
|
|
40
44
|
const sortByNames = (a, b) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
if (!a.lastName && !a.email || !b.lastName && !b.email) {
|
|
46
|
+
throw new Error('Last name or email required');
|
|
47
|
+
}
|
|
48
|
+
// (last name or email) => first name
|
|
49
|
+
const lastNameA = a.lastName ? a.lastName.toLowerCase() : a.email ? a.email : '';
|
|
50
|
+
const lastNameB = b.lastName ? b.lastName.toLowerCase() : b.email ? b.email : '';
|
|
51
|
+
if (lastNameA !== lastNameB) {
|
|
52
|
+
return lastNameA > lastNameB ? 1 : -1;
|
|
53
|
+
}
|
|
54
|
+
const firstNameA = a.firstName ? a.firstName.toLowerCase() : '';
|
|
55
|
+
const firstNameB = b.firstName ? b.firstName.toLowerCase() : '';
|
|
56
|
+
if (firstNameA !== firstNameB) {
|
|
57
|
+
return firstNameA > firstNameB ? 1 : -1;
|
|
58
|
+
}
|
|
59
|
+
return 0;
|
|
56
60
|
};
|
|
57
61
|
exports.sortByNames = sortByNames;
|
|
58
62
|
const sortByNameNatural = (a, b) => {
|
|
59
|
-
|
|
63
|
+
return a.name.trim().localeCompare(b.name.trim(), undefined, {
|
|
64
|
+
numeric: true,
|
|
65
|
+
sensitivity: 'base'
|
|
66
|
+
});
|
|
60
67
|
};
|
|
61
68
|
exports.sortByNameNatural = sortByNameNatural;
|
|
62
69
|
const sort = (array, attributeName, shouldSortAscending) => {
|
|
63
|
-
|
|
70
|
+
return array.slice().sort(sortByAttribute(attributeName, shouldSortAscending));
|
|
64
71
|
};
|
|
65
72
|
exports.sort = sort;
|
|
73
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzb3J0QnlBdHRyaWJ1dGUiLCJhdHRyaWJ1dGVOYW1lIiwic2hvdWxkU29ydEFzY2VuZGluZyIsImFyZ3VtZW50cyIsImxlbmd0aCIsInVuZGVmaW5lZCIsImEiLCJiIiwiYXR0ckEiLCJ0b1VwcGVyQ2FzZSIsImF0dHJCIiwic29ydFJlc3VsdCIsImV4cG9ydHMiLCJzb3J0QnlBdHRyaWJ1dGVOdW1lcmljIiwiYXR0cmlidXRlIiwic29ydEJ5TmFtZXMiLCJsYXN0TmFtZSIsImVtYWlsIiwiRXJyb3IiLCJsYXN0TmFtZUEiLCJ0b0xvd2VyQ2FzZSIsImxhc3ROYW1lQiIsImZpcnN0TmFtZUEiLCJmaXJzdE5hbWUiLCJmaXJzdE5hbWVCIiwic29ydEJ5TmFtZU5hdHVyYWwiLCJuYW1lIiwidHJpbSIsImxvY2FsZUNvbXBhcmUiLCJudW1lcmljIiwic2Vuc2l0aXZpdHkiLCJzb3J0IiwiYXJyYXkiLCJzbGljZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9zb3J0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wdGlvbmFsUmVjb3JkIH0gZnJvbSAnLi4vdHlwZXMvT3B0aW9uYWxSZWNvcmQnXHJcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuLi90eXBlcy9Vc2VyJ1xyXG5cclxuZXhwb3J0IGNvbnN0IHNvcnRCeUF0dHJpYnV0ZSA9XHJcblx0PEsgZXh0ZW5kcyBrZXlvZiBULCBUIGV4dGVuZHMgT3B0aW9uYWxSZWNvcmQ8Sywgc3RyaW5nPj4oYXR0cmlidXRlTmFtZTogSywgc2hvdWxkU29ydEFzY2VuZGluZyA9IHRydWUpID0+XHJcblx0KGE6IFQsIGI6IFQpID0+IHtcclxuXHRcdGNvbnN0IGF0dHJBID0gYVthdHRyaWJ1dGVOYW1lXSA/IGFbYXR0cmlidXRlTmFtZV0udG9VcHBlckNhc2UoKSA6ICcnXHJcblx0XHRjb25zdCBhdHRyQiA9IGJbYXR0cmlidXRlTmFtZV0gPyBiW2F0dHJpYnV0ZU5hbWVdLnRvVXBwZXJDYXNlKCkgOiAnJ1xyXG5cdFx0bGV0IHNvcnRSZXN1bHQgPSAwXHJcblx0XHRpZiAoYXR0ckEgPT09ICcnKSB7XHJcblx0XHRcdHNvcnRSZXN1bHQgPSAxXHJcblx0XHR9IGVsc2UgaWYgKGF0dHJCID09PSAnJykge1xyXG5cdFx0XHRzb3J0UmVzdWx0ID0gLTFcclxuXHRcdH0gZWxzZSBpZiAoYXR0ckEgPT09IGF0dHJCKSB7XHJcblx0XHRcdHJldHVybiAwXHJcblx0XHR9XHJcblx0XHRpZiAoYXR0ckEgPCBhdHRyQikge1xyXG5cdFx0XHRzb3J0UmVzdWx0ID0gLTFcclxuXHRcdH0gZWxzZSBpZiAoYXR0ckEgPiBhdHRyQikge1xyXG5cdFx0XHRzb3J0UmVzdWx0ID0gMVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHNob3VsZFNvcnRBc2NlbmRpbmcgPyBzb3J0UmVzdWx0IDogLTEgKiBzb3J0UmVzdWx0XHJcblx0fVxyXG5cclxuZXhwb3J0IGNvbnN0IHNvcnRCeUF0dHJpYnV0ZU51bWVyaWMgPVxyXG5cdDxUPihhdHRyaWJ1dGU6IGtleW9mIFQpID0+XHJcblx0KGE6IFQsIGI6IFQpID0+IHtcclxuXHRcdGlmIChhW2F0dHJpYnV0ZV0gPT09IGJbYXR0cmlidXRlXSkge1xyXG5cdFx0XHRyZXR1cm4gMFxyXG5cdFx0fVxyXG5cdFx0aWYgKGFbYXR0cmlidXRlXSA+IGJbYXR0cmlidXRlXSkge1xyXG5cdFx0XHRyZXR1cm4gMVxyXG5cdFx0fVxyXG5cdFx0aWYgKGFbYXR0cmlidXRlXSA8IGJbYXR0cmlidXRlXSkge1xyXG5cdFx0XHRyZXR1cm4gLTFcclxuXHRcdH1cclxuXHRcdHJldHVybiAwXHJcblx0fVxyXG5cclxuLy8gUmVxdWlyZXMgYXQgbGVhc3QgbGFzdCBuYW1lIG9yIGVtYWlsIGFkZHJlc3MgZm9yIGVhY2ggdXNlclxyXG5leHBvcnQgY29uc3Qgc29ydEJ5TmFtZXMgPSAoYTogVXNlciwgYjogVXNlcikgPT4ge1xyXG5cdGlmICgoIWEubGFzdE5hbWUgJiYgIWEuZW1haWwpIHx8ICghYi5sYXN0TmFtZSAmJiAhYi5lbWFpbCkpIHtcclxuXHRcdHRocm93IG5ldyBFcnJvcignTGFzdCBuYW1lIG9yIGVtYWlsIHJlcXVpcmVkJylcclxuXHR9XHJcblx0Ly8gKGxhc3QgbmFtZSBvciBlbWFpbCkgPT4gZmlyc3QgbmFtZVxyXG5cdGNvbnN0IGxhc3ROYW1lQSA9IGEubGFzdE5hbWUgPyBhLmxhc3ROYW1lLnRvTG93ZXJDYXNlKCkgOiBhLmVtYWlsID8gYS5lbWFpbCA6ICcnXHJcblx0Y29uc3QgbGFzdE5hbWVCID0gYi5sYXN0TmFtZSA/IGIubGFzdE5hbWUudG9Mb3dlckNhc2UoKSA6IGIuZW1haWwgPyBiLmVtYWlsIDogJydcclxuXHRpZiAobGFzdE5hbWVBICE9PSBsYXN0TmFtZUIpIHtcclxuXHRcdHJldHVybiBsYXN0TmFtZUEgPiBsYXN0TmFtZUIgPyAxIDogLTFcclxuXHR9XHJcblx0Y29uc3QgZmlyc3ROYW1lQSA9IGEuZmlyc3ROYW1lID8gYS5maXJzdE5hbWUudG9Mb3dlckNhc2UoKSA6ICcnXHJcblx0Y29uc3QgZmlyc3ROYW1lQiA9IGIuZmlyc3ROYW1lID8gYi5maXJzdE5hbWUudG9Mb3dlckNhc2UoKSA6ICcnXHJcblx0aWYgKGZpcnN0TmFtZUEgIT09IGZpcnN0TmFtZUIpIHtcclxuXHRcdHJldHVybiBmaXJzdE5hbWVBID4gZmlyc3ROYW1lQiA/IDEgOiAtMVxyXG5cdH1cclxuXHRyZXR1cm4gMFxyXG59XHJcblxyXG5leHBvcnQgY29uc3Qgc29ydEJ5TmFtZU5hdHVyYWwgPSAoYTogeyBuYW1lOiBzdHJpbmcgfSwgYjogeyBuYW1lOiBzdHJpbmcgfSkgPT4ge1xyXG5cdHJldHVybiBhLm5hbWUudHJpbSgpLmxvY2FsZUNvbXBhcmUoYi5uYW1lLnRyaW0oKSwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUsIHNlbnNpdGl2aXR5OiAnYmFzZScgfSlcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHNvcnQgPSAoYXJyYXk6IGFueVtdLCBhdHRyaWJ1dGVOYW1lOiBzdHJpbmcsIHNob3VsZFNvcnRBc2NlbmRpbmc6IGJvb2xlYW4pID0+IHtcclxuXHRyZXR1cm4gYXJyYXkuc2xpY2UoKS5zb3J0KHNvcnRCeUF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBzaG91bGRTb3J0QXNjZW5kaW5nKSlcclxufVxyXG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdPLE1BQU1BLGVBQWUsR0FDM0IsU0FBQUEsQ0FBeURDLGFBQWdCO0VBQUEsSUFBRUMsbUJBQW1CLEdBQUFDLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHLElBQUk7RUFBQSxPQUNyRyxDQUFDRyxDQUFJLEVBQUVDLENBQUksS0FBSztJQUNmLE1BQU1DLEtBQUssR0FBR0YsQ0FBQyxDQUFDTCxhQUFhLENBQUMsR0FBR0ssQ0FBQyxDQUFDTCxhQUFhLENBQUMsQ0FBQ1EsV0FBVyxDQUFDLENBQUMsR0FBRyxFQUFFO0lBQ3BFLE1BQU1DLEtBQUssR0FBR0gsQ0FBQyxDQUFDTixhQUFhLENBQUMsR0FBR00sQ0FBQyxDQUFDTixhQUFhLENBQUMsQ0FBQ1EsV0FBVyxDQUFDLENBQUMsR0FBRyxFQUFFO0lBQ3BFLElBQUlFLFVBQVUsR0FBRyxDQUFDO0lBQ2xCLElBQUlILEtBQUssS0FBSyxFQUFFLEVBQUU7TUFDakJHLFVBQVUsR0FBRyxDQUFDO0lBQ2YsQ0FBQyxNQUFNLElBQUlELEtBQUssS0FBSyxFQUFFLEVBQUU7TUFDeEJDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDaEIsQ0FBQyxNQUFNLElBQUlILEtBQUssS0FBS0UsS0FBSyxFQUFFO01BQzNCLE9BQU8sQ0FBQztJQUNUO0lBQ0EsSUFBSUYsS0FBSyxHQUFHRSxLQUFLLEVBQUU7TUFDbEJDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDaEIsQ0FBQyxNQUFNLElBQUlILEtBQUssR0FBR0UsS0FBSyxFQUFFO01BQ3pCQyxVQUFVLEdBQUcsQ0FBQztJQUNmO0lBQ0EsT0FBT1QsbUJBQW1CLEdBQUdTLFVBQVUsR0FBRyxDQUFDLENBQUMsR0FBR0Es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
|
package/lib/utils/string.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
exports
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
4
6
|
exports.isEmail = isEmail;
|
|
7
|
+
exports.isPurdueAliasOrPuid = isPurdueAliasOrPuid;
|
|
5
8
|
function isPurdueAliasOrPuid(aliasOrPuid) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
const isPuid = /^\d{10}$/.test(aliasOrPuid);
|
|
10
|
+
const isAlias = /^[a-z0-9]{2,8}$/i.test(aliasOrPuid);
|
|
11
|
+
return isPuid || isAlias;
|
|
9
12
|
}
|
|
13
|
+
|
|
10
14
|
// https://stackoverflow.com/a/1373724
|
|
11
15
|
function isEmail(email) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
// eslint-disable-next-line
|
|
17
|
+
const regexEmail = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
|
|
18
|
+
return regexEmail.test(email);
|
|
15
19
|
}
|
|
20
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc1B1cmR1ZUFsaWFzT3JQdWlkIiwiYWxpYXNPclB1aWQiLCJpc1B1aWQiLCJ0ZXN0IiwiaXNBbGlhcyIsImlzRW1haWwiLCJlbWFpbCIsInJlZ2V4RW1haWwiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc3RyaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBpc1B1cmR1ZUFsaWFzT3JQdWlkKGFsaWFzT3JQdWlkOiBzdHJpbmcpIHtcclxuXHRjb25zdCBpc1B1aWQgPSAvXlxcZHsxMH0kLy50ZXN0KGFsaWFzT3JQdWlkKVxyXG5cdGNvbnN0IGlzQWxpYXMgPSAvXlthLXowLTldezIsOH0kL2kudGVzdChhbGlhc09yUHVpZClcclxuXHRyZXR1cm4gaXNQdWlkIHx8IGlzQWxpYXNcclxufVxyXG5cclxuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzEzNzM3MjRcclxuZXhwb3J0IGZ1bmN0aW9uIGlzRW1haWwoZW1haWw6IHN0cmluZykge1xyXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxyXG5cdGNvbnN0IHJlZ2V4RW1haWwgPSAvKD86W2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKnxcIig/OltcXHgwMS1cXHgwOFxceDBiXFx4MGNcXHgwZS1cXHgxZlxceDIxXFx4MjMtXFx4NWJcXHg1ZC1cXHg3Zl18XFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZS1cXHg3Zl0pKlwiKUAoPzooPzpbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/fFxcWyg/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/fFthLXowLTktXSpbYS16MC05XTooPzpbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHgyMS1cXHg1YVxceDUzLVxceDdmXXxcXFxcW1xceDAxLVxceDA5XFx4MGJcXHgwY1xceDBlLVxceDdmXSkrKVxcXSkvXHJcblx0cmV0dXJuIHJlZ2V4RW1haWwudGVzdChlbWFpbClcclxufVxyXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxTQUFTQSxtQkFBbUJBLENBQUNDLFdBQW1CLEVBQUU7RUFDeEQsTUFBTUMsTUFBTSxHQUFHLFVBQVUsQ0FBQ0MsSUFBSSxDQUFDRixXQUFXLENBQUM7RUFDM0MsTUFBTUcsT0FBTyxHQUFHLGtCQUFrQixDQUFDRCxJQUFJLENBQUNGLFdBQVcsQ0FBQztFQUNwRCxPQUFPQyxNQUFNLElBQUlFLE9BQU87QUFDekI7O0FBRUE7QUFDTyxTQUFTQyxPQUFPQSxDQUFDQyxLQUFhLEVBQUU7RUFDdEM7RUFDQSxNQUFNQyxVQUFVLEdBQUcsNGFBQTRhO0VBQy9iLE9BQU9BLFVBQVUsQ0FBQ0osSUFBSSxDQUFDRyxLQUFLLENBQUM7QUFDOUIiLCJpZ25vcmVMaXN0IjpbXX0=
|
package/lib/utils/table.js
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getPageSizeOptions = exports.getManageTableTabName = exports.getGroupManageTableTabName = void 0;
|
|
7
|
+
var _table = require("../constants/table");
|
|
8
|
+
const getManageTableTabName = selectedTab => {
|
|
9
|
+
switch (selectedTab) {
|
|
10
|
+
case _table.MANAGE_TABLE_TAB.AVAILABLE:
|
|
11
|
+
return 'Available';
|
|
12
|
+
case _table.MANAGE_TABLE_TAB.DELETED:
|
|
13
|
+
return 'Deleted';
|
|
14
|
+
default:
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
14
17
|
};
|
|
15
18
|
exports.getManageTableTabName = getManageTableTabName;
|
|
16
|
-
const getGroupManageTableTabName =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
const getGroupManageTableTabName = selectedTab => {
|
|
20
|
+
switch (selectedTab) {
|
|
21
|
+
case _table.GROUP_MANAGE_TABLE_TAB.CURRENT:
|
|
22
|
+
return 'Current';
|
|
23
|
+
case _table.GROUP_MANAGE_TABLE_TAB.DELETED:
|
|
24
|
+
return 'Deleted';
|
|
25
|
+
case _table.GROUP_MANAGE_TABLE_TAB.PAST:
|
|
26
|
+
return 'Past';
|
|
27
|
+
default:
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
27
30
|
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* return page size options that are less than or equal to the total data length,
|
|
31
|
-
* and one that is greater (if it exists) to allow viewing all data on one page.
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* return page size options that are less than or equal to the total data length,
|
|
34
|
+
* and one that is greater (if it exists) to allow viewing all data on one page.
|
|
32
35
|
* */
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
exports.getGroupManageTableTabName = getGroupManageTableTabName;
|
|
37
|
+
const getPageSizeOptions = dataLength => _table.TABLE_PAGE_SIZE_OPTIONS.reduce((options, option, currentIndex) => {
|
|
38
|
+
const prevOption = currentIndex > 0 ? options[currentIndex - 1] : undefined;
|
|
39
|
+
if (!dataLength || option < dataLength || prevOption && prevOption < dataLength) {
|
|
40
|
+
options.push(option);
|
|
41
|
+
}
|
|
42
|
+
return options;
|
|
39
43
|
}, []);
|
|
40
44
|
exports.getPageSizeOptions = getPageSizeOptions;
|
|
45
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdGFibGUiLCJyZXF1aXJlIiwiZ2V0TWFuYWdlVGFibGVUYWJOYW1lIiwic2VsZWN0ZWRUYWIiLCJNQU5BR0VfVEFCTEVfVEFCIiwiQVZBSUxBQkxFIiwiREVMRVRFRCIsImV4cG9ydHMiLCJnZXRHcm91cE1hbmFnZVRhYmxlVGFiTmFtZSIsIkdST1VQX01BTkFHRV9UQUJMRV9UQUIiLCJDVVJSRU5UIiwiUEFTVCIsImdldFBhZ2VTaXplT3B0aW9ucyIsImRhdGFMZW5ndGgiLCJUQUJMRV9QQUdFX1NJWkVfT1BUSU9OUyIsInJlZHVjZSIsIm9wdGlvbnMiLCJvcHRpb24iLCJjdXJyZW50SW5kZXgiLCJwcmV2T3B0aW9uIiwidW5kZWZpbmVkIiwicHVzaCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90YWJsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHUk9VUF9NQU5BR0VfVEFCTEVfVEFCLCBNQU5BR0VfVEFCTEVfVEFCLCBUQUJMRV9QQUdFX1NJWkVfT1BUSU9OUyB9IGZyb20gJy4uL2NvbnN0YW50cy90YWJsZSdcclxuXHJcbmV4cG9ydCBjb25zdCBnZXRNYW5hZ2VUYWJsZVRhYk5hbWUgPSAoc2VsZWN0ZWRUYWI/OiBudW1iZXIpID0+IHtcclxuXHRzd2l0Y2ggKHNlbGVjdGVkVGFiKSB7XHJcblx0XHRjYXNlIE1BTkFHRV9UQUJMRV9UQUIuQVZBSUxBQkxFOlxyXG5cdFx0XHRyZXR1cm4gJ0F2YWlsYWJsZSdcclxuXHRcdGNhc2UgTUFOQUdFX1RBQkxFX1RBQi5ERUxFVEVEOlxyXG5cdFx0XHRyZXR1cm4gJ0RlbGV0ZWQnXHJcblx0XHRkZWZhdWx0OlxyXG5cdFx0XHRyZXR1cm4gJydcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXRHcm91cE1hbmFnZVRhYmxlVGFiTmFtZSA9IChzZWxlY3RlZFRhYj86IG51bWJlcikgPT4ge1xyXG5cdHN3aXRjaCAoc2VsZWN0ZWRUYWIpIHtcclxuXHRcdGNhc2UgR1JPVVBfTUFOQUdFX1RBQkxFX1RBQi5DVVJSRU5UOlxyXG5cdFx0XHRyZXR1cm4gJ0N1cnJlbnQnXHJcblx0XHRjYXNlIEdST1VQX01BTkFHRV9UQUJMRV9UQUIuREVMRVRFRDpcclxuXHRcdFx0cmV0dXJuICdEZWxldGVkJ1xyXG5cdFx0Y2FzZSBHUk9VUF9NQU5BR0VfVEFCTEVfVEFCLlBBU1Q6XHJcblx0XHRcdHJldHVybiAnUGFzdCdcclxuXHRcdGRlZmF1bHQ6XHJcblx0XHRcdHJldHVybiAnJ1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIHJldHVybiBwYWdlIHNpemUgb3B0aW9ucyB0aGF0IGFyZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRvdGFsIGRhdGEgbGVuZ3RoLFxyXG4gKiBhbmQgb25lIHRoYXQgaXMgZ3JlYXRlciAoaWYgaXQgZXhpc3RzKSB0byBhbGxvdyB2aWV3aW5nIGFsbCBkYXRhIG9uIG9uZSBwYWdlLlxyXG4gKiAqL1xyXG5leHBvcnQgY29uc3QgZ2V0UGFnZVNpemVPcHRpb25zID0gKGRhdGFMZW5ndGg/OiBudW1iZXIpID0+XHJcblx0VEFCTEVfUEFHRV9TSVpFX09QVElPTlMucmVkdWNlPG51bWJlcltdPigob3B0aW9ucywgb3B0aW9uLCBjdXJyZW50SW5kZXgpID0+IHtcclxuXHRcdGNvbnN0IHByZXZPcHRpb24gPSBjdXJyZW50SW5kZXggPiAwID8gb3B0aW9uc1tjdXJyZW50SW5kZXggLSAxXSA6IHVuZGVmaW5lZFxyXG5cdFx0aWYgKCFkYXRhTGVuZ3RoIHx8IG9wdGlvbiA8IGRhdGFMZW5ndGggfHwgKHByZXZPcHRpb24gJiYgcHJldk9wdGlvbiA8IGRhdGFMZW5ndGgpKSB7XHJcblx0XHRcdG9wdGlvbnMucHVzaChvcHRpb24pXHJcblx0XHR9XHJcblx0XHRyZXR1cm4gb3B0aW9uc1xyXG5cdH0sIFtdKVxyXG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUVPLE1BQU1DLHFCQUFxQixHQUFJQyxXQUFvQixJQUFLO0VBQzlELFFBQVFBLFdBQVc7SUFDbEIsS0FBS0MsdUJBQWdCLENBQUNDLFNBQVM7TUFDOUIsT0FBTyxXQUFXO0lBQ25CLEtBQUtELHVCQUFnQixDQUFDRSxPQUFPO01BQzVCLE9BQU8sU0FBUztJQUNqQjtNQUNDLE9BQU8sRUFBRTtFQUNYO0FBQ0QsQ0FBQztBQUFBQyxPQUFBLENBQUFMLHFCQUFBLEdBQUFBLHFCQUFBO0FBRU0sTUFBTU0sMEJBQTBCLEdBQUlMLFdBQW9CLElBQUs7RUFDbkUsUUFBUUEsV0FBVztJQUNsQixLQUFLTSw2QkFBc0IsQ0FBQ0MsT0FBTztNQUNsQyxPQUFPLFNBQVM7SUFDakIsS0FBS0QsNkJBQXNCLENBQUNILE9BQU87TUFDbEMsT0FBTyxTQUFTO0lBQ2pCLEtBQUtHLDZCQUFzQixDQUFDRSxJQUFJO01BQy9CLE9BQU8sTUFBTTtJQUNkO01BQ0MsT0FBTyxFQUFFO0VBQ1g7QUFDRCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBSEFKLE9BQUEsQ0FBQUMsMEJBQUEsR0FBQUEsMEJBQUE7QUFJTyxNQUFNSSxrQkFBa0IsR0FBSUMsVUFBbUIsSUFDckRDLDhCQUF1QixDQUFDQyxNQUFNLENBQVcsQ0FBQ0MsT0FBTyxFQUFFQyxNQUFNLEVBQUVDLFlBQVksS0FBSztFQUMzRSxNQUFNQyxVQUFVLEdBQUdELFlBQVksR0FBRyxDQUFDLEdBQUdGLE9BQU8sQ0FBQ0UsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHRSxTQUFTO0VBQzNFLElBQUksQ0FBQ1AsVUFBVSxJQUFJSSxNQUFNLEdBQUdKLFVBQVUsSUFBS00sVUFBVSxJQUFJQSxVQUFVLEdBQUdOLFVBQVcsRUFBRTtJQUNsRkcsT0FBTyxDQUFDSyxJQUFJLENBQUNKLE1BQU0sQ0FBQztFQUNyQjtFQUNBLE9BQU9ELE9BQU87QUFDZixDQUFDLEVBQUUsRUFBRSxDQUFDO0FBQUFULE9BQUEsQ0FBQUssa0JBQUEsR0FBQUEsa0JBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
package/lib/utils/timezone.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
3
6
|
exports.guessTimeZoneId = exports.getDefaultTimeZoneId = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
var moment = _interopRequireWildcard(require("moment-timezone"));
|
|
8
|
+
var _configuration = require("../constants/configuration");
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
7
10
|
const defaultTimeZoneId = 'America/Indianapolis';
|
|
8
11
|
const getDefaultTimeZoneId = () => {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
const shardConfig = (0, _configuration.getShardConfig)();
|
|
13
|
+
return shardConfig.defaultTimeZoneId ? shardConfig.defaultTimeZoneId : defaultTimeZoneId;
|
|
11
14
|
};
|
|
12
15
|
exports.getDefaultTimeZoneId = getDefaultTimeZoneId;
|
|
13
16
|
const guessTimeZoneId = () => moment.tz.guess();
|
|
14
17
|
exports.guessTimeZoneId = guessTimeZoneId;
|
|
18
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJtb21lbnQiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY29uZmlndXJhdGlvbiIsImUiLCJ0IiwiV2Vha01hcCIsInIiLCJuIiwiX19lc01vZHVsZSIsIm8iLCJpIiwiZiIsIl9fcHJvdG9fXyIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJzZXQiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImRlZmF1bHRUaW1lWm9uZUlkIiwiZ2V0RGVmYXVsdFRpbWVab25lSWQiLCJzaGFyZENvbmZpZyIsImdldFNoYXJkQ29uZmlnIiwiZXhwb3J0cyIsImd1ZXNzVGltZVpvbmVJZCIsInR6IiwiZ3Vlc3MiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdGltZXpvbmUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSdcclxuaW1wb3J0IHsgZ2V0U2hhcmRDb25maWcgfSBmcm9tICcuLi9jb25zdGFudHMvY29uZmlndXJhdGlvbidcclxuXHJcbmNvbnN0IGRlZmF1bHRUaW1lWm9uZUlkID0gJ0FtZXJpY2EvSW5kaWFuYXBvbGlzJ1xyXG5cclxuZXhwb3J0IGNvbnN0IGdldERlZmF1bHRUaW1lWm9uZUlkID0gKCkgPT4ge1xyXG5cdGNvbnN0IHNoYXJkQ29uZmlnID0gZ2V0U2hhcmRDb25maWcoKVxyXG5cdHJldHVybiBzaGFyZENvbmZpZy5kZWZhdWx0VGltZVpvbmVJZCA/IHNoYXJkQ29uZmlnLmRlZmF1bHRUaW1lWm9uZUlkIDogZGVmYXVsdFRpbWVab25lSWRcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGd1ZXNzVGltZVpvbmVJZCA9ICgpID0+IG1vbWVudC50ei5ndWVzcygpXHJcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsY0FBQSxHQUFBRCxPQUFBO0FBQTJELFNBQUFELHdCQUFBRyxDQUFBLEVBQUFDLENBQUEsNkJBQUFDLE9BQUEsTUFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBTCx1QkFBQSxZQUFBQSxDQUFBRyxDQUFBLEVBQUFDLENBQUEsU0FBQUEsQ0FBQSxJQUFBRCxDQUFBLElBQUFBLENBQUEsQ0FBQUssVUFBQSxTQUFBTCxDQUFBLE1BQUFNLENBQUEsRUFBQUMsQ0FBQSxFQUFBQyxDQUFBLEtBQUFDLFNBQUEsUUFBQUMsT0FBQSxFQUFBVixDQUFBLGlCQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFNBQUFRLENBQUEsTUFBQUYsQ0FBQSxHQUFBTCxDQUFBLEdBQUFHLENBQUEsR0FBQUQsQ0FBQSxRQUFBRyxDQUFBLENBQUFLLEdBQUEsQ0FBQVgsQ0FBQSxVQUFBTSxDQUFBLENBQUFNLEdBQUEsQ0FBQVosQ0FBQSxHQUFBTSxDQUFBLENBQUFPLEdBQUEsQ0FBQWIsQ0FBQSxFQUFBUSxDQUFBLGdCQUFBUCxDQUFBLElBQUFELENBQUEsZ0JBQUFDLENBQUEsT0FBQWEsY0FBQSxDQUFBQyxJQUFBLENBQUFmLENBQUEsRUFBQUMsQ0FBQSxPQUFBTSxDQUFBLElBQUFELENBQUEsR0FBQVUsTUFBQSxDQUFBQyxjQUFBLEtBQUFELE1BQUEsQ0FBQUUsd0JBQUEsQ0FBQWxCLENBQUEsRUFBQUMsQ0FBQSxPQUFBTSxDQUFBLENBQUFLLEdBQUEsSUFBQUwsQ0FBQSxDQUFBTSxHQUFBLElBQUFQLENBQUEsQ0FBQUUsQ0FBQSxFQUFBUCxDQUFBLEVBQUFNLENBQUEsSUFBQUMsQ0FBQSxDQUFBUCxDQUFBLElBQUFELENBQUEsQ0FBQUMsQ0FBQSxXQUFBTyxDQUFBLEtBQUFSLENBQUEsRUFBQUMsQ0FBQTtBQUUzRCxNQUFNa0IsaUJBQWlCLEdBQUcsc0JBQXNCO0FBRXpDLE1BQU1DLG9CQUFvQixHQUFHQSxDQUFBLEtBQU07RUFDekMsTUFBTUMsV0FBVyxHQUFHLElBQUFDLDZCQUFjLEVBQUMsQ0FBQztFQUNwQyxPQUFPRCxXQUFXLENBQUNGLGlCQUFpQixHQUFHRSxXQUFXLENBQUNGLGlCQUFpQixHQUFHQSxpQkFBaUI7QUFDekYsQ0FBQztBQUFBSSxPQUFBLENBQUFILG9CQUFBLEdBQUFBLG9CQUFBO0FBRU0sTUFBTUksZUFBZSxHQUFHQSxDQUFBLEtBQU01QixNQUFNLENBQUM2QixFQUFFLENBQUNDLEtBQUssQ0FBQyxDQUFDO0FBQUFILE9BQUEsQ0FBQUMsZUFBQSxHQUFBQSxlQUFBIiwiaWdub3JlTGlzdCI6W119
|
package/lib/utils/url.js
CHANGED
|
@@ -1,166 +1,166 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.X_FRAME_OPTIONS = void 0;
|
|
7
|
+
exports.fetchText = fetchText;
|
|
4
8
|
exports.getApiBaseUrl = getApiBaseUrl;
|
|
5
9
|
exports.getStorageUrl = getStorageUrl;
|
|
6
10
|
exports.hasHttpProtocol = hasHttpProtocol;
|
|
7
11
|
exports.isUrlValid = isUrlValid;
|
|
8
|
-
exports.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const shard_2 = require("./shard");
|
|
12
|
+
exports.parseLocation = exports.parseHeadersResponse = void 0;
|
|
13
|
+
var _lodash = require("lodash");
|
|
14
|
+
var _shard = require("../constants/shard");
|
|
15
|
+
var _tier = require("../constants/tier");
|
|
16
|
+
var _windowService = require("../services/windowService");
|
|
17
|
+
var _logger = require("./logger");
|
|
18
|
+
var _shard2 = require("./shard");
|
|
16
19
|
function getApiBaseUrl(tier, apiUrlString) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
// skip shard logic on LOCAL or if not using a custom domain (e.g. staging)
|
|
21
|
+
if (tier === _tier.TIER.LOCAL || apiUrlString.includes('azurewebsites.net')) {
|
|
22
|
+
return apiUrlString;
|
|
23
|
+
}
|
|
24
|
+
let shardKey = (0, _shard2.getShardKey)();
|
|
25
|
+
|
|
26
|
+
// TODO: default ROOT to point to Purdue, until we have a landing marketing page
|
|
27
|
+
if (shardKey === _shard.SHARD.ROOT) {
|
|
28
|
+
shardKey = _shard.SHARD.PURDUE;
|
|
29
|
+
}
|
|
30
|
+
const protocol = apiUrlString.substring(0, apiUrlString.indexOf('//'));
|
|
31
|
+
const host = apiUrlString.substring(apiUrlString.indexOf('://') + 3);
|
|
32
|
+
let tierSubdomainPart = '';
|
|
33
|
+
switch (tier) {
|
|
34
|
+
case _tier.TIER.DEV:
|
|
35
|
+
tierSubdomainPart = '.dev';
|
|
36
|
+
break;
|
|
37
|
+
case _tier.TIER.QA:
|
|
38
|
+
tierSubdomainPart = '.qa';
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
return `${protocol}//${shardKey}${tierSubdomainPart}.${host}`;
|
|
38
42
|
}
|
|
39
43
|
function getStorageUrl(config, url) {
|
|
40
|
-
|
|
41
|
-
? url.replace('http://127.0.0.1:10000', config.STORAGE_URL)
|
|
42
|
-
: url;
|
|
44
|
+
return config.TIER === _tier.TIER.LOCAL && !!config.STORAGE_URL ? url.replace('http://127.0.0.1:10000', config.STORAGE_URL) : url;
|
|
43
45
|
}
|
|
44
46
|
function hasHttpProtocol(url) {
|
|
45
|
-
|
|
47
|
+
return /^(http|https):\/\//.test(url);
|
|
46
48
|
}
|
|
47
49
|
function isUrlValid(url) {
|
|
48
|
-
|
|
50
|
+
return /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=]+$/.test(url);
|
|
49
51
|
}
|
|
52
|
+
|
|
50
53
|
/** The total number of tries for `fetchText`, including the initial request. */
|
|
51
54
|
const TRY_LIMIT = 5;
|
|
52
55
|
function wait(time) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
return new Promise(resolve => {
|
|
57
|
+
setTimeout(resolve, time);
|
|
58
|
+
});
|
|
56
59
|
}
|
|
57
|
-
function fetchText(url, options) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} while (tryCount < TRY_LIMIT);
|
|
74
|
-
throw new Error(`Failed to fetch ${url} after ${TRY_LIMIT} attempts.`);
|
|
75
|
-
});
|
|
60
|
+
async function fetchText(url, options) {
|
|
61
|
+
let tryCount = 0;
|
|
62
|
+
do {
|
|
63
|
+
tryCount++;
|
|
64
|
+
try {
|
|
65
|
+
const resp = await fetch(url, options);
|
|
66
|
+
const text = await resp.text();
|
|
67
|
+
return text;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
(0, _logger.getLogger)().error(`Failed to fetch ${url}. attempt: ${tryCount}, error: ${error}`);
|
|
70
|
+
if (tryCount < TRY_LIMIT) {
|
|
71
|
+
await wait(2 ** (tryCount - 1) * 100); // 100, 200, 400, 800
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} while (tryCount < TRY_LIMIT);
|
|
75
|
+
throw new Error(`Failed to fetch ${url} after ${TRY_LIMIT} attempts.`);
|
|
76
76
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Using the given headers, determine if a url is allowed to be displayed in an iFrame.
|
|
85
|
-
* @param headers An array of request headers.
|
|
86
|
-
* @returns The parsed result
|
|
77
|
+
let X_FRAME_OPTIONS = exports.X_FRAME_OPTIONS = /*#__PURE__*/function (X_FRAME_OPTIONS) {
|
|
78
|
+
X_FRAME_OPTIONS["DENY"] = "DENY";
|
|
79
|
+
X_FRAME_OPTIONS["SAMEORIGIN"] = "SAMEORIGIN";
|
|
80
|
+
X_FRAME_OPTIONS["ALLOW_FROM"] = "ALLOW-FROM";
|
|
81
|
+
return X_FRAME_OPTIONS;
|
|
82
|
+
}({});
|
|
83
|
+
/**
|
|
84
|
+
* Using the given headers, determine if a url is allowed to be displayed in an iFrame.
|
|
85
|
+
* @param headers An array of request headers.
|
|
86
|
+
* @returns The parsed result
|
|
87
87
|
*/
|
|
88
|
-
const parseHeadersResponse =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
|
-
result.isValid = true;
|
|
98
|
-
result.iFrameAllowed = true;
|
|
99
|
-
const location = windowService_1.windowService.getLocation();
|
|
100
|
-
// content-security-policy / x-content-security-policy
|
|
101
|
-
// can contain 'frame-ancestors <source> <source>' with one or many sources
|
|
102
|
-
// iFrameAllowed if it does not contain 'frame-ancestors' or if it does with an acceptable source
|
|
103
|
-
const xContentSecurityPolicy = (0, lodash_1.find)(headers, (value, key) => key.toLowerCase() === 'content-security-policy' || key.toLowerCase() === 'x-content-security-policy');
|
|
104
|
-
if (xContentSecurityPolicy && (0, lodash_1.isArray)(xContentSecurityPolicy)) {
|
|
105
|
-
// define all acceptable frame-ancestors sources
|
|
106
|
-
// protocol, full location host, host, and all wildcard permutations
|
|
107
|
-
const acceptableSources = [location.protocol, `${location.protocol}//${location.host}`, location.host];
|
|
108
|
-
const hostParts = location.host.split('.');
|
|
109
|
-
while (hostParts.length > 2) {
|
|
110
|
-
hostParts.shift();
|
|
111
|
-
const tempHost = `*.${hostParts.join('.')}`;
|
|
112
|
-
acceptableSources.push(tempHost);
|
|
113
|
-
acceptableSources.push(`${location.protocol}//${tempHost}`);
|
|
114
|
-
}
|
|
115
|
-
result.iFrameAllowed =
|
|
116
|
-
!xContentSecurityPolicy.some(x => x.indexOf('frame-ancestors ') >= 0) ||
|
|
117
|
-
xContentSecurityPolicy.some(x => {
|
|
118
|
-
/**
|
|
119
|
-
* Matches
|
|
120
|
-
* * the string `frame-ancestors `
|
|
121
|
-
* * one or many of the following, followed by a space, semicolon, or end of string
|
|
122
|
-
* * `http:`
|
|
123
|
-
* * `https:`
|
|
124
|
-
* * `'self'`
|
|
125
|
-
* * `'none'`
|
|
126
|
-
* * url with optional scheme and optional asterisk wildcards
|
|
127
|
-
*/
|
|
128
|
-
const frameAncestorsRegex = /frame-ancestors ((?:(?:(?:http:)|(?:https:)|(?:'self')|(?:'none')|(?:(?:https?:\/\/)?[\w*.-]+(?:\.[\w*.-]+)+[\w-._~:/?#[\]@!$&'()*+,=]+))(?:[ ;]|$))+)/g;
|
|
129
|
-
const results = frameAncestorsRegex.exec(x);
|
|
130
|
-
if (!results) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const sources = results[1].split(' ');
|
|
134
|
-
return sources.some(source => acceptableSources.some(acceptableSource => acceptableSource === source));
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
// x-frame-options can be ['SAMEORIGIN', 'DENY', 'ALLOW-FROM...']
|
|
138
|
-
// iFrameAllowed if the the x-frame-options is 'ALLOW-FROM {app web url}'
|
|
139
|
-
const xFrameOptions = (0, lodash_1.find)(headers, (value, key) => key.toLowerCase() === 'x-frame-options');
|
|
140
|
-
if (xFrameOptions && (0, lodash_1.isArray)(xFrameOptions)) {
|
|
141
|
-
result.iFrameAllowed =
|
|
142
|
-
!xFrameOptions.some(x => x === X_FRAME_OPTIONS.DENY || x === X_FRAME_OPTIONS.SAMEORIGIN) &&
|
|
143
|
-
xFrameOptions.some(x => x === `${X_FRAME_OPTIONS.ALLOW_FROM} ${location.protocol}//${location.host}`);
|
|
144
|
-
}
|
|
88
|
+
const parseHeadersResponse = headers => {
|
|
89
|
+
// default result
|
|
90
|
+
const result = {
|
|
91
|
+
isValid: false,
|
|
92
|
+
iFrameAllowed: undefined
|
|
93
|
+
};
|
|
94
|
+
if (!headers) {
|
|
145
95
|
return result;
|
|
96
|
+
}
|
|
97
|
+
result.isValid = true;
|
|
98
|
+
result.iFrameAllowed = true;
|
|
99
|
+
const location = _windowService.windowService.getLocation();
|
|
100
|
+
|
|
101
|
+
// content-security-policy / x-content-security-policy
|
|
102
|
+
// can contain 'frame-ancestors <source> <source>' with one or many sources
|
|
103
|
+
// iFrameAllowed if it does not contain 'frame-ancestors' or if it does with an acceptable source
|
|
104
|
+
const xContentSecurityPolicy = (0, _lodash.find)(headers, (value, key) => key.toLowerCase() === 'content-security-policy' || key.toLowerCase() === 'x-content-security-policy');
|
|
105
|
+
if (xContentSecurityPolicy && (0, _lodash.isArray)(xContentSecurityPolicy)) {
|
|
106
|
+
// define all acceptable frame-ancestors sources
|
|
107
|
+
// protocol, full location host, host, and all wildcard permutations
|
|
108
|
+
const acceptableSources = [location.protocol, `${location.protocol}//${location.host}`, location.host];
|
|
109
|
+
const hostParts = location.host.split('.');
|
|
110
|
+
while (hostParts.length > 2) {
|
|
111
|
+
hostParts.shift();
|
|
112
|
+
const tempHost = `*.${hostParts.join('.')}`;
|
|
113
|
+
acceptableSources.push(tempHost);
|
|
114
|
+
acceptableSources.push(`${location.protocol}//${tempHost}`);
|
|
115
|
+
}
|
|
116
|
+
result.iFrameAllowed = !xContentSecurityPolicy.some(x => x.indexOf('frame-ancestors ') >= 0) || xContentSecurityPolicy.some(x => {
|
|
117
|
+
/**
|
|
118
|
+
* Matches
|
|
119
|
+
* * the string `frame-ancestors `
|
|
120
|
+
* * one or many of the following, followed by a space, semicolon, or end of string
|
|
121
|
+
* * `http:`
|
|
122
|
+
* * `https:`
|
|
123
|
+
* * `'self'`
|
|
124
|
+
* * `'none'`
|
|
125
|
+
* * url with optional scheme and optional asterisk wildcards
|
|
126
|
+
*/
|
|
127
|
+
const frameAncestorsRegex = /frame-ancestors ((?:(?:(?:http:)|(?:https:)|(?:'self')|(?:'none')|(?:(?:https?:\/\/)?[\w*.-]+(?:\.[\w*.-]+)+[\w-._~:/?#[\]@!$&'()*+,=]+))(?:[ ;]|$))+)/g;
|
|
128
|
+
const results = frameAncestorsRegex.exec(x);
|
|
129
|
+
if (!results) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
const sources = results[1].split(' ');
|
|
133
|
+
return sources.some(source => acceptableSources.some(acceptableSource => acceptableSource === source));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// x-frame-options can be ['SAMEORIGIN', 'DENY', 'ALLOW-FROM...']
|
|
138
|
+
// iFrameAllowed if the the x-frame-options is 'ALLOW-FROM {app web url}'
|
|
139
|
+
const xFrameOptions = (0, _lodash.find)(headers, (value, key) => key.toLowerCase() === 'x-frame-options');
|
|
140
|
+
if (xFrameOptions && (0, _lodash.isArray)(xFrameOptions)) {
|
|
141
|
+
result.iFrameAllowed = !xFrameOptions.some(x => x === X_FRAME_OPTIONS.DENY || x === X_FRAME_OPTIONS.SAMEORIGIN) && xFrameOptions.some(x => x === `${X_FRAME_OPTIONS.ALLOW_FROM} ${location.protocol}//${location.host}`);
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
146
144
|
};
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Parse a path string into a location with separate pathname, search, and hash components.
|
|
150
|
-
* @param path A path string
|
|
151
|
-
* @returns The parsed result
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Parse a path string into a location with separate pathname, search, and hash components.
|
|
148
|
+
* @param path A path string
|
|
149
|
+
* @returns The parsed result
|
|
152
150
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
exports.parseHeadersResponse = parseHeadersResponse;
|
|
152
|
+
const parseLocation = path => {
|
|
153
|
+
const searchStart = path.indexOf('?');
|
|
154
|
+
const hashStart = path.indexOf('#');
|
|
155
|
+
const searchEnd = hashStart > -1 ? hashStart : undefined;
|
|
156
|
+
const pathname = searchStart > -1 ? path.substring(0, searchStart) : hashStart > -1 ? path.substring(0, hashStart) : path;
|
|
157
|
+
const search = searchStart > -1 ? path.substring(searchStart, searchEnd) : undefined;
|
|
158
|
+
const hash = hashStart > -1 ? path.substring(hashStart) : undefined;
|
|
159
|
+
return {
|
|
160
|
+
pathname: pathname || '/',
|
|
161
|
+
search: search,
|
|
162
|
+
hash: hash
|
|
163
|
+
};
|
|
165
164
|
};
|
|
166
165
|
exports.parseLocation = parseLocation;
|
|
166
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl9zaGFyZCIsIl90aWVyIiwiX3dpbmRvd1NlcnZpY2UiLCJfbG9nZ2VyIiwiX3NoYXJkMiIsImdldEFwaUJhc2VVcmwiLCJ0aWVyIiwiYXBpVXJsU3RyaW5nIiwiVElFUiIsIkxPQ0FMIiwiaW5jbHVkZXMiLCJzaGFyZEtleSIsImdldFNoYXJkS2V5IiwiU0hBUkQiLCJST09UIiwiUFVSRFVFIiwicHJvdG9jb2wiLCJzdWJzdHJpbmciLCJpbmRleE9mIiwiaG9zdCIsInRpZXJTdWJkb21haW5QYXJ0IiwiREVWIiwiUUEiLCJnZXRTdG9yYWdlVXJsIiwiY29uZmlnIiwidXJsIiwiU1RPUkFHRV9VUkwiLCJyZXBsYWNlIiwiaGFzSHR0cFByb3RvY29sIiwidGVzdCIsImlzVXJsVmFsaWQiLCJUUllfTElNSVQiLCJ3YWl0IiwidGltZSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2V0VGltZW91dCIsImZldGNoVGV4dCIsIm9wdGlvbnMiLCJ0cnlDb3VudCIsInJlc3AiLCJmZXRjaCIsInRleHQiLCJlcnJvciIsImdldExvZ2dlciIsIkVycm9yIiwiWF9GUkFNRV9PUFRJT05TIiwiZXhwb3J0cyIsInBhcnNlSGVhZGVyc1Jlc3BvbnNlIiwiaGVhZGVycyIsInJlc3VsdCIsImlzVmFsaWQiLCJpRnJhbWVBbGxvd2VkIiwidW5kZWZpbmVkIiwibG9jYXRpb24iLCJ3aW5kb3dTZXJ2aWNlIiwiZ2V0TG9jYXRpb24iLCJ4Q29udGVudFNlY3VyaXR5UG9saWN5IiwiZmluZCIsInZhbHVlIiwia2V5IiwidG9Mb3dlckNhc2UiLCJpc0FycmF5IiwiYWNjZXB0YWJsZVNvdXJjZXMiLCJob3N0UGFydHMiLCJzcGxpdCIsImxlbmd0aCIsInNoaWZ0IiwidGVtcEhvc3QiLCJqb2luIiwicHVzaCIsInNvbWUiLCJ4IiwiZnJhbWVBbmNlc3RvcnNSZWdleCIsInJlc3VsdHMiLCJleGVjIiwic291cmNlcyIsInNvdXJjZSIsImFjY2VwdGFibGVTb3VyY2UiLCJ4RnJhbWVPcHRpb25zIiwiREVOWSIsIlNBTUVPUklHSU4iLCJBTExPV19GUk9NIiwicGFyc2VMb2NhdGlvbiIsInBhdGgiLCJzZWFyY2hTdGFydCIsImhhc2hTdGFydCIsInNlYXJjaEVuZCIsInBhdGhuYW1lIiwic2VhcmNoIiwiaGFzaCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy91cmwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgaHR0cCBmcm9tICdub2RlOmh0dHAnXHJcbmltcG9ydCB7IExvY2F0aW9uRGVzY3JpcHRvciB9IGZyb20gJ2hpc3RvcnknXHJcbmltcG9ydCB7IGZpbmQsIGlzQXJyYXkgfSBmcm9tICdsb2Rhc2gnXHJcbmltcG9ydCB7IFNIQVJEIH0gZnJvbSAnLi4vY29uc3RhbnRzL3NoYXJkJ1xyXG5pbXBvcnQgeyBUSUVSIH0gZnJvbSAnLi4vY29uc3RhbnRzL3RpZXInXHJcbmltcG9ydCB7IHdpbmRvd1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy93aW5kb3dTZXJ2aWNlJ1xyXG5pbXBvcnQgeyBBcHBDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vdHlwZXMnXHJcbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJ1xyXG5pbXBvcnQgeyBnZXRTaGFyZEtleSB9IGZyb20gJy4vc2hhcmQnXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBpQmFzZVVybCh0aWVyOiBUSUVSLCBhcGlVcmxTdHJpbmc6IHN0cmluZykge1xyXG5cdC8vIHNraXAgc2hhcmQgbG9naWMgb24gTE9DQUwgb3IgaWYgbm90IHVzaW5nIGEgY3VzdG9tIGRvbWFpbiAoZS5nLiBzdGFnaW5nKVxyXG5cdGlmICh0aWVyID09PSBUSUVSLkxPQ0FMIHx8IGFwaVVybFN0cmluZy5pbmNsdWRlcygnYXp1cmV3ZWJzaXRlcy5uZXQnKSkge1xyXG5cdFx0cmV0dXJuIGFwaVVybFN0cmluZ1xyXG5cdH1cclxuXHRsZXQgc2hhcmRLZXkgPSBnZXRTaGFyZEtleSgpXHJcblxyXG5cdC8vIFRPRE86IGRlZmF1bHQgUk9PVCB0byBwb2ludCB0byBQdXJkdWUsIHVudGlsIHdlIGhhdmUgYSBsYW5kaW5nIG1hcmtldGluZyBwYWdlXHJcblx0aWYgKHNoYXJkS2V5ID09PSBTSEFSRC5ST09UKSB7XHJcblx0XHRzaGFyZEtleSA9IFNIQVJELlBVUkRVRVxyXG5cdH1cclxuXHJcblx0Y29uc3QgcHJvdG9jb2wgPSBhcGlVcmxTdHJpbmcuc3Vic3RyaW5nKDAsIGFwaVVybFN0cmluZy5pbmRleE9mKCcvLycpKVxyXG5cdGNvbnN0IGhvc3QgPSBhcGlVcmxTdHJpbmcuc3Vic3RyaW5nKGFwaVVybFN0cmluZy5pbmRleE9mKCc6Ly8nKSArIDMpXHJcblx0bGV0IHRpZXJTdWJkb21haW5QYXJ0ID0gJydcclxuXHRzd2l0Y2ggKHRpZXIpIHtcclxuXHRcdGNhc2UgVElFUi5ERVY6XHJcblx0XHRcdHRpZXJTdWJkb21haW5QYXJ0ID0gJy5kZXYnXHJcblx0XHRcdGJyZWFrXHJcblx0XHRjYXNlIFRJRVIuUUE6XHJcblx0XHRcdHRpZXJTdWJkb21haW5QYXJ0ID0gJy5xYSdcclxuXHRcdFx0YnJlYWtcclxuXHR9XHJcblx0cmV0dXJuIGAke3Byb3RvY29sfS8vJHtzaGFyZEtleX0ke3RpZXJTdWJkb21haW5QYXJ0fS4ke2hvc3R9YFxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RvcmFnZVVybChjb25maWc6IEFwcENvbmZpZ3VyYXRpb24sIHVybDogc3RyaW5nKSB7XHJcblx0cmV0dXJuIGNvbmZpZy5USUVSID09PSBUSUVSLkxPQ0FMICYmICEhY29uZmlnLlNUT1JBR0VfVVJMXHJcblx0XHQ/IHVybC5yZXBsYWNlKCdodHRwOi8vMTI3LjAuMC4xOjEwMDAwJywgY29uZmlnLlNUT1JBR0VfVVJMKVxyXG5cdFx0OiB1cmxcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGhhc0h0dHBQcm90b2NvbCh1cmw6IHN0cmluZykge1xyXG5cdHJldHVybiAvXihodHRwfGh0dHBzKTpcXC9cXC8vLnRlc3QodXJsKVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNVcmxWYWxpZCh1cmw6IHN0cmluZykge1xyXG5cdHJldHVybiAvXig/Omh0dHAocyk/OlxcL1xcLyk/W1xcdy4tXSsoPzpcXC5bXFx3Li1dKykrW1xcd1xcLS5ffjovPyNbXFxdQCEkJicoKSorLDs9XSskLy50ZXN0KHVybClcclxufVxyXG5cclxuLyoqIFRoZSB0b3RhbCBudW1iZXIgb2YgdHJpZXMgZm9yIGBmZXRjaFRleHRgLCBpbmNsdWRpbmcgdGhlIGluaXRpYWwgcmVxdWVzdC4gKi9cclxuY29uc3QgVFJZX0xJTUlUID0gNVxyXG5cclxuZnVuY3Rpb24gd2FpdCh0aW1lOiBudW1iZXIpIHtcclxuXHRyZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcblx0XHRzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWUpXHJcblx0fSlcclxufVxyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoVGV4dCh1cmw6IHN0cmluZywgb3B0aW9ucz86IFJlcXVlc3RJbml0KSB7XHJcblx0bGV0IHRyeUNvdW50ID0gMFxyXG5cdGRvIHtcclxuXHRcdHRyeUNvdW50KytcclxuXHRcdHRyeSB7XHJcblx0XHRcdGNvbnN0IHJlc3AgPSBhd2FpdCBmZXRjaCh1cmwsIG9wdGlvbnMpXHJcblx0XHRcdGNvbnN0IHRleHQgPSBhd2FpdCByZXNwLnRleHQoKVxyXG5cdFx0XHRyZXR1cm4gdGV4dFxyXG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcclxuXHRcdFx0Z2V0TG9nZ2VyKCkuZXJyb3IoYEZhaWxlZCB0byBmZXRjaCAke3VybH0uIGF0dGVtcHQ6ICR7dHJ5Q291bnR9LCBlcnJvcjogJHtlcnJvcn1gKVxyXG5cdFx0XHRpZiAodHJ5Q291bnQgPCBUUllfTElNSVQpIHtcclxuXHRcdFx0XHRhd2FpdCB3YWl0KDIgKiogKHRyeUNvdW50IC0gMSkgKiAxMDApIC8vIDEwMCwgMjAwLCA0MDAsIDgwMFxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSB3aGlsZSAodHJ5Q291bnQgPCBUUllfTElNSVQpXHJcblxyXG5cdHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoICR7dXJsfSBhZnRlciAke1RSWV9MSU1JVH0gYXR0ZW1wdHMuYClcclxufVxyXG5cclxuZXhwb3J0IGVudW0gWF9GUkFNRV9PUFRJT05TIHtcclxuXHRERU5ZID0gJ0RFTlknLFxyXG5cdFNBTUVPUklHSU4gPSAnU0FNRU9SSUdJTicsXHJcblx0QUxMT1dfRlJPTSA9ICdBTExPVy1GUk9NJ1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZEhlYWRlcnNSZXNwb25zZSB7XHJcblx0aXNWYWxpZDogYm9vbGVhblxyXG5cdGlGcmFtZUFsbG93ZWQ/OiBib29sZWFuXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBVc2luZyB0aGUgZ2l2ZW4gaGVhZGVycywgZGV0ZXJtaW5lIGlmIGEgdXJsIGlzIGFsbG93ZWQgdG8gYmUgZGlzcGxheWVkIGluIGFuIGlGcmFtZS5cclxuICogQHBhcmFtIGhlYWRlcnMgQW4gYXJyYXkgb2YgcmVxdWVzdCBoZWFkZXJzLlxyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlc3VsdFxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHBhcnNlSGVhZGVyc1Jlc3BvbnNlID0gKGhlYWRlcnM/OiBodHRwLkluY29taW5nSHR0cEhlYWRlcnMpID0+IHtcclxuXHQvLyBkZWZhdWx0IHJlc3VsdFxyXG5cdGNvbnN0IHJlc3VsdDogUGFyc2VkSGVhZGVyc1Jlc3BvbnNlID0ge1xyXG5cdFx0aXNWYWxpZDogZmFsc2UsXHJcblx0XHRpRnJhbWVBbGxvd2VkOiB1bmRlZmluZWRcclxuXHR9XHJcblxyXG5cdGlmICghaGVhZGVycykge1xyXG5cdFx0cmV0dXJuIHJlc3VsdFxyXG5cdH1cclxuXHJcblx0cmVzdWx0LmlzVmFsaWQgPSB0cnVlXHJcblx0cmVzdWx0LmlGcmFtZUFsbG93ZWQgPSB0cnVlXHJcblxyXG5cdGNvbnN0IGxvY2F0aW9uID0gd2luZG93U2VydmljZS5nZXRMb2NhdGlvbigpXHJcblxyXG5cdC8vIGNvbnRlbnQtc2VjdXJpdHktcG9saWN5IC8geC1jb250ZW50LXNlY3VyaXR5LXBvbGljeVxyXG5cdC8vIGNhbiBjb250YWluICdmcmFtZS1hbmNlc3RvcnMgPHNvdXJjZT4gPHNvdXJjZT4nIHdpdGggb25lIG9yIG1hbnkgc291cmNlc1xyXG5cdC8vIGlGcmFtZUFsbG93ZWQgaWYgaXQgZG9lcyBub3QgY29udGFpbiAnZnJhbWUtYW5jZXN0b3JzJyBvciBpZiBpdCBkb2VzIHdpdGggYW4gYWNjZXB0YWJsZSBzb3VyY2VcclxuXHRjb25zdCB4Q29udGVudFNlY3VyaXR5UG9saWN5ID0gZmluZChcclxuXHRcdGhlYWRlcnMsXHJcblx0XHQodmFsdWUsIGtleSkgPT5cclxuXHRcdFx0a2V5LnRvTG93ZXJDYXNlKCkgPT09ICdjb250ZW50LXNlY3VyaXR5LXBvbGljeScgfHwga2V5LnRvTG93ZXJDYXNlKCkgPT09ICd4LWNvbnRlbnQtc2VjdXJpdHktcG9saWN5J1xyXG5cdClcclxuXHRpZiAoeENvbnRlbnRTZWN1cml0eVBvbGljeSAmJiBpc0FycmF5KHhDb250ZW50U2VjdXJpdHlQb2xpY3kpKSB7XHJcblx0XHQvLyBkZWZpbmUgYWxsIGFjY2VwdGFibGUgZnJhbWUtYW5jZXN0b3JzIHNvdXJjZXNcclxuXHRcdC8vIHByb3RvY29sLCBmdWxsIGxvY2F0aW9uIGhvc3QsIGhvc3QsIGFuZCBhbGwgd2lsZGNhcmQgcGVybXV0YXRpb25zXHJcblx0XHRjb25zdCBhY2NlcHRhYmxlU291cmNlcyA9IFtsb2NhdGlvbi5wcm90b2NvbCwgYCR7bG9jYXRpb24ucHJvdG9jb2x9Ly8ke2xvY2F0aW9uLmhvc3R9YCwgbG9jYXRpb24uaG9zdF1cclxuXHRcdGNvbnN0IGhvc3RQYXJ0cyA9IGxvY2F0aW9uLmhvc3Quc3BsaXQoJy4nKVxyXG5cdFx0d2hpbGUgKGhvc3RQYXJ0cy5sZW5ndGggPiAyKSB7XHJcblx0XHRcdGhvc3RQYXJ0cy5zaGlmdCgpXHJcblx0XHRcdGNvbnN0IHRlbXBIb3N0ID0gYCouJHtob3N0UGFydHMuam9pbignLicpfWBcclxuXHRcdFx0YWNjZXB0YWJsZVNvdXJjZXMucHVzaCh0ZW1wSG9zdClcclxuXHRcdFx0YWNjZXB0YWJsZVNvdXJjZXMucHVzaChgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7dGVtcEhvc3R9YClcclxuXHRcdH1cclxuXHRcdHJlc3VsdC5pRnJhbWVBbGxvd2VkID1cclxuXHRcdFx0IXhDb250ZW50U2VjdXJpdHlQb2xpY3kuc29tZSh4ID0+IHguaW5kZXhPZignZnJhbWUtYW5jZXN0b3JzICcpID49IDApIHx8XHJcblx0XHRcdHhDb250ZW50U2VjdXJpdHlQb2xpY3kuc29tZSh4ID0+IHtcclxuXHRcdFx0XHQvKipcclxuXHRcdFx0XHQgKiBNYXRjaGVzXHJcblx0XHRcdFx0ICogKiB0aGUgc3RyaW5nIGBmcmFtZS1hbmNlc3RvcnMgYFxyXG5cdFx0XHRcdCAqICogb25lIG9yIG1hbnkgb2YgdGhlIGZvbGxvd2luZywgZm9sbG93ZWQgYnkgYSBzcGFjZSwgc2VtaWNvbG9uLCBvciBlbmQgb2Ygc3RyaW5nXHJcblx0XHRcdFx0ICogICAgICogYGh0dHA6YFxyXG5cdFx0XHRcdCAqICAgICAqIGBodHRwczpgXHJcblx0XHRcdFx0ICogICAgICogYCdzZWxmJ2BcclxuXHRcdFx0XHQgKiAgICAgKiBgJ25vbmUnYFxyXG5cdFx0XHRcdCAqICAgICAqIHVybCB3aXRoIG9wdGlvbmFsIHNjaGVtZSBhbmQgb3B0aW9uYWwgYXN0ZXJpc2sgd2lsZGNhcmRzXHJcblx0XHRcdFx0ICovXHJcblx0XHRcdFx0Y29uc3QgZnJhbWVBbmNlc3RvcnNSZWdleCA9XHJcblx0XHRcdFx0XHQvZnJhbWUtYW5jZXN0b3JzICgoPzooPzooPzpodHRwOil8KD86aHR0cHM6KXwoPzonc2VsZicpfCg/Oidub25lJyl8KD86KD86aHR0cHM/OlxcL1xcLyk/W1xcdyouLV0rKD86XFwuW1xcdyouLV0rKStbXFx3LS5ffjovPyNbXFxdQCEkJicoKSorLD1dKykpKD86WyA7XXwkKSkrKS9nXHJcblx0XHRcdFx0Y29uc3QgcmVzdWx0cyA9IGZyYW1lQW5jZXN0b3JzUmVnZXguZXhlYyh4KVxyXG5cdFx0XHRcdGlmICghcmVzdWx0cykge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGNvbnN0IHNvdXJjZXMgPSByZXN1bHRzWzFdLnNwbGl0KCcgJylcclxuXHRcdFx0XHRyZXR1cm4gc291cmNlcy5zb21lKHNvdXJjZSA9PiBhY2NlcHRhYmxlU291cmNlcy5zb21lKGFjY2VwdGFibGVTb3VyY2UgPT4gYWNjZXB0YWJsZVNvdXJjZSA9PT0gc291cmNlKSlcclxuXHRcdFx0fSlcclxuXHR9XHJcblxyXG5cdC8vIHgtZnJhbWUtb3B0aW9ucyBjYW4gYmUgWydTQU1FT1JJR0lOJywgJ0RFTlknLCAnQUxMT1ctRlJPTS4uLiddXHJcblx0Ly8gaUZyYW1lQWxsb3dlZCBpZiB0aGUgdGhlIHgtZnJhbWUtb3B0aW9ucyBpcyAnQUxMT1ctRlJPTSB7YXBwIHdlYiB1cmx9J1xyXG5cdGNvbnN0IHhGcmFtZU9wdGlvbnMgPSBmaW5kKGhlYWRlcnMsICh2YWx1ZSwga2V5KSA9PiBrZXkudG9Mb3dlckNhc2UoKSA9PT0gJ3gtZnJhbWUtb3B0aW9ucycpXHJcblx0aWYgKHhGcmFtZU9wdGlvbnMgJiYgaXNBcnJheSh4RnJhbWVPcHRpb25zKSkge1xyXG5cdFx0cmVzdWx0LmlGcmFtZUFsbG93ZWQgPVxyXG5cdFx0XHQheEZyYW1lT3B0aW9ucy5zb21lKHggPT4geCA9PT0gWF9GUkFNRV9PUFRJT05TLkRFTlkgfHwgeCA9PT0gWF9GUkFNRV9PUFRJT05TLlNBTUVPUklHSU4pICYmXHJcblx0XHRcdHhGcmFtZU9wdGlvbnMuc29tZSh4ID0+IHggPT09IGAke1hfRlJBTUVfT1BUSU9OUy5BTExPV19GUk9NfSAke2xvY2F0aW9uLnByb3RvY29sfS8vJHtsb2NhdGlvbi5ob3N0fWApXHJcblx0fVxyXG5cdHJldHVybiByZXN1bHRcclxufVxyXG5cclxuLyoqXHJcbiAqIFBhcnNlIGEgcGF0aCBzdHJpbmcgaW50byBhIGxvY2F0aW9uIHdpdGggc2VwYXJhdGUgcGF0aG5hbWUsIHNlYXJjaCwgYW5kIGhhc2ggY29tcG9uZW50cy5cclxuICogQHBhcmFtIHBhdGggQSBwYXRoIHN0cmluZ1xyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlc3VsdFxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHBhcnNlTG9jYXRpb24gPSAocGF0aDogc3RyaW5nKTogTG9jYXRpb25EZXNjcmlwdG9yID0+IHtcclxuXHRjb25zdCBzZWFyY2hTdGFydCA9IHBhdGguaW5kZXhPZignPycpXHJcblx0Y29uc3QgaGFzaFN0YXJ0ID0gcGF0aC5pbmRleE9mKCcjJylcclxuXHRjb25zdCBzZWFyY2hFbmQgPSBoYXNoU3RhcnQgPiAtMSA/IGhhc2hTdGFydCA6IHVuZGVmaW5lZFxyXG5cdGNvbnN0IHBhdGhuYW1lID1cclxuXHRcdHNlYXJjaFN0YXJ0ID4gLTEgPyBwYXRoLnN1YnN0cmluZygwLCBzZWFyY2hTdGFydCkgOiBoYXNoU3RhcnQgPiAtMSA/IHBhdGguc3Vic3RyaW5nKDAsIGhhc2hTdGFydCkgOiBwYXRoXHJcblx0Y29uc3Qgc2VhcmNoID0gc2VhcmNoU3RhcnQgPiAtMSA/IHBhdGguc3Vic3RyaW5nKHNlYXJjaFN0YXJ0LCBzZWFyY2hFbmQpIDogdW5kZWZpbmVkXHJcblx0Y29uc3QgaGFzaCA9IGhhc2hTdGFydCA+IC0xID8gcGF0aC5zdWJzdHJpbmcoaGFzaFN0YXJ0KSA6IHVuZGVmaW5lZFxyXG5cdHJldHVybiB7XHJcblx0XHRwYXRobmFtZTogcGF0aG5hbWUgfHwgJy8nLFxyXG5cdFx0c2VhcmNoOiBzZWFyY2gsXHJcblx0XHRoYXNoOiBoYXNoXHJcblx0fVxyXG59XHJcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBRUEsSUFBQUEsT0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsTUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUs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
|