studiokit-scaffolding-js 7.0.12-next.1.3 → 7.0.12-next.2.1

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.
Files changed (258) hide show
  1. package/lib/components/ActionList.js +164 -37
  2. package/lib/components/AlertDialog.js +128 -12
  3. package/lib/components/AlertWithIcon.js +88 -29
  4. package/lib/components/ConnectedModal.js +35 -12
  5. package/lib/components/Dropdowns/GroupsDropdown.js +63 -45
  6. package/lib/components/Dropdowns/ManagedNavDropdown.js +92 -67
  7. package/lib/components/Dropdowns/UserDropdown.js +105 -24
  8. package/lib/components/Dropdowns/index.js +4 -10
  9. package/lib/components/EntityOwnerList.js +47 -21
  10. package/lib/components/Error.js +101 -12
  11. package/lib/components/ErrorBoundary.js +127 -38
  12. package/lib/components/ErrorMessage.js +39 -12
  13. package/lib/components/Forms/DateField.js +56 -45
  14. package/lib/components/Forms/TimeField.js +76 -45
  15. package/lib/components/Forms/index.js +3 -5
  16. package/lib/components/Groups/CreateEditCopySaveButtons.js +109 -14
  17. package/lib/components/Groups/ExternalGroups/Attach.js +206 -151
  18. package/lib/components/Groups/ExternalGroups/Table.js +176 -48
  19. package/lib/components/Groups/GroupCreateOrEditCommonProps.js +2 -2
  20. package/lib/components/Groups/RosterSyncInfo.js +142 -23
  21. package/lib/components/HOC/AccessibleAppComponent.js +88 -72
  22. package/lib/components/HOC/ActivityRequiredComponent.js +68 -33
  23. package/lib/components/HOC/AsyncComponent.js +49 -41
  24. package/lib/components/HOC/AuthenticatedComponent.js +55 -44
  25. package/lib/components/HOC/CollectionComponent.js +154 -104
  26. package/lib/components/HOC/CollectionFirstItemComponent.js +45 -40
  27. package/lib/components/HOC/CollectionItemComponent.js +152 -100
  28. package/lib/components/HOC/ConnectedModalComponent.js +87 -69
  29. package/lib/components/HOC/DataDependentComponent.js +26 -27
  30. package/lib/components/HOC/EntityComponent.js +57 -53
  31. package/lib/components/HOC/FullscreenModalComponent.js +139 -108
  32. package/lib/components/HOC/GroupActivityRequiredComponent.js +27 -20
  33. package/lib/components/HOC/GuidComponent.js +20 -20
  34. package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +32 -29
  35. package/lib/components/HOC/ModelErrorRedirectComponent.js +37 -39
  36. package/lib/components/HOC/SearchPersistorComponent.js +237 -173
  37. package/lib/components/HOC/UnauthenticatedComponent.js +32 -30
  38. package/lib/components/HOC/UserComponent.js +6 -8
  39. package/lib/components/Icons/IconAlphaList.js +28 -8
  40. package/lib/components/Icons/IconExternalUser.js +28 -8
  41. package/lib/components/Icons/IconImpersonation.js +28 -8
  42. package/lib/components/Icons/IconStopImpersonating.js +28 -8
  43. package/lib/components/Icons/IconTable.js +29 -9
  44. package/lib/components/Icons/IconTableDeleteCol.js +28 -8
  45. package/lib/components/Icons/IconTableDeleteRow.js +28 -8
  46. package/lib/components/Icons/IconTableInsertCol.js +28 -8
  47. package/lib/components/Icons/IconTableInsertRow.js +28 -8
  48. package/lib/components/Impersonation/Button.js +71 -16
  49. package/lib/components/Impersonation/Link.js +72 -16
  50. package/lib/components/Impersonation/UserDetail.js +60 -11
  51. package/lib/components/Loading.js +23 -8
  52. package/lib/components/LockDownBrowser/Check.js +188 -51
  53. package/lib/components/LockDownBrowser/ExitButton.js +22 -13
  54. package/lib/components/LockDownBrowser/Launch.js +64 -64
  55. package/lib/components/Lti/Confirm.js +147 -14
  56. package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +165 -36
  57. package/lib/components/Lti/Launch.js +99 -25
  58. package/lib/components/Lti/LaunchGroup.js +81 -16
  59. package/lib/components/ManageTable.js +304 -90
  60. package/lib/components/ManageTableNoDataComponent.js +38 -7
  61. package/lib/components/NewVersionAlert.js +76 -49
  62. package/lib/components/NotFound.js +81 -11
  63. package/lib/components/Notifications.js +179 -129
  64. package/lib/components/PaginationNextButton.js +28 -9
  65. package/lib/components/PaginationPreviousButton.js +28 -9
  66. package/lib/components/Quill/CustomToolbar.js +427 -222
  67. package/lib/components/Quill/Formats/Image.js +67 -67
  68. package/lib/components/Quill/Formats/List.js +38 -47
  69. package/lib/components/Quill/Formats/Video.js +23 -26
  70. package/lib/components/Quill/ImageDropModule.js +136 -114
  71. package/lib/components/Quill/ImageWarning.js +41 -12
  72. package/lib/components/Quill/ImageWithAltTextModal.js +420 -89
  73. package/lib/components/Quill/Specs/CustomImageSpec.js +32 -31
  74. package/lib/components/Quill/Specs/CustomVideoSpec.js +22 -23
  75. package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +89 -97
  76. package/lib/components/Quill/TableModule/Blots/TableBlot.js +47 -50
  77. package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +48 -51
  78. package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +219 -224
  79. package/lib/components/Quill/TableModule/Blots/TableContainer.js +75 -86
  80. package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +70 -73
  81. package/lib/components/Quill/TableModule/constants.js +40 -42
  82. package/lib/components/Quill/TableModule/index.js +357 -305
  83. package/lib/components/Quill/TableModule/utils.js +39 -48
  84. package/lib/components/Quill/accessibilityFix.js +219 -223
  85. package/lib/components/Quill/index.js +30 -33
  86. package/lib/components/RefreshIndicator/Bordered.js +44 -10
  87. package/lib/components/RefreshIndicator/Inline.js +43 -12
  88. package/lib/components/RefreshIndicator/index.js +257 -62
  89. package/lib/components/SearchControls.js +211 -14
  90. package/lib/components/SentryRoute.js +5 -7
  91. package/lib/components/Tables/RoleFilter.js +66 -38
  92. package/lib/components/Tables/TextFilter.js +58 -18
  93. package/lib/components/UserRoles/Add.js +193 -99
  94. package/lib/components/UserRoles/Context.js +3 -6
  95. package/lib/components/UserRoles/RoleCell.js +176 -75
  96. package/lib/components/UserRoles/Select.js +151 -20
  97. package/lib/components/UserRoles/Table.js +215 -82
  98. package/lib/components/UserRoles/index.js +526 -386
  99. package/lib/config/eslint/index.js +26 -29
  100. package/lib/config/eslint/lib/order.js +21 -28
  101. package/lib/config/eslint/lib/prettier.js +15 -19
  102. package/lib/config/eslint/lib/typescript.js +87 -113
  103. package/lib/config/eslint/react.js +18 -15
  104. package/lib/constants/baseActivity.js +26 -28
  105. package/lib/constants/baseRole.js +10 -12
  106. package/lib/constants/configuration.js +43 -55
  107. package/lib/constants/externalProviderType.js +6 -8
  108. package/lib/constants/fetchErrorData.js +10 -12
  109. package/lib/constants/index.js +13 -15
  110. package/lib/constants/lockDownBrowser.js +23 -25
  111. package/lib/constants/mockData.js +370 -300
  112. package/lib/constants/modelStatus.js +11 -13
  113. package/lib/constants/notificationType.js +8 -10
  114. package/lib/constants/operatingSystem.js +8 -10
  115. package/lib/constants/shard.js +7 -9
  116. package/lib/constants/table.js +18 -22
  117. package/lib/constants/tier.js +8 -10
  118. package/lib/constants/userRole.js +11 -8
  119. package/lib/endpointMappings.js +191 -182
  120. package/lib/hooks/useCollection.js +79 -65
  121. package/lib/hooks/useCollectionConfiguration.js +220 -80
  122. package/lib/hooks/useCollectionItem.js +151 -57
  123. package/lib/hooks/useGuid.js +16 -9
  124. package/lib/hooks/usePrevious.js +14 -13
  125. package/lib/index.js +11 -26
  126. package/lib/redux/actionCreator.js +44 -35
  127. package/lib/redux/actions/AuthAction.js +45 -32
  128. package/lib/redux/actions/ModalAction.js +6 -8
  129. package/lib/redux/actions/ModelAction.js +95 -43
  130. package/lib/redux/actions/NotificationAction.js +6 -8
  131. package/lib/redux/actions/SearchAction.js +5 -7
  132. package/lib/redux/actions/index.js +6 -8
  133. package/lib/redux/configureReducers.js +48 -46
  134. package/lib/redux/configureStore.js +77 -91
  135. package/lib/redux/helpers.js +2 -5
  136. package/lib/redux/reducers/authReducer.js +44 -43
  137. package/lib/redux/reducers/index.js +7 -14
  138. package/lib/redux/reducers/modalsReducer.js +43 -31
  139. package/lib/redux/reducers/modelsReducer.js +131 -137
  140. package/lib/redux/reducers/notificationsReducer.js +20 -20
  141. package/lib/redux/reducers/searchReducer.js +13 -13
  142. package/lib/redux/sagas/appInsightsSaga.js +19 -21
  143. package/lib/redux/sagas/authSaga.js +248 -234
  144. package/lib/redux/sagas/caliperSaga.js +142 -131
  145. package/lib/redux/sagas/clockOffsetSaga.js +29 -32
  146. package/lib/redux/sagas/configurationSaga.js +8 -10
  147. package/lib/redux/sagas/downtimeApiErrorSaga.js +16 -19
  148. package/lib/redux/sagas/errorSaga.js +23 -24
  149. package/lib/redux/sagas/googleAnalyticsSaga.js +24 -27
  150. package/lib/redux/sagas/identityProviderSaga.js +19 -21
  151. package/lib/redux/sagas/initialDataLoadSaga.js +34 -31
  152. package/lib/redux/sagas/lockDownBrowserErrorSaga.js +25 -22
  153. package/lib/redux/sagas/modelFetchSaga.js +302 -286
  154. package/lib/redux/sagas/noStoreSaga.js +60 -61
  155. package/lib/redux/sagas/postLoginDataSaga.js +37 -32
  156. package/lib/redux/sagas/postLoginRedirectSaga.js +22 -27
  157. package/lib/redux/sagas/rootSaga.js +77 -60
  158. package/lib/redux/sagas/sentrySaga.js +25 -28
  159. package/lib/redux/sagas/userIdSaga.js +13 -15
  160. package/lib/services/codeProviderService.js +21 -21
  161. package/lib/services/dateService.js +6 -8
  162. package/lib/services/documentService.js +10 -11
  163. package/lib/services/fetchService.js +103 -95
  164. package/lib/services/persistenceService.js +27 -30
  165. package/lib/services/ticketProviderService.js +25 -25
  166. package/lib/services/tokenPersistenceService.js +8 -10
  167. package/lib/services/windowService.js +14 -16
  168. package/lib/startup.js +110 -101
  169. package/lib/types/AppConfiguration.js +2 -2
  170. package/lib/types/Artifact.js +7 -9
  171. package/lib/types/BaseReduxState.js +2 -2
  172. package/lib/types/Client.js +2 -2
  173. package/lib/types/Collection.js +2 -2
  174. package/lib/types/Configuration.js +2 -2
  175. package/lib/types/DeepLinkingResponseRequest.js +2 -2
  176. package/lib/types/DeletableModel.js +2 -2
  177. package/lib/types/Event.js +2 -2
  178. package/lib/types/ExternalGroup.js +2 -2
  179. package/lib/types/ExternalProvider.js +2 -2
  180. package/lib/types/ExternalTerm.js +2 -2
  181. package/lib/types/Group.js +2 -2
  182. package/lib/types/IdentityProvider.js +2 -2
  183. package/lib/types/LtiLaunch.js +2 -2
  184. package/lib/types/NameOnlyEntity.js +2 -2
  185. package/lib/types/Notification.js +2 -2
  186. package/lib/types/OptionalRecord.js +2 -2
  187. package/lib/types/OwnerSchedule.js +2 -2
  188. package/lib/types/PropertyOfType.js +2 -2
  189. package/lib/types/Quill.js +2 -2
  190. package/lib/types/RoleDescription.js +2 -2
  191. package/lib/types/Search.js +2 -2
  192. package/lib/types/SimpleLocation.js +2 -2
  193. package/lib/types/UniTime.js +2 -2
  194. package/lib/types/User.js +2 -2
  195. package/lib/types/UserRole.js +2 -2
  196. package/lib/types/auth/AuthState.js +2 -2
  197. package/lib/types/auth/CasV1LoginRequestBody.js +2 -2
  198. package/lib/types/auth/ClientCredentials.js +2 -2
  199. package/lib/types/auth/CodeProviderService.js +2 -2
  200. package/lib/types/auth/LocalLoginRequestBody.js +2 -2
  201. package/lib/types/auth/TicketProviderService.js +2 -2
  202. package/lib/types/auth/TokenPersistenceService.js +2 -2
  203. package/lib/types/auth/index.js +8 -10
  204. package/lib/types/externals.d.js +2 -0
  205. package/lib/types/index.js +29 -31
  206. package/lib/types/net/EndpointConfig.js +2 -2
  207. package/lib/types/net/EndpointMapping.js +2 -2
  208. package/lib/types/net/EndpointMappings.js +2 -2
  209. package/lib/types/net/ErrorHandler.js +2 -2
  210. package/lib/types/net/FetchConfig.js +2 -2
  211. package/lib/types/net/FetchErrorData.js +6 -8
  212. package/lib/types/net/FetchResult.js +2 -2
  213. package/lib/types/net/HTTPMethod.js +2 -2
  214. package/lib/types/net/HTTPStatusCode.js +12 -14
  215. package/lib/types/net/Metadata.js +2 -2
  216. package/lib/types/net/Model.js +2 -2
  217. package/lib/types/net/ModelCollection.js +2 -2
  218. package/lib/types/net/ModelsState.js +2 -2
  219. package/lib/types/net/OAuthToken.js +2 -2
  220. package/lib/types/net/OAuthTokenOrNull.js +2 -2
  221. package/lib/types/net/TokenAccessFunction.js +2 -2
  222. package/lib/types/net/index.js +17 -19
  223. package/lib/utils/baseActivity.js +83 -85
  224. package/lib/utils/baseRole.js +32 -36
  225. package/lib/utils/collection.js +403 -297
  226. package/lib/utils/cookies.js +19 -23
  227. package/lib/utils/date.js +188 -205
  228. package/lib/utils/dom.js +130 -131
  229. package/lib/utils/domainIdentifier.js +4 -8
  230. package/lib/utils/entityUserRole.js +2 -5
  231. package/lib/utils/error.js +14 -19
  232. package/lib/utils/events.js +32 -31
  233. package/lib/utils/externalGroup.js +20 -25
  234. package/lib/utils/externalProviders.js +4 -7
  235. package/lib/utils/externalTerms.js +6 -6
  236. package/lib/utils/fetch.js +168 -176
  237. package/lib/utils/group.js +14 -11
  238. package/lib/utils/groupDates.js +38 -46
  239. package/lib/utils/groupRoles.js +23 -32
  240. package/lib/utils/lockDownBrowser.js +12 -15
  241. package/lib/utils/logger.js +23 -28
  242. package/lib/utils/lti.js +4 -7
  243. package/lib/utils/model.js +28 -43
  244. package/lib/utils/number.js +9 -13
  245. package/lib/utils/promise.js +23 -26
  246. package/lib/utils/quill.js +55 -60
  247. package/lib/utils/route.js +52 -60
  248. package/lib/utils/search.js +72 -87
  249. package/lib/utils/shard.js +33 -42
  250. package/lib/utils/sort.js +47 -50
  251. package/lib/utils/string.js +10 -12
  252. package/lib/utils/table.js +29 -33
  253. package/lib/utils/timezone.js +7 -12
  254. package/lib/utils/url.js +130 -144
  255. package/lib/utils/user.js +54 -64
  256. package/lib/utils/userAgent.js +7 -14
  257. package/lib/utils/userRole.js +36 -39
  258. package/package.json +17 -3
@@ -1,396 +1,536 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapStateToProps = exports.UserRoles = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const lodash_1 = require("lodash");
6
- const react_1 = require("react");
7
- const react_bootstrap_1 = require("react-bootstrap");
8
- const react_redux_1 = require("react-redux");
9
- const uuid_1 = require("uuid");
10
- const AlertDialog_1 = require("../../components/AlertDialog");
11
- const Loading_1 = require("../../components/Loading");
12
- const Add_1 = require("../../components/UserRoles/Add");
13
- const Table_1 = require("../../components/UserRoles/Table");
14
- const constants_1 = require("../../constants");
15
- const baseRole_1 = require("../../constants/baseRole");
16
- const modelStatus_1 = require("../../constants/modelStatus");
17
- const actionCreator_1 = require("../../redux/actionCreator");
18
- const actions_1 = require("../../redux/actions");
19
- const noStoreSaga_1 = require("../../redux/sagas/noStoreSaga");
20
- const baseActivity_1 = require("../../utils/baseActivity");
21
- const baseRole_2 = require("../../utils/baseRole");
22
- const domainIdentifier_1 = require("../../utils/domainIdentifier");
23
- const entityUserRole_1 = require("../../utils/entityUserRole");
24
- const fetch_1 = require("../../utils/fetch");
25
- const sort_1 = require("../../utils/sort");
26
- const user_1 = require("../../utils/user");
27
- const userRole_1 = require("../../utils/userRole");
28
- const AlertWithIcon_1 = require("../AlertWithIcon");
29
- const Context_1 = require("./Context");
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { cloneDeep, isEqual, pickBy } from 'lodash';
3
+ import React, { Component } from 'react';
4
+ import { Col, Row } from 'react-bootstrap';
5
+ import { connect } from 'react-redux';
6
+ import { v4 as uuidv4 } from 'uuid';
7
+ import { AlertDialog } from '../../components/AlertDialog';
8
+ import { Loading } from '../../components/Loading';
9
+ import { UserRolesAdd } from '../../components/UserRoles/Add';
10
+ import { UserRolesTable } from '../../components/UserRoles/Table';
11
+ import { getEndpointMappings } from '../../constants';
12
+ import { BASE_ROLE } from '../../constants/baseRole';
13
+ import { MODEL_STATUS } from '../../constants/modelStatus';
14
+ import { dispatchAction, dispatchModelFetchRequest } from '../../redux/actionCreator';
15
+ import { MODEL_FETCH_REQUEST_ACTION_TYPE, MODEL_FETCH_RESULT_ACTION_TYPE } from '../../redux/actions';
16
+ import { noStoreHooks } from '../../redux/sagas/noStoreSaga';
17
+ import { canPerformActivityGlobally, canPerformActivityOnEntity, defaultOptions } from '../../utils/baseActivity';
18
+ import { singularArticleForBaseRole, textForBaseRole } from '../../utils/baseRole';
19
+ import { getDomainIdentifierTypePluralString } from '../../utils/domainIdentifier';
20
+ import { getRootModelName } from '../../utils/entityUserRole';
21
+ import { isFetchErrorData, prepareFetch } from '../../utils/fetch';
22
+ import { sortByNames } from '../../utils/sort';
23
+ import { displayName } from '../../utils/user';
24
+ import { convertToUserWithRoles, getUserId } from '../../utils/userRole';
25
+ import { AlertWithIcon } from '../AlertWithIcon';
26
+ import { UserRolesContext } from './Context';
27
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
30
28
  /**
31
29
  * Component used to manage either UserRoles (global roles) or EntityUserRoles.
32
30
  */
33
- class UserRoles extends react_1.Component {
34
- constructor() {
35
- super(...arguments);
36
- this.state = {
37
- sortedUsers: [],
38
- // add
39
- addUsersHookId: (0, uuid_1.v4)(),
40
- isAdding: false,
41
- isUpdating: false,
42
- isRemoving: false,
43
- shouldResetAddForm: false,
44
- shouldShowRemoveDialog: false
45
- };
46
- this.setStateFromProps = (props) => {
47
- const { modelArray: userRoles, filterUsers } = props;
48
- const usersWithRoles = Object.values(userRoles.reduce((result, userRole) => {
49
- const userId = (0, userRole_1.getUserId)(userRole);
50
- let userWithRoles = result[userId];
51
- if (!userWithRoles) {
52
- userWithRoles = (0, userRole_1.convertToUserWithRoles)(userRole);
53
- }
54
- else {
55
- userWithRoles.roles.push(userRole);
56
- }
57
- result[userId] = userWithRoles;
58
- return result;
59
- }, {}));
60
- const filteredUsers = filterUsers ? filterUsers(usersWithRoles) : usersWithRoles;
61
- const sortedUsers = filteredUsers.sort(sort_1.sortByNames);
62
- this.setState({
63
- sortedUsers
64
- });
65
- };
66
- this.textForRole = (role, lowercase = false) => {
67
- if (lowercase && this.props.lowercaseTextForRole) {
68
- return this.props.lowercaseTextForRole(role);
69
- }
70
- const roleString = this.props.textForRole ? this.props.textForRole(role) : (0, baseRole_2.textForBaseRole)(role);
71
- return lowercase ? roleString.toLowerCase() : roleString;
72
- };
73
- this.singularArticleForRole = (role) => {
74
- return this.props.singularArticleForRole
75
- ? this.props.singularArticleForRole(role)
76
- : (0, baseRole_2.singularArticleForBaseRole)(role);
77
- };
78
- //#region Add Users
79
- this.addUserRoles = (identifiers, role) => {
80
- const { entity } = this.props;
81
- this.setState({
82
- identifiersToAdd: identifiers,
83
- roleForAdd: role,
84
- successMessage: undefined,
85
- failMessage: undefined,
86
- existingMessage: undefined,
87
- blockedMessage: undefined,
88
- shouldResetAddForm: false,
89
- isAdding: true
90
- });
91
- const { addUsersHookId } = this.state;
92
- noStoreSaga_1.noStoreHooks.registerNoStoreActionHook(addUsersHookId, (data) => {
93
- noStoreSaga_1.noStoreHooks.unregisterNoStoreActionHook(addUsersHookId);
94
- this.didAdd(data);
95
- });
96
- const rootModelName = (0, entityUserRole_1.getRootModelName)(this.props);
97
- (0, actionCreator_1.dispatchModelFetchRequest)({
98
- modelName: `${rootModelName ? `${rootModelName}.` : ''}addUserRoles`,
99
- pathParams: entity ? [entity.id] : undefined,
100
- body: {
101
- entityId: entity ? entity.id : undefined,
102
- identifiers: identifiers,
103
- roleName: role
104
- },
105
- noStore: true,
106
- guid: addUsersHookId
107
- });
108
- };
109
- this.didAdd = (data) => {
110
- const { entityName, onAdd, model, modelName, pathParams } = this.props;
111
- const { roleForAdd, identifiersToAdd } = this.state;
112
- if (!roleForAdd || !identifiersToAdd || identifiersToAdd.length === 0) {
113
- throw new Error('didAdd was called in the incorrect state');
114
- }
115
- if (!data || (0, fetch_1.isFetchErrorData)(data)) {
116
- const failMessage = `The following identifiers were not added${entityName ? ` to your ${entityName}` : ''}:\r\n${identifiersToAdd.join('\r\n')}`;
117
- this.setState({
118
- shouldResetAddForm: true,
119
- isAdding: false,
120
- identifiersToAdd: undefined,
121
- roleForAdd: undefined,
122
- failMessage
123
- });
124
- return;
125
- }
126
- const { addedUserRoles, existingUserRoles, blockedUserRoles, invalidIdentifiers, allowedDomains, invalidDomainIdentifiers } = data;
127
- const roleString = this.textForRole(roleForAdd, true);
128
- const singularArticleString = this.singularArticleForRole(roleForAdd);
129
- const addedNames = addedUserRoles.length > 0
130
- ? addedUserRoles
131
- .map((au) => {
132
- return `${(0, user_1.displayName)(au)}${au.uid ? ` (${au.uid})` : ''}`;
133
- })
134
- .join('\r\n')
135
- : undefined;
136
- const successMessage = addedNames
137
- ? `The following ${roleString}${addedUserRoles.length > 1 ? 's were' : ' was'} successfully added${entityName ? ` to your ${entityName}` : ''}:\r\n${addedNames}`
138
- : undefined;
139
- const existingNames = existingUserRoles.length > 0
140
- ? existingUserRoles.map((eu) => `${(0, user_1.displayName)(eu)}${eu.uid ? ` (${eu.uid})` : ''}`).join('\r\n')
141
- : undefined;
142
- const hasMultipleExisting = existingUserRoles.length > 1;
143
- const existingMessage = existingNames
144
- ? `The following ${hasMultipleExisting ? 'people were' : 'person was'} already ${entityName
145
- ? `in your ${entityName} as ${hasMultipleExisting ? '' : `${singularArticleString} `}`
146
- : hasMultipleExisting
147
- ? ''
148
- : `${singularArticleString} `}${roleString}${hasMultipleExisting ? 's' : ''}:\r\n${existingNames}`
149
- : undefined;
150
- const blockedNames = !!blockedUserRoles && blockedUserRoles.length > 0
151
- ? blockedUserRoles.map((eu) => `${(0, user_1.displayName)(eu)}${eu.uid ? ` (${eu.uid})` : ''}`).join('\r\n')
152
- : undefined;
153
- const hasMultipleBlocked = !!blockedUserRoles && blockedUserRoles.length > 1;
154
- const blockedMessage = blockedNames
155
- ? `The following ${hasMultipleBlocked ? 'people' : 'person'} could not be added ${entityName ? `to your ${entityName}` : ''} as ${hasMultipleBlocked ? '' : `${singularArticleString} `}${roleString}${hasMultipleBlocked ? 's' : ''} because they already have a role:\r\n${blockedNames}`
156
- : undefined;
157
- let failMessage = invalidIdentifiers.length > 0
158
- ? `The following ${(0, domainIdentifier_1.getDomainIdentifierTypePluralString)()} are invalid:\r\n${invalidIdentifiers.join('\r\n')}`
159
- : undefined;
160
- if (invalidDomainIdentifiers.length > 0) {
161
- failMessage = `${failMessage ? `${failMessage}\r\n` : ''}The following ${(0, domainIdentifier_1.getDomainIdentifierTypePluralString)()} do not match the allowed domains of ${allowedDomains.replace(',', ', ')}:\r\n${invalidDomainIdentifiers.join('\r\n')}`;
162
- }
163
- this.setState({
164
- shouldResetAddForm: true,
165
- isAdding: false,
166
- identifiersToAdd: undefined,
167
- roleForAdd: undefined,
168
- successMessage,
169
- existingMessage,
170
- blockedMessage,
171
- failMessage
172
- });
173
- // only reload if we had some successful adds
174
- if (addedNames) {
175
- // update redux with added userRoles
176
- const updatedModel = (0, lodash_1.cloneDeep)(model);
177
- addedUserRoles.forEach(userRole => (updatedModel[userRole.id] = (0, lodash_1.cloneDeep)(userRole)));
178
- // create a dummy action and call `prepareFetch` to get the final `modelPath`
179
- const { modelPath } = (0, fetch_1.prepareFetch)({
180
- type: actions_1.MODEL_FETCH_REQUEST_ACTION_TYPE.FETCH_REQUEST,
181
- modelName,
182
- pathParams
183
- }, (0, constants_1.getEndpointMappings)());
184
- (0, actionCreator_1.dispatchAction)({
185
- type: actions_1.MODEL_FETCH_RESULT_ACTION_TYPE.FETCH_RESULT_RECEIVED,
186
- modelPath,
187
- data: updatedModel
188
- });
189
- if (onAdd) {
190
- onAdd(addedUserRoles);
191
- }
192
- }
193
- };
194
- //#endregion Add Users
195
- //#region Update
196
- this.updateUserRole = (userRoleToUpdate, newRole) => {
197
- this.setState({
198
- isUpdating: true,
199
- userRoleToUpdate,
200
- roleForUpdate: newRole,
201
- successMessage: undefined,
202
- failMessage: undefined
203
- });
204
- this.props.update({
205
- id: userRoleToUpdate.id,
206
- body: {},
207
- queryParams: {
208
- roleName: newRole
209
- }
210
- });
211
- };
212
- this.didUpdate = (isSuccess) => {
213
- const { entityName, onUpdate } = this.props;
214
- const { userRoleToUpdate, roleForUpdate } = this.state;
215
- if (userRoleToUpdate === undefined) {
216
- throw new Error('`didUpdate` was called without setting `userRoleToUpdate` in state');
217
- }
218
- if (roleForUpdate === undefined) {
219
- throw new Error('`didUpdate` was called without setting `roleForUpdate` in state');
220
- }
221
- const name = (0, user_1.displayName)(userRoleToUpdate);
222
- const roleString = this.textForRole(roleForUpdate, true);
223
- const singularArticleString = this.singularArticleForRole(roleForUpdate);
224
- if (!isSuccess) {
225
- const failMessage = `Oops! There was an error updating ${name} to ${singularArticleString} ${roleString}${entityName ? ` in your ${entityName}` : ''}. Please try again.`;
226
- this.setState({
227
- isUpdating: false,
228
- userRoleToUpdate: undefined,
229
- roleForUpdate: undefined,
230
- failMessage
231
- });
232
- return;
233
- }
234
- const successMessage = `${name} was successfully updated to ${singularArticleString} ${roleString}${entityName ? ` in your ${entityName}` : ''}.`;
235
- if (onUpdate) {
236
- onUpdate(userRoleToUpdate, roleForUpdate);
237
- }
238
- this.setState({
239
- isUpdating: false,
240
- userRoleToUpdate: undefined,
241
- roleForUpdate: undefined,
242
- successMessage
243
- });
244
- };
245
- //#endregion Update
246
- //#region Remove User
247
- this.alertRemoveUserRole = (userRoleToRemove) => {
248
- this.setState({
249
- userRoleToRemove,
250
- shouldShowRemoveDialog: true
251
- });
252
- };
253
- this.removeUserRoleTitle = (roleForRemove) => {
254
- return `Remove ${this.textForRole(roleForRemove)}`;
255
- };
256
- this.renderRemoveUserRoleDescription = (userRoleToRemove, warning) => {
257
- const { entity, externalProviders } = this.props;
258
- const group = entity && 'externalGroups' in entity ? entity : undefined;
259
- const roleString = this.textForRole(userRoleToRemove.role, true);
260
- const singularArticleString = this.singularArticleForRole(userRoleToRemove.role);
261
- const defaultWarning = warning !== null && warning !== void 0 ? warning : ((0, jsx_runtime_1.jsxs)("p", { className: "ma0", children: ["Are you sure you want to ", (0, jsx_runtime_1.jsxs)("strong", { children: ["remove ", (0, user_1.displayName)(userRoleToRemove)] }), " as", ' ', singularArticleString, " ", roleString, "?"] }));
262
- const externalGroupsToRemove = group === null || group === void 0 ? void 0 : group.externalGroups.filter(eg => eg.userId === userRoleToRemove.id);
263
- if (!externalGroupsToRemove ||
264
- externalGroupsToRemove.length === 0 ||
265
- userRoleToRemove.role !== baseRole_1.BASE_ROLE.GROUP_OWNER) {
266
- return defaultWarning;
267
- }
268
- const externalGroupsToRemoveWithRosterSync = externalGroupsToRemove.filter(eg => { var _a; return (_a = externalProviders === null || externalProviders === void 0 ? void 0 : externalProviders[eg.externalProviderId]) === null || _a === void 0 ? void 0 : _a.rosterSyncEnabled; });
269
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["The following course sections will be ", (0, jsx_runtime_1.jsx)("strong", { children: "disconnected" }), ".", ' ', externalGroupsToRemoveWithRosterSync.length > 0 && ((0, jsx_runtime_1.jsxs)("span", { children: ["Any automatically added students will be ", (0, jsx_runtime_1.jsx)("strong", { children: "removed" }), "."] }))] }), (0, jsx_runtime_1.jsx)("ul", { children: externalGroupsToRemove.map(eg => ((0, jsx_runtime_1.jsx)("li", { children: eg.description }, eg.id))) }), defaultWarning] }));
270
- };
271
- this.removeUserRole = (shouldRemove) => {
272
- const { userRoleToRemove } = this.state;
273
- if (userRoleToRemove === undefined) {
274
- throw new Error('`removeUser` was called without setting `userRoleToRemove` in state');
275
- }
276
- this.setState({
277
- isRemoving: shouldRemove,
278
- shouldShowRemoveDialog: false,
279
- successMessage: undefined,
280
- failMessage: undefined,
281
- // clear if cancelled
282
- userRoleToRemove: shouldRemove ? userRoleToRemove : undefined
283
- });
284
- if (!shouldRemove) {
285
- return;
286
- }
287
- this.props.delete({
288
- id: userRoleToRemove.id
289
- });
290
- };
291
- this.didRemove = (isSuccess) => {
292
- const { entityName, onRemove } = this.props;
293
- const { userRoleToRemove } = this.state;
294
- if (userRoleToRemove === undefined) {
295
- throw new Error('`didRemove` was called without setting `userRoleToRemove` in state');
296
- }
297
- const name = (0, user_1.displayName)(userRoleToRemove);
298
- if (!isSuccess) {
299
- const failMessage = `Oops! There was an error removing ${name}${entityName ? ` from your ${entityName}` : ''}. Please try again.`;
300
- this.setState({
301
- isRemoving: false,
302
- userRoleToRemove: undefined,
303
- failMessage
304
- });
305
- return;
306
- }
307
- const successMessage = `${name} was successfully removed${entityName ? ` from your ${entityName}` : ''}.`;
308
- if (onRemove) {
309
- onRemove(userRoleToRemove);
310
- }
311
- this.setState({
312
- isRemoving: false,
313
- userRoleToRemove: undefined,
314
- successMessage
315
- });
316
- };
317
- }
318
- componentDidMount() {
319
- this.setStateFromProps(this.props);
320
- const { addUsersHookId } = this.state;
321
- noStoreSaga_1.noStoreHooks.unregisterNoStoreActionHook(addUsersHookId);
322
- }
323
- componentDidUpdate(prevProps) {
324
- const { modelArray: prevModelArray, modelStatus: prevModelStatus } = prevProps;
325
- const { modelArray, modelStatus, entityName } = this.props;
326
- if (!(0, lodash_1.isEqual)(prevModelArray, modelArray)) {
327
- this.setStateFromProps(this.props);
328
- }
329
- // loading error
330
- if ((prevModelStatus === modelStatus_1.MODEL_STATUS.UNINITIALIZED || prevModelStatus === modelStatus_1.MODEL_STATUS.LOADING) &&
331
- modelStatus === modelStatus_1.MODEL_STATUS.ERROR) {
332
- this.setState({
333
- failMessage: `Oops! There was an error loading${entityName ? ` the people for your ${entityName}` : ''}.\r\nPlease try again.`
334
- });
31
+ export class UserRoles extends Component {
32
+ constructor() {
33
+ var _this;
34
+ super(...arguments);
35
+ _this = this;
36
+ _defineProperty(this, "state", {
37
+ sortedUsers: [],
38
+ // add
39
+ addUsersHookId: uuidv4(),
40
+ isAdding: false,
41
+ isUpdating: false,
42
+ isRemoving: false,
43
+ shouldResetAddForm: false,
44
+ shouldShowRemoveDialog: false
45
+ });
46
+ _defineProperty(this, "setStateFromProps", props => {
47
+ const {
48
+ modelArray: userRoles,
49
+ filterUsers
50
+ } = props;
51
+ const usersWithRoles = Object.values(userRoles.reduce((result, userRole) => {
52
+ const userId = getUserId(userRole);
53
+ let userWithRoles = result[userId];
54
+ if (!userWithRoles) {
55
+ userWithRoles = convertToUserWithRoles(userRole);
56
+ } else {
57
+ userWithRoles.roles.push(userRole);
335
58
  }
336
- // updating
337
- if (prevModelStatus === modelStatus_1.MODEL_STATUS.UPDATING && modelStatus !== modelStatus_1.MODEL_STATUS.UPDATING) {
338
- this.didUpdate(modelStatus === modelStatus_1.MODEL_STATUS.READY);
59
+ result[userId] = userWithRoles;
60
+ return result;
61
+ }, {}));
62
+ const filteredUsers = filterUsers ? filterUsers(usersWithRoles) : usersWithRoles;
63
+ const sortedUsers = filteredUsers.sort(sortByNames);
64
+ this.setState({
65
+ sortedUsers
66
+ });
67
+ });
68
+ _defineProperty(this, "textForRole", function (role) {
69
+ let lowercase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
70
+ if (lowercase && _this.props.lowercaseTextForRole) {
71
+ return _this.props.lowercaseTextForRole(role);
72
+ }
73
+ const roleString = _this.props.textForRole ? _this.props.textForRole(role) : textForBaseRole(role);
74
+ return lowercase ? roleString.toLowerCase() : roleString;
75
+ });
76
+ _defineProperty(this, "singularArticleForRole", role => {
77
+ return this.props.singularArticleForRole ? this.props.singularArticleForRole(role) : singularArticleForBaseRole(role);
78
+ });
79
+ //#region Add Users
80
+ _defineProperty(this, "addUserRoles", (identifiers, role) => {
81
+ const {
82
+ entity
83
+ } = this.props;
84
+ this.setState({
85
+ identifiersToAdd: identifiers,
86
+ roleForAdd: role,
87
+ successMessage: undefined,
88
+ failMessage: undefined,
89
+ existingMessage: undefined,
90
+ blockedMessage: undefined,
91
+ shouldResetAddForm: false,
92
+ isAdding: true
93
+ });
94
+ const {
95
+ addUsersHookId
96
+ } = this.state;
97
+ noStoreHooks.registerNoStoreActionHook(addUsersHookId, data => {
98
+ noStoreHooks.unregisterNoStoreActionHook(addUsersHookId);
99
+ this.didAdd(data);
100
+ });
101
+ const rootModelName = getRootModelName(this.props);
102
+ dispatchModelFetchRequest({
103
+ modelName: `${rootModelName ? `${rootModelName}.` : ''}addUserRoles`,
104
+ pathParams: entity ? [entity.id] : undefined,
105
+ body: {
106
+ entityId: entity ? entity.id : undefined,
107
+ identifiers: identifiers,
108
+ roleName: role
109
+ },
110
+ noStore: true,
111
+ guid: addUsersHookId
112
+ });
113
+ });
114
+ _defineProperty(this, "didAdd", data => {
115
+ const {
116
+ entityName,
117
+ onAdd,
118
+ model,
119
+ modelName,
120
+ pathParams
121
+ } = this.props;
122
+ const {
123
+ roleForAdd,
124
+ identifiersToAdd
125
+ } = this.state;
126
+ if (!roleForAdd || !identifiersToAdd || identifiersToAdd.length === 0) {
127
+ throw new Error('didAdd was called in the incorrect state');
128
+ }
129
+ if (!data || isFetchErrorData(data)) {
130
+ const failMessage = `The following identifiers were not added${entityName ? ` to your ${entityName}` : ''}:\r\n${identifiersToAdd.join('\r\n')}`;
131
+ this.setState({
132
+ shouldResetAddForm: true,
133
+ isAdding: false,
134
+ identifiersToAdd: undefined,
135
+ roleForAdd: undefined,
136
+ failMessage
137
+ });
138
+ return;
139
+ }
140
+ const {
141
+ addedUserRoles,
142
+ existingUserRoles,
143
+ blockedUserRoles,
144
+ invalidIdentifiers,
145
+ allowedDomains,
146
+ invalidDomainIdentifiers
147
+ } = data;
148
+ const roleString = this.textForRole(roleForAdd, true);
149
+ const singularArticleString = this.singularArticleForRole(roleForAdd);
150
+ const addedNames = addedUserRoles.length > 0 ? addedUserRoles.map(au => {
151
+ return `${displayName(au)}${au.uid ? ` (${au.uid})` : ''}`;
152
+ }).join('\r\n') : undefined;
153
+ const successMessage = addedNames ? `The following ${roleString}${addedUserRoles.length > 1 ? 's were' : ' was'} successfully added${entityName ? ` to your ${entityName}` : ''}:\r\n${addedNames}` : undefined;
154
+ const existingNames = existingUserRoles.length > 0 ? existingUserRoles.map(eu => `${displayName(eu)}${eu.uid ? ` (${eu.uid})` : ''}`).join('\r\n') : undefined;
155
+ const hasMultipleExisting = existingUserRoles.length > 1;
156
+ const existingMessage = existingNames ? `The following ${hasMultipleExisting ? 'people were' : 'person was'} already ${entityName ? `in your ${entityName} as ${hasMultipleExisting ? '' : `${singularArticleString} `}` : hasMultipleExisting ? '' : `${singularArticleString} `}${roleString}${hasMultipleExisting ? 's' : ''}:\r\n${existingNames}` : undefined;
157
+ const blockedNames = !!blockedUserRoles && blockedUserRoles.length > 0 ? blockedUserRoles.map(eu => `${displayName(eu)}${eu.uid ? ` (${eu.uid})` : ''}`).join('\r\n') : undefined;
158
+ const hasMultipleBlocked = !!blockedUserRoles && blockedUserRoles.length > 1;
159
+ const blockedMessage = blockedNames ? `The following ${hasMultipleBlocked ? 'people' : 'person'} could not be added ${entityName ? `to your ${entityName}` : ''} as ${hasMultipleBlocked ? '' : `${singularArticleString} `}${roleString}${hasMultipleBlocked ? 's' : ''} because they already have a role:\r\n${blockedNames}` : undefined;
160
+ let failMessage = invalidIdentifiers.length > 0 ? `The following ${getDomainIdentifierTypePluralString()} are invalid:\r\n${invalidIdentifiers.join('\r\n')}` : undefined;
161
+ if (invalidDomainIdentifiers.length > 0) {
162
+ failMessage = `${failMessage ? `${failMessage}\r\n` : ''}The following ${getDomainIdentifierTypePluralString()} do not match the allowed domains of ${allowedDomains.replace(',', ', ')}:\r\n${invalidDomainIdentifiers.join('\r\n')}`;
163
+ }
164
+ this.setState({
165
+ shouldResetAddForm: true,
166
+ isAdding: false,
167
+ identifiersToAdd: undefined,
168
+ roleForAdd: undefined,
169
+ successMessage,
170
+ existingMessage,
171
+ blockedMessage,
172
+ failMessage
173
+ });
174
+
175
+ // only reload if we had some successful adds
176
+ if (addedNames) {
177
+ // update redux with added userRoles
178
+ const updatedModel = cloneDeep(model);
179
+ addedUserRoles.forEach(userRole => updatedModel[userRole.id] = cloneDeep(userRole));
180
+
181
+ // create a dummy action and call `prepareFetch` to get the final `modelPath`
182
+ const {
183
+ modelPath
184
+ } = prepareFetch({
185
+ type: MODEL_FETCH_REQUEST_ACTION_TYPE.FETCH_REQUEST,
186
+ modelName,
187
+ pathParams
188
+ }, getEndpointMappings());
189
+ dispatchAction({
190
+ type: MODEL_FETCH_RESULT_ACTION_TYPE.FETCH_RESULT_RECEIVED,
191
+ modelPath,
192
+ data: updatedModel
193
+ });
194
+ if (onAdd) {
195
+ onAdd(addedUserRoles);
339
196
  }
340
- // removing
341
- if (prevModelStatus === modelStatus_1.MODEL_STATUS.DELETING && modelStatus !== modelStatus_1.MODEL_STATUS.DELETING) {
342
- this.didRemove(modelStatus === modelStatus_1.MODEL_STATUS.READY);
197
+ }
198
+ });
199
+ //#endregion Add Users
200
+ //#region Update
201
+ _defineProperty(this, "updateUserRole", (userRoleToUpdate, newRole) => {
202
+ this.setState({
203
+ isUpdating: true,
204
+ userRoleToUpdate,
205
+ roleForUpdate: newRole,
206
+ successMessage: undefined,
207
+ failMessage: undefined
208
+ });
209
+ this.props.update({
210
+ id: userRoleToUpdate.id,
211
+ body: {},
212
+ queryParams: {
213
+ roleName: newRole
343
214
  }
215
+ });
216
+ });
217
+ _defineProperty(this, "didUpdate", isSuccess => {
218
+ const {
219
+ entityName,
220
+ onUpdate
221
+ } = this.props;
222
+ const {
223
+ userRoleToUpdate,
224
+ roleForUpdate
225
+ } = this.state;
226
+ if (userRoleToUpdate === undefined) {
227
+ throw new Error('`didUpdate` was called without setting `userRoleToUpdate` in state');
228
+ }
229
+ if (roleForUpdate === undefined) {
230
+ throw new Error('`didUpdate` was called without setting `roleForUpdate` in state');
231
+ }
232
+ const name = displayName(userRoleToUpdate);
233
+ const roleString = this.textForRole(roleForUpdate, true);
234
+ const singularArticleString = this.singularArticleForRole(roleForUpdate);
235
+ if (!isSuccess) {
236
+ const failMessage = `Oops! There was an error updating ${name} to ${singularArticleString} ${roleString}${entityName ? ` in your ${entityName}` : ''}. Please try again.`;
237
+ this.setState({
238
+ isUpdating: false,
239
+ userRoleToUpdate: undefined,
240
+ roleForUpdate: undefined,
241
+ failMessage
242
+ });
243
+ return;
244
+ }
245
+ const successMessage = `${name} was successfully updated to ${singularArticleString} ${roleString}${entityName ? ` in your ${entityName}` : ''}.`;
246
+ if (onUpdate) {
247
+ onUpdate(userRoleToUpdate, roleForUpdate);
248
+ }
249
+ this.setState({
250
+ isUpdating: false,
251
+ userRoleToUpdate: undefined,
252
+ roleForUpdate: undefined,
253
+ successMessage
254
+ });
255
+ });
256
+ //#endregion Update
257
+ //#region Remove User
258
+ _defineProperty(this, "alertRemoveUserRole", userRoleToRemove => {
259
+ this.setState({
260
+ userRoleToRemove,
261
+ shouldShowRemoveDialog: true
262
+ });
263
+ });
264
+ _defineProperty(this, "removeUserRoleTitle", roleForRemove => {
265
+ return `Remove ${this.textForRole(roleForRemove)}`;
266
+ });
267
+ _defineProperty(this, "renderRemoveUserRoleDescription", (userRoleToRemove, warning) => {
268
+ const {
269
+ entity,
270
+ externalProviders
271
+ } = this.props;
272
+ const group = entity && 'externalGroups' in entity ? entity : undefined;
273
+ const roleString = this.textForRole(userRoleToRemove.role, true);
274
+ const singularArticleString = this.singularArticleForRole(userRoleToRemove.role);
275
+ const defaultWarning = warning ?? /*#__PURE__*/_jsxs("p", {
276
+ className: "ma0",
277
+ children: ["Are you sure you want to ", /*#__PURE__*/_jsxs("strong", {
278
+ children: ["remove ", displayName(userRoleToRemove)]
279
+ }), " as", ' ', singularArticleString, " ", roleString, "?"]
280
+ });
281
+ const externalGroupsToRemove = group?.externalGroups.filter(eg => eg.userId === userRoleToRemove.id);
282
+ if (!externalGroupsToRemove || externalGroupsToRemove.length === 0 || userRoleToRemove.role !== BASE_ROLE.GROUP_OWNER) {
283
+ return defaultWarning;
284
+ }
285
+ const externalGroupsToRemoveWithRosterSync = externalGroupsToRemove.filter(eg => externalProviders?.[eg.externalProviderId]?.rosterSyncEnabled);
286
+ return /*#__PURE__*/_jsxs("div", {
287
+ children: [/*#__PURE__*/_jsxs("p", {
288
+ children: ["The following course sections will be ", /*#__PURE__*/_jsx("strong", {
289
+ children: "disconnected"
290
+ }), ".", ' ', externalGroupsToRemoveWithRosterSync.length > 0 && /*#__PURE__*/_jsxs("span", {
291
+ children: ["Any automatically added students will be ", /*#__PURE__*/_jsx("strong", {
292
+ children: "removed"
293
+ }), "."]
294
+ })]
295
+ }), /*#__PURE__*/_jsx("ul", {
296
+ children: externalGroupsToRemove.map(eg => /*#__PURE__*/_jsx("li", {
297
+ children: eg.description
298
+ }, eg.id))
299
+ }), defaultWarning]
300
+ });
301
+ });
302
+ _defineProperty(this, "removeUserRole", shouldRemove => {
303
+ const {
304
+ userRoleToRemove
305
+ } = this.state;
306
+ if (userRoleToRemove === undefined) {
307
+ throw new Error('`removeUser` was called without setting `userRoleToRemove` in state');
308
+ }
309
+ this.setState({
310
+ isRemoving: shouldRemove,
311
+ shouldShowRemoveDialog: false,
312
+ successMessage: undefined,
313
+ failMessage: undefined,
314
+ // clear if cancelled
315
+ userRoleToRemove: shouldRemove ? userRoleToRemove : undefined
316
+ });
317
+ if (!shouldRemove) {
318
+ return;
319
+ }
320
+ this.props.delete({
321
+ id: userRoleToRemove.id
322
+ });
323
+ });
324
+ _defineProperty(this, "didRemove", isSuccess => {
325
+ const {
326
+ entityName,
327
+ onRemove
328
+ } = this.props;
329
+ const {
330
+ userRoleToRemove
331
+ } = this.state;
332
+ if (userRoleToRemove === undefined) {
333
+ throw new Error('`didRemove` was called without setting `userRoleToRemove` in state');
334
+ }
335
+ const name = displayName(userRoleToRemove);
336
+ if (!isSuccess) {
337
+ const failMessage = `Oops! There was an error removing ${name}${entityName ? ` from your ${entityName}` : ''}. Please try again.`;
338
+ this.setState({
339
+ isRemoving: false,
340
+ userRoleToRemove: undefined,
341
+ failMessage
342
+ });
343
+ return;
344
+ }
345
+ const successMessage = `${name} was successfully removed${entityName ? ` from your ${entityName}` : ''}.`;
346
+ if (onRemove) {
347
+ onRemove(userRoleToRemove);
348
+ }
349
+ this.setState({
350
+ isRemoving: false,
351
+ userRoleToRemove: undefined,
352
+ successMessage
353
+ });
354
+ });
355
+ }
356
+ componentDidMount() {
357
+ this.setStateFromProps(this.props);
358
+ const {
359
+ addUsersHookId
360
+ } = this.state;
361
+ noStoreHooks.unregisterNoStoreActionHook(addUsersHookId);
362
+ }
363
+ componentDidUpdate(prevProps) {
364
+ const {
365
+ modelArray: prevModelArray,
366
+ modelStatus: prevModelStatus
367
+ } = prevProps;
368
+ const {
369
+ modelArray,
370
+ modelStatus,
371
+ entityName
372
+ } = this.props;
373
+ if (!isEqual(prevModelArray, modelArray)) {
374
+ this.setStateFromProps(this.props);
375
+ }
376
+
377
+ // loading error
378
+ if ((prevModelStatus === MODEL_STATUS.UNINITIALIZED || prevModelStatus === MODEL_STATUS.LOADING) && modelStatus === MODEL_STATUS.ERROR) {
379
+ this.setState({
380
+ failMessage: `Oops! There was an error loading${entityName ? ` the people for your ${entityName}` : ''}.\r\nPlease try again.`
381
+ });
382
+ }
383
+
384
+ // updating
385
+ if (prevModelStatus === MODEL_STATUS.UPDATING && modelStatus !== MODEL_STATUS.UPDATING) {
386
+ this.didUpdate(modelStatus === MODEL_STATUS.READY);
344
387
  }
345
- //#endregion Remove User
346
- render() {
347
- const { modelStatus, canModify, readOnly, canDeleteSelf, allowMultipleRoles, isAddDisabled, isUpdateDisabled, isDeleteDisabled, defaultRole, requiredRole, roleDescriptions, addRoleExcludeList, entityName, renderTableDescription, renderAddDescription } = this.props;
348
- const { sortedUsers, isAdding, isUpdating, isRemoving, shouldResetAddForm, shouldShowRemoveDialog, userRoleToUpdate, userRoleToRemove, successMessage, existingMessage, blockedMessage, failMessage } = this.state;
349
- const addableRoleDescriptions = addRoleExcludeList
350
- ? (0, lodash_1.pickBy)(roleDescriptions, (_, key) => !addRoleExcludeList.includes(key))
351
- : roleDescriptions;
352
- const roles = Object.keys(roleDescriptions);
353
- const shouldRenderAsMutable = !readOnly && canModify;
354
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!!successMessage && ((0, jsx_runtime_1.jsx)(AlertWithIcon_1.AlertWithIcon, { id: "successMessageAlert", variant: "success", dismissible: true, onClose: () => this.setState({
355
- successMessage: undefined
356
- }), children: (0, jsx_runtime_1.jsx)("p", { className: "pre-wrap", children: successMessage }) })), !!existingMessage && ((0, jsx_runtime_1.jsx)(AlertWithIcon_1.AlertWithIcon, { id: "existingMessageAlert", variant: "info", dismissible: true, onClose: () => this.setState({
357
- existingMessage: undefined
358
- }), children: (0, jsx_runtime_1.jsx)("p", { className: "pre-wrap", children: existingMessage }) })), !!blockedMessage && ((0, jsx_runtime_1.jsx)(AlertWithIcon_1.AlertWithIcon, { id: "blockedMessageAlert", variant: "warning", dismissible: true, onClose: () => this.setState({
359
- blockedMessage: undefined
360
- }), children: (0, jsx_runtime_1.jsx)("p", { className: "pre-wrap", children: blockedMessage }) })), !!failMessage && ((0, jsx_runtime_1.jsx)(AlertWithIcon_1.AlertWithIcon, { id: "failMessageAlert", variant: "warning", dismissible: true, onClose: () => this.setState({
361
- failMessage: undefined
362
- }), children: (0, jsx_runtime_1.jsx)("p", { className: "pre-wrap", children: failMessage }) })), shouldRenderAsMutable && ((0, jsx_runtime_1.jsx)(Add_1.UserRolesAdd, { id: "entityUserRolesAdd", disabled: isAddDisabled, entityName: entityName, defaultRole: defaultRole, roleDescriptions: addableRoleDescriptions, renderAddDescription: renderAddDescription, textForRole: this.textForRole, isAddingUsersToRole: isAdding, shouldReset: shouldResetAddForm, addUserRoles: this.addUserRoles })), !!renderTableDescription && renderTableDescription(shouldRenderAsMutable), (0, jsx_runtime_1.jsx)(react_bootstrap_1.Row, { className: "mt3", children: (0, jsx_runtime_1.jsx)(react_bootstrap_1.Col, { xs: 12, children: modelStatus === modelStatus_1.MODEL_STATUS.LOADING ? ((0, jsx_runtime_1.jsx)(Loading_1.Loading, {})) : sortedUsers.length > 0 ? ((0, jsx_runtime_1.jsx)(Context_1.UserRolesContext.Provider, { value: {
363
- isUpdateDisabled: isUpdateDisabled || readOnly,
364
- isDeleteDisabled: isDeleteDisabled || readOnly,
365
- canModify: shouldRenderAsMutable,
366
- canDeleteSelf,
367
- allowMultipleRoles,
368
- roles,
369
- requiredRole,
370
- textForRole: this.textForRole,
371
- userRoleToUpdate,
372
- isUpdating,
373
- updateUserRole: this.updateUserRole,
374
- userRoleToRemove,
375
- isRemoving,
376
- removeUserRole: this.alertRemoveUserRole
377
- }, children: (0, jsx_runtime_1.jsx)(Table_1.UserRolesTable, { id: "entityUserRolesTable", users: sortedUsers }) })) : null }) }), !!userRoleToRemove && ((0, jsx_runtime_1.jsx)(AlertDialog_1.AlertDialog, { id: "removeUserAlert", isOpen: shouldShowRemoveDialog, title: this.removeUserRoleTitle(userRoleToRemove.role), description: this.renderRemoveUserRoleDescription(userRoleToRemove), onDestroy: () => this.removeUserRole(true), destroyText: "Yes, remove the user", onCancel: () => this.removeUserRole(false), cancelText: "No, I changed my mind" }))] }));
388
+
389
+ // removing
390
+ if (prevModelStatus === MODEL_STATUS.DELETING && modelStatus !== MODEL_STATUS.DELETING) {
391
+ this.didRemove(modelStatus === MODEL_STATUS.READY);
378
392
  }
393
+ }
394
+ //#endregion Remove User
395
+
396
+ render() {
397
+ const {
398
+ modelStatus,
399
+ canModify,
400
+ readOnly,
401
+ canDeleteSelf,
402
+ allowMultipleRoles,
403
+ isAddDisabled,
404
+ isUpdateDisabled,
405
+ isDeleteDisabled,
406
+ defaultRole,
407
+ requiredRole,
408
+ roleDescriptions,
409
+ addRoleExcludeList,
410
+ entityName,
411
+ renderTableDescription,
412
+ renderAddDescription
413
+ } = this.props;
414
+ const {
415
+ sortedUsers,
416
+ isAdding,
417
+ isUpdating,
418
+ isRemoving,
419
+ shouldResetAddForm,
420
+ shouldShowRemoveDialog,
421
+ userRoleToUpdate,
422
+ userRoleToRemove,
423
+ successMessage,
424
+ existingMessage,
425
+ blockedMessage,
426
+ failMessage
427
+ } = this.state;
428
+ const addableRoleDescriptions = addRoleExcludeList ? pickBy(roleDescriptions, (_, key) => !addRoleExcludeList.includes(key)) : roleDescriptions;
429
+ const roles = Object.keys(roleDescriptions);
430
+ const shouldRenderAsMutable = !readOnly && canModify;
431
+ return /*#__PURE__*/_jsxs(_Fragment, {
432
+ children: [!!successMessage && /*#__PURE__*/_jsx(AlertWithIcon, {
433
+ id: "successMessageAlert",
434
+ variant: "success",
435
+ dismissible: true,
436
+ onClose: () => this.setState({
437
+ successMessage: undefined
438
+ }),
439
+ children: /*#__PURE__*/_jsx("p", {
440
+ className: "pre-wrap",
441
+ children: successMessage
442
+ })
443
+ }), !!existingMessage && /*#__PURE__*/_jsx(AlertWithIcon, {
444
+ id: "existingMessageAlert",
445
+ variant: "info",
446
+ dismissible: true,
447
+ onClose: () => this.setState({
448
+ existingMessage: undefined
449
+ }),
450
+ children: /*#__PURE__*/_jsx("p", {
451
+ className: "pre-wrap",
452
+ children: existingMessage
453
+ })
454
+ }), !!blockedMessage && /*#__PURE__*/_jsx(AlertWithIcon, {
455
+ id: "blockedMessageAlert",
456
+ variant: "warning",
457
+ dismissible: true,
458
+ onClose: () => this.setState({
459
+ blockedMessage: undefined
460
+ }),
461
+ children: /*#__PURE__*/_jsx("p", {
462
+ className: "pre-wrap",
463
+ children: blockedMessage
464
+ })
465
+ }), !!failMessage && /*#__PURE__*/_jsx(AlertWithIcon, {
466
+ id: "failMessageAlert",
467
+ variant: "warning",
468
+ dismissible: true,
469
+ onClose: () => this.setState({
470
+ failMessage: undefined
471
+ }),
472
+ children: /*#__PURE__*/_jsx("p", {
473
+ className: "pre-wrap",
474
+ children: failMessage
475
+ })
476
+ }), shouldRenderAsMutable && /*#__PURE__*/_jsx(UserRolesAdd, {
477
+ id: "entityUserRolesAdd",
478
+ disabled: isAddDisabled,
479
+ entityName: entityName,
480
+ defaultRole: defaultRole,
481
+ roleDescriptions: addableRoleDescriptions,
482
+ renderAddDescription: renderAddDescription,
483
+ textForRole: this.textForRole,
484
+ isAddingUsersToRole: isAdding,
485
+ shouldReset: shouldResetAddForm,
486
+ addUserRoles: this.addUserRoles
487
+ }), !!renderTableDescription && renderTableDescription(shouldRenderAsMutable), /*#__PURE__*/_jsx(Row, {
488
+ className: "mt3",
489
+ children: /*#__PURE__*/_jsx(Col, {
490
+ xs: 12,
491
+ children: modelStatus === MODEL_STATUS.LOADING ? /*#__PURE__*/_jsx(Loading, {}) : sortedUsers.length > 0 ? /*#__PURE__*/_jsx(UserRolesContext.Provider, {
492
+ value: {
493
+ isUpdateDisabled: isUpdateDisabled || readOnly,
494
+ isDeleteDisabled: isDeleteDisabled || readOnly,
495
+ canModify: shouldRenderAsMutable,
496
+ canDeleteSelf,
497
+ allowMultipleRoles,
498
+ roles,
499
+ requiredRole,
500
+ textForRole: this.textForRole,
501
+ userRoleToUpdate,
502
+ isUpdating,
503
+ updateUserRole: this.updateUserRole,
504
+ userRoleToRemove,
505
+ isRemoving,
506
+ removeUserRole: this.alertRemoveUserRole
507
+ },
508
+ children: /*#__PURE__*/_jsx(UserRolesTable, {
509
+ id: "entityUserRolesTable",
510
+ users: sortedUsers
511
+ })
512
+ }) : null
513
+ })
514
+ }), !!userRoleToRemove && /*#__PURE__*/_jsx(AlertDialog, {
515
+ id: "removeUserAlert",
516
+ isOpen: shouldShowRemoveDialog,
517
+ title: this.removeUserRoleTitle(userRoleToRemove.role),
518
+ description: this.renderRemoveUserRoleDescription(userRoleToRemove),
519
+ onDestroy: () => this.removeUserRole(true),
520
+ destroyText: "Yes, remove the user",
521
+ onCancel: () => this.removeUserRole(false),
522
+ cancelText: "No, I changed my mind"
523
+ })]
524
+ });
525
+ }
379
526
  }
380
- exports.UserRoles = UserRoles;
381
- const mapStateToProps = (state, ownProps) => {
382
- const canModifyGlobally = (0, baseActivity_1.canPerformActivityGlobally)(ownProps.modifyUserRoleActivityName, (0, baseActivity_1.defaultOptions)(state));
383
- const canModify = canModifyGlobally ||
384
- (ownProps.entity
385
- ? (0, baseActivity_1.canPerformActivityOnEntity)(ownProps.modifyUserRoleActivityName, (0, baseActivity_1.defaultOptions)(state, ownProps, 'entity'))
386
- : false);
387
- return {
388
- canModify,
389
- canDeleteSelf: canModify ||
390
- (ownProps.entity && ownProps.deleteOwnUserRoleActivityName
391
- ? (0, baseActivity_1.canPerformActivityOnEntity)(ownProps.deleteOwnUserRoleActivityName, (0, baseActivity_1.defaultOptions)(state, ownProps, 'entity'))
392
- : false)
393
- };
527
+ export const mapStateToProps = (state, ownProps) => {
528
+ const canModifyGlobally = canPerformActivityGlobally(ownProps.modifyUserRoleActivityName, defaultOptions(state));
529
+ const canModify = canModifyGlobally || (ownProps.entity ? canPerformActivityOnEntity(ownProps.modifyUserRoleActivityName, defaultOptions(state, ownProps, 'entity')) : false);
530
+ return {
531
+ canModify,
532
+ canDeleteSelf: canModify || (ownProps.entity && ownProps.deleteOwnUserRoleActivityName ? canPerformActivityOnEntity(ownProps.deleteOwnUserRoleActivityName, defaultOptions(state, ownProps, 'entity')) : false)
533
+ };
394
534
  };
395
- exports.mapStateToProps = mapStateToProps;
396
- exports.default = (0, react_redux_1.connect)(exports.mapStateToProps)(UserRoles);
535
+ export default connect(mapStateToProps)(UserRoles);
536
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjbG9uZURlZXAiLCJpc0VxdWFsIiwicGlja0J5IiwiUmVhY3QiLCJDb21wb25lbnQiLCJDb2wiLCJSb3ciLCJjb25uZWN0IiwidjQiLCJ1dWlkdjQiLCJBbGVydERpYWxvZyIsIkxvYWRpbmciLCJVc2VyUm9sZXNBZGQiLCJVc2VyUm9sZXNUYWJsZSIsImdldEVuZHBvaW50TWFwcGluZ3MiLCJCQVNFX1JPTEUiLCJNT0RFTF9TVEFUVVMiLCJkaXNwYXRjaEFjdGlvbiIsImRpc3BhdGNoTW9kZWxGZXRjaFJlcXVlc3QiLCJNT0RFTF9GRVRDSF9SRVFVRVNUX0FDVElPTl9UWVBFIiwiTU9ERUxfRkVUQ0hfUkVTVUxUX0FDVElPTl9UWVBFIiwibm9TdG9yZUhvb2tzIiwiY2FuUGVyZm9ybUFjdGl2aXR5R2xvYmFsbHkiLCJjYW5QZXJmb3JtQWN0aXZpdHlPbkVudGl0eSIsImRlZmF1bHRPcHRpb25zIiwic2luZ3VsYXJBcnRpY2xlRm9yQmFzZVJvbGUiLCJ0ZXh0Rm9yQmFzZVJvbGUiLCJnZXREb21haW5JZGVudGlmaWVyVHlwZVBsdXJhbFN0cmluZyIsImdldFJvb3RNb2RlbE5hbWUiLCJpc0ZldGNoRXJyb3JEYXRhIiwicHJlcGFyZUZldGNoIiwic29ydEJ5TmFtZXMiLCJkaXNwbGF5TmFtZSIsImNvbnZlcnRUb1VzZXJXaXRoUm9sZXMiLCJnZXRVc2VySWQiLCJBbGVydFdpdGhJY29uIiwiVXNlclJvbGVzQ29udGV4dCIsImpzeHMiLCJfanN4cyIsImpzeCIsIl9qc3giLCJGcmFnbWVudCIsIl9GcmFnbWVudCIsIlVzZXJSb2xlcyIsImNvbnN0cnVjdG9yIiwiX3RoaXMiLCJhcmd1bWVudHMiLCJ0aGlzIiwiX2RlZmluZVByb3BlcnR5Iiwic29ydGVkVXNlcnMiLCJhZGRVc2Vyc0hvb2tJZCIsImlzQWRkaW5nIiwiaXNVcGRhdGluZyIsImlzUmVtb3ZpbmciLCJzaG91bGRSZXNldEFkZEZvcm0iLCJzaG91bGRTaG93UmVtb3ZlRGlhbG9nIiwicHJvcHMiLCJtb2RlbEFycmF5IiwidXNlclJvbGVzIiwiZmlsdGVyVXNlcnMiLCJ1c2Vyc1dpdGhSb2xlcyIsIk9iamVjdCIsInZhbHVlcyIsInJlZHVjZSIsInJlc3VsdCIsInVzZXJSb2xlIiwidXNlcklkIiwidXNlcldpdGhSb2xlcyIsInJvbGVzIiwicHVzaCIsImZpbHRlcmVkVXNlcnMiLCJzb3J0Iiwic2V0U3RhdGUiLCJyb2xlIiwibG93ZXJjYXNlIiwibGVuZ3RoIiwidW5kZWZpbmVkIiwibG93ZXJjYXNlVGV4dEZvclJvbGUiLCJyb2xlU3RyaW5nIiwidGV4dEZvclJvbGUiLCJ0b0xvd2VyQ2FzZSIsInNpbmd1bGFyQXJ0aWNsZUZvclJvbGUiLCJpZGVudGlmaWVycyIsImVudGl0eSIsImlkZW50aWZpZXJzVG9BZGQiLCJyb2xlRm9yQWRkIiwic3VjY2Vzc01lc3NhZ2UiLCJmYWlsTWVzc2FnZSIsImV4aXN0aW5nTWVzc2FnZSIsImJsb2NrZWRNZXNzYWdlIiwic3RhdGUiLCJyZWdpc3Rlck5vU3RvcmVBY3Rpb25Ib29rIiwiZGF0YSIsInVucmVnaXN0ZXJOb1N0b3JlQWN0aW9uSG9vayIsImRpZEFkZCIsInJvb3RNb2RlbE5hbWUiLCJtb2RlbE5hbWUiLCJwYXRoUGFyYW1zIiwiaWQiLCJib2R5IiwiZW50aXR5SWQiLCJyb2xlTmFtZSIsIm5vU3RvcmUiLCJndWlkIiwiZW50aXR5TmFtZSIsIm9uQWRkIiwibW9kZWwiLCJFcnJvciIsImpvaW4iLCJhZGRlZFVzZXJSb2xlcyIsImV4aXN0aW5nVXNlclJvbGVzIiwiYmxvY2tlZFVzZXJSb2xlcyIsImludmFsaWRJZGVudGlmaWVycyIsImFsbG93ZWREb21haW5zIiwiaW52YWxpZERvbWFpbklkZW50aWZpZXJzIiwic2luZ3VsYXJBcnRpY2xlU3RyaW5nIiwiYWRkZWROYW1lcyIsIm1hcCIsImF1IiwidWlkIiwiZXhpc3RpbmdOYW1lcyIsImV1IiwiaGFzTXVsdGlwbGVFeGlzdGluZyIsImJsb2NrZWROYW1lcyIsImhhc011bHRpcGxlQmxvY2tlZCIsInJlcGxhY2UiLCJ1cGRhdGVkTW9kZWwiLCJmb3JFYWNoIiwibW9kZWxQYXRoIiwidHlwZSIsIkZFVENIX1JFUVVFU1QiLCJGRVRDSF9SRVNVTFRfUkVDRUlWRUQiLCJ1c2VyUm9sZVRvVXBkYXRlIiwibmV3Um9sZSIsInJvbGVGb3JVcGRhdGUiLCJ1cGRhdGUiLCJxdWVyeVBhcmFtcyIsImlzU3VjY2VzcyIsIm9uVXBkYXRlIiwibmFtZSIsInVzZXJSb2xlVG9SZW1vdmUiLCJyb2xlRm9yUmVtb3ZlIiwid2FybmluZyIsImV4dGVybmFsUHJvdmlkZXJzIiwiZ3JvdXAiLCJkZWZhdWx0V2FybmluZyIsImNsYXNzTmFtZSIsImNoaWxkcmVuIiwiZXh0ZXJuYWxHcm91cHNUb1JlbW92ZSIsImV4dGVybmFsR3JvdXBzIiwiZmlsdGVyIiwiZWciLCJHUk9VUF9PV05FUiIsImV4dGVybmFsR3JvdXBzVG9SZW1vdmVXaXRoUm9zdGVyU3luYyIsImV4dGVybmFsUHJvdmlkZXJJZCIsInJvc3RlclN5bmNFbmFibGVkIiwiZGVzY3JpcHRpb24iLCJzaG91bGRSZW1vdmUiLCJkZWxldGUiLCJvblJlbW92ZSIsImNvbXBvbmVudERpZE1vdW50Iiwic2V0U3RhdGVGcm9tUHJvcHMiLCJjb21wb25lbnREaWRVcGRhdGUiLCJwcmV2UHJvcHMiLCJwcmV2TW9kZWxBcnJheSIsIm1vZGVsU3RhdHVzIiwicHJldk1vZGVsU3RhdHVzIiwiVU5JTklUSUFMSVpFRCIsIkxPQURJTkciLCJFUlJPUiIsIlVQREFUSU5HIiwiZGlkVXBkYXRlIiwiUkVBRFkiLCJERUxFVElORyIsImRpZFJlbW92ZSIsInJlbmRlciIsImNhbk1vZGlmeSIsInJlYWRPbmx5IiwiY2FuRGVsZXRlU2VsZiIsImFsbG93TXVsdGlwbGVSb2xlcyIsImlzQWRkRGlzYWJsZWQiLCJpc1VwZGF0ZURpc2FibGVkIiwiaXNEZWxldGVEaXNhYmxlZCIsImRlZmF1bHRSb2xlIiwicmVxdWlyZWRSb2xlIiwicm9sZURlc2NyaXB0aW9ucyIsImFkZFJvbGVFeGNsdWRlTGlzdCIsInJlbmRlclRhYmxlRGVzY3JpcHRpb24iLCJyZW5kZXJBZGREZXNjcmlwdGlvbiIsImFkZGFibGVSb2xlRGVzY3JpcHRpb25zIiwiXyIsImtleSIsImluY2x1ZGVzIiwia2V5cyIsInNob3VsZFJlbmRlckFzTXV0YWJsZSIsInZhcmlhbnQiLCJkaXNtaXNzaWJsZSIsIm9uQ2xvc2UiLCJkaXNhYmxlZCIsImlzQWRkaW5nVXNlcnNUb1JvbGUiLCJzaG91bGRSZXNldCIsImFkZFVzZXJSb2xlcyIsInhzIiwiUHJvdmlkZXIiLCJ2YWx1ZSIsInVwZGF0ZVVzZXJSb2xlIiwicmVtb3ZlVXNlclJvbGUiLCJhbGVydFJlbW92ZVVzZXJSb2xlIiwidXNlcnMiLCJpc09wZW4iLCJ0aXRsZSIsInJlbW92ZVVzZXJSb2xlVGl0bGUiLCJyZW5kZXJSZW1vdmVVc2VyUm9sZURlc2NyaXB0aW9uIiwib25EZXN0cm95IiwiZGVzdHJveVRleHQiLCJvbkNhbmNlbCIsImNhbmNlbFRleHQiLCJtYXBTdGF0ZVRvUHJvcHMiLCJvd25Qcm9wcyIsImNhbk1vZGlmeUdsb2JhbGx5IiwibW9kaWZ5VXNlclJvbGVBY3Rpdml0eU5hbWUiLCJkZWxldGVPd25Vc2VyUm9sZUFjdGl2aXR5TmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL1VzZXJSb2xlcy9pbmRleC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2xvbmVEZWVwLCBEaWN0aW9uYXJ5LCBpc0VxdWFsLCBwaWNrQnkgfSBmcm9tICdsb2Rhc2gnXG5pbXBvcnQgUmVhY3QsIHsgQ29tcG9uZW50IH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBDb2wsIFJvdyB9IGZyb20gJ3JlYWN0LWJvb3RzdHJhcCdcbmltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCdcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnXG5pbXBvcnQgeyBBbGVydERpYWxvZyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvQWxlcnREaWFsb2cnXG5pbXBvcnQgeyBMb2FkaW5nIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9Mb2FkaW5nJ1xuaW1wb3J0IHsgVXNlclJvbGVzQWRkIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9Vc2VyUm9sZXMvQWRkJ1xuaW1wb3J0IHsgVXNlclJvbGVzVGFibGUgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL1VzZXJSb2xlcy9UYWJsZSdcbmltcG9ydCB7IGdldEVuZHBvaW50TWFwcGluZ3MgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnXG5pbXBvcnQgeyBCQVNFX1JPTEUgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvYmFzZVJvbGUnXG5pbXBvcnQgeyBNT0RFTF9TVEFUVVMgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvbW9kZWxTdGF0dXMnXG5pbXBvcnQgeyBkaXNwYXRjaEFjdGlvbiwgZGlzcGF0Y2hNb2RlbEZldGNoUmVxdWVzdCB9IGZyb20gJy4uLy4uL3JlZHV4L2FjdGlvbkNyZWF0b3InXG5pbXBvcnQge1xuXHRNT0RFTF9GRVRDSF9SRVFVRVNUX0FDVElPTl9UWVBFLFxuXHRNT0RFTF9GRVRDSF9SRVNVTFRfQUNUSU9OX1RZUEUsXG5cdE1vZGVsRmV0Y2hSZXN1bHRBY3Rpb25cbn0gZnJvbSAnLi4vLi4vcmVkdXgvYWN0aW9ucydcbmltcG9ydCB7IG5vU3RvcmVIb29rcyB9IGZyb20gJy4uLy4uL3JlZHV4L3NhZ2FzL25vU3RvcmVTYWdhJ1xuaW1wb3J0IHtcblx0QmFzZVJlZHV4U3RhdGUsXG5cdEV4dGVybmFsUHJvdmlkZXIsXG5cdEZldGNoRXJyb3JEYXRhLFxuXHRHcm91cCxcblx0TW9kZWwsXG5cdE1vZGVsQ29sbGVjdGlvbixcblx0Um9sZURlc2NyaXB0aW9ucyxcblx0VXNlcixcblx0VXNlclJvbGUsXG5cdFVzZXJXaXRoUm9sZXNcbn0gZnJvbSAnLi4vLi4vdHlwZXMnXG5pbXBvcnQgeyBjYW5QZXJmb3JtQWN0aXZpdHlHbG9iYWxseSwgY2FuUGVyZm9ybUFjdGl2aXR5T25FbnRpdHksIGRlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi4vLi4vdXRpbHMvYmFzZUFjdGl2aXR5J1xuaW1wb3J0IHsgc2luZ3VsYXJBcnRpY2xlRm9yQmFzZVJvbGUsIHRleHRGb3JCYXNlUm9sZSB9IGZyb20gJy4uLy4uL3V0aWxzL2Jhc2VSb2xlJ1xuaW1wb3J0IHsgZ2V0RG9tYWluSWRlbnRpZmllclR5cGVQbHVyYWxTdHJpbmcgfSBmcm9tICcuLi8uLi91dGlscy9kb21haW5JZGVudGlmaWVyJ1xuaW1wb3J0IHsgZ2V0Um9vdE1vZGVsTmFtZSB9IGZyb20gJy4uLy4uL3V0aWxzL2VudGl0eVVzZXJSb2xlJ1xuaW1wb3J0IHsgaXNGZXRjaEVycm9yRGF0YSwgcHJlcGFyZUZldGNoIH0gZnJvbSAnLi4vLi4vdXRpbHMvZmV0Y2gnXG5pbXBvcnQgeyBzb3J0QnlOYW1lcyB9IGZyb20gJy4uLy4uL3V0aWxzL3NvcnQnXG5pbXBvcnQgeyBkaXNwbGF5TmFtZSB9IGZyb20gJy4uLy4uL3V0aWxzL3VzZXInXG5pbXBvcnQgeyBjb252ZXJ0VG9Vc2VyV2l0aFJvbGVzLCBnZXRVc2VySWQgfSBmcm9tICcuLi8uLi91dGlscy91c2VyUm9sZSdcbmltcG9ydCB7IEFsZXJ0V2l0aEljb24gfSBmcm9tICcuLi9BbGVydFdpdGhJY29uJ1xuaW1wb3J0IHsgQ29sbGVjdGlvbkNvbXBvbmVudFdyYXBwZWRQcm9wcyB9IGZyb20gJy4uL0hPQy9Db2xsZWN0aW9uQ29tcG9uZW50J1xuaW1wb3J0IHsgVXNlclJvbGVzQ29udGV4dCB9IGZyb20gJy4vQ29udGV4dCdcblxuZXhwb3J0IGludGVyZmFjZSBVc2VyUm9sZXNSZWR1eFByb3BzIHtcblx0LyoqIElzIHRoZSBjdXJyZW50IHVzZXIgYWxsb3dlZCB0byBhZGQsIHVwZGF0ZSwgYW5kIGRlbGV0ZSB1c2VyIHJvbGVzPyAqL1xuXHRjYW5Nb2RpZnk/OiBib29sZWFuXG5cdC8qKiBJcyB0aGUgY3VycmVudCB1c2VyIGFsbG93ZWQgdG8gZGVsZXRlIHRoZWlyIG93biB1c2VyIHJvbGU/ICovXG5cdGNhbkRlbGV0ZVNlbGY/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlclJvbGVzT3duUHJvcHMgZXh0ZW5kcyBDb2xsZWN0aW9uQ29tcG9uZW50V3JhcHBlZFByb3BzPFVzZXJSb2xlPiB7XG5cdC8qKiBTaG91bGQgdGhlIGNvbXBvbmVudCBwcmV2ZW50IG1vZGlmaWNhdGlvbnMsIGluZGVwZW5kZW50IG9mIHBlcm1pc3Npb25zPyAqL1xuXHRyZWFkT25seT86IGJvb2xlYW5cblx0LyoqIElzIHRoZSBjdXJyZW50IHVzZXIgYWxsb3dlZCB0byBkZWxldGUgdGhlaXIgb3duIHVzZXIgcm9sZT8gT3ZlcnJpZGVzIHRoZSB2YWx1ZSBmcm9tIHJlZHV4LiAqL1xuXHRjYW5EZWxldGVTZWxmPzogYm9vbGVhblxuXG5cdC8qKiBJZiBtdWx0aXBsZSByb2xlcyBhbGxvd2VkLCBlYWNoIHJvbGUgaXMgZGlzcGxheWVkIHBlciB1c2VyLCBvdGhlcndpc2UgYSBzZWxlY3QgZHJvcGRvd24gaXMgZGlzcGxheWVkLiAqL1xuXHRhbGxvd011bHRpcGxlUm9sZXM/OiBib29sZWFuXG5cdC8qKiBkaXNhYmxlIGFkZGluZyBuZXcgdXNlciByb2xlcyAqL1xuXHRpc0FkZERpc2FibGVkPzogYm9vbGVhblxuXHQvKiogZGlzYWJsZSBhbGwgdXNlciByb2xlIHNlbGVjdCBkcm9wZG93bnMsIGlmIGFueSAqL1xuXHRpc1VwZGF0ZURpc2FibGVkPzogYm9vbGVhblxuXHQvKiogZGlzYWJsZSBhbGwgdXNlciByb2xlIGRlbGV0ZSBidXR0b25zICovXG5cdGlzRGVsZXRlRGlzYWJsZWQ/OiBib29sZWFuXG5cblx0LyoqIFRoZSBhY3Rpdml0eSB0aGUgY3VycmVudCB1c2VyIG11c3QgaGF2ZSBpbiBvcmRlciB0byBhZGQsIHVwZGF0ZSwgb3IgZGVsZXRlIHVzZXIgcm9sZXMuICovXG5cdG1vZGlmeVVzZXJSb2xlQWN0aXZpdHlOYW1lOiBzdHJpbmdcblx0LyoqIChPcHRpb25hbCkgVGhlIGFjdGl2aXR5IHRoZSBjdXJyZW50IHVzZXIgbXVzdCBoYXZlIGluIG9yZGVyIHRvIGRlbGV0ZSB0aGVpciBvd24gdXNlciByb2xlcywgaWYgdGhleSBjYW5ub3QgbW9kaWZ5IGFsbC4gKi9cblx0ZGVsZXRlT3duVXNlclJvbGVBY3Rpdml0eU5hbWU/OiBzdHJpbmdcblx0LyoqIFRoZSByb2xlIHRoYXQgd2lsbCBiZSBzaG93biBmaXJzdCBpbiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgcm9sZXMuICovXG5cdGRlZmF1bHRSb2xlOiBzdHJpbmdcblx0LyoqIChPcHRpb25hbCkgSWYgcHJvdmlkZWQsIHRoZSBsYXN0IHVzZXIgcm9sZSB3aXRoIHRoZSByZXF1aXJlZCByb2xlIHdpbGwgYmUgcHJldmVudGVkIGZyb20gYmVpbmcgcmVtb3ZlZC4gKi9cblx0cmVxdWlyZWRSb2xlPzogc3RyaW5nXG5cdC8qKiBBIGRpY3Rpb25hcnkgb2YgYWxsIHBvc3NpYmxlIHJvbGVzIGFuZCB0aGVpciBkZXNjcmlwdGlvbnMuICovXG5cdHJvbGVEZXNjcmlwdGlvbnM6IFJvbGVEZXNjcmlwdGlvbnNcblx0LyoqIChPcHRpb25hbCkgbGlzdCBvZiByb2xlcyB0aGF0IHNob3VsZCBiZSBleGNsdWRlZCBmcm9tIHRoZSBhZGQgb3B0aW9ucy4gKi9cblx0YWRkUm9sZUV4Y2x1ZGVMaXN0Pzogc3RyaW5nW11cblxuXHQvKiogKE9wdGlvbmFsKSBUaGUgZW50aXR5IHRoYXQgb3ducyB0aGUgdXNlciByb2xlcywgd2hlbiB0YXJnZXRpbmcgRW50aXR5VXNlclJvbGVzICovXG5cdGVudGl0eT86IE1vZGVsXG5cdC8qKiAoT3B0aW9uYWwpIEEgdXNlci1mcmllbmRseSBuYW1lIGZvciB0aGUgZW50aXR5IHR5cGUsIHdoZW4gdGFyZ2V0aW5nIEVudGl0eVVzZXJSb2xlcyAgKi9cblx0ZW50aXR5TmFtZT86IHN0cmluZ1xuXHQvKiogKE9wdGlvbmFsKSBzZXQgaWYgYHJlbmRlclJlbW92ZVVzZXJSb2xlRGVzY3JpcHRpb25gIHNob3VsZCBjaGVjayBmb3Igcm9zdGVyIHN5bmMgKi9cblx0ZXh0ZXJuYWxQcm92aWRlcnM/OiBNb2RlbENvbGxlY3Rpb248RXh0ZXJuYWxQcm92aWRlcj5cblxuXHQvKiogKE9wdGlvbmFsKSBBbGxvdyB1c2VycyB0byBiZSBleGNsdWRlZCBmcm9tIGJlaW5nIGRpc3BsYXllZCBpbiB0aGUgdGFibGUgKi9cblx0ZmlsdGVyVXNlcnM/OiAodXNlcnM6IFVzZXJXaXRoUm9sZXNbXSkgPT4gVXNlcldpdGhSb2xlc1tdXG5cdC8qKiAoT3B0aW9uYWwpIENhbGxiYWNrIHRoYXQgaXMgY2FsbGVkIGFmdGVyIHVzZXIgcm9sZXMgYXJlIGFkZGVkICovXG5cdG9uQWRkPzogKHVzZXJSb2xlczogVXNlclJvbGVbXSkgPT4gdm9pZFxuXHQvKiogKE9wdGlvbmFsKSBDYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBhZnRlciBhIHVzZXIgcm9sZSBpcyB1cGRhdGVkICovXG5cdG9uVXBkYXRlPzogKHVzZXJSb2xlOiBVc2VyUm9sZSwgcm9sZTogc3RyaW5nKSA9PiB2b2lkXG5cdC8qKiAoT3B0aW9uYWwpIENhbGxiYWNrIHRoYXQgaXMgY2FsbGVkIGFmdGVyIGEgdXNlciByb2xlIGlzIHJlbW92ZWQgKi9cblx0b25SZW1vdmU/OiAodXNlclJvbGU6IFVzZXJSb2xlKSA9PiB2b2lkXG5cdC8qKiAoT3B0aW9uYWwpIFJlbmRlciBjdXN0b20gY29tcG9uZW50cyBiZXR3ZWVuIHRoZSBBZGQgYW5kIFRhYmxlIGNvbXBvbmVudHMgKi9cblx0cmVuZGVyVGFibGVEZXNjcmlwdGlvbj86IChjYW5Nb2RpZnk/OiBib29sZWFuKSA9PiBSZWFjdC5KU1guRWxlbWVudFxuXHQvKiogKE9wdGlvbmFsKSBSZW5kZXIgY3VzdG9tIGNvbXBvbmVudHMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBBZGQgY29tcG9uZW50ICovXG5cdHJlbmRlckFkZERlc2NyaXB0aW9uPzogKGVudGl0eU5hbWU/OiBzdHJpbmcpID0+IFJlYWN0LkpTWC5FbGVtZW50XG5cdC8qKiAoT3B0aW9uYWwpIFByb3ZpZGUgY3VzdG9tIHVzZXItZnJpZW5kbHkgbmFtZXMgZm9yIGRpc3BsYXllZCByb2xlcyAqL1xuXHR0ZXh0Rm9yUm9sZT86IChyb2xlOiBzdHJpbmcpID0+IHN0cmluZ1xuXHQvKiogKE9wdGlvbmFsKSBQcm92aWRlIGN1c3RvbSB1c2VyLWZyaWVuZGx5IG5hbWVzIGZvciBkaXNwbGF5ZWQgcm9sZXMgdGhhdCByZXF1aXJlIGN1c3RvbSBjYXNpbmcgKi9cblx0bG93ZXJjYXNlVGV4dEZvclJvbGU/OiAocm9sZTogc3RyaW5nKSA9PiBzdHJpbmdcblx0LyoqIChPcHRpb25hbCkgUHJvdmlkZSBjdXN0b20gdXNlci1mcmllbmRseSBhcnRpY2xlcyAoXCJhXCIgdnMuIFwiYW5cIikgZm9yIGRpc3BsYXllZCByb2xlcyAqL1xuXHRzaW5ndWxhckFydGljbGVGb3JSb2xlPzogKHJvbGU6IHN0cmluZykgPT4gc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlclJvbGVzUHJvcHMgZXh0ZW5kcyBVc2VyUm9sZXNSZWR1eFByb3BzLCBVc2VyUm9sZXNPd25Qcm9wcyB7fVxuXG5pbnRlcmZhY2UgVXNlclJvbGVzU3RhdGUge1xuXHRzb3J0ZWRVc2VyczogVXNlcldpdGhSb2xlc1tdXG5cdC8vIGFkZFxuXHRhZGRVc2Vyc0hvb2tJZDogc3RyaW5nXG5cdGlzQWRkaW5nOiBib29sZWFuXG5cdGlkZW50aWZpZXJzVG9BZGQ/OiBzdHJpbmdbXVxuXHRyb2xlRm9yQWRkPzogc3RyaW5nXG5cdHNob3VsZFJlc2V0QWRkRm9ybTogYm9vbGVhblxuXHQvLyB1cGRhdGVcblx0dXNlclJvbGVUb1VwZGF0ZT86IFVzZXJSb2xlXG5cdHJvbGVGb3JVcGRhdGU/OiBzdHJpbmdcblx0aXNVcGRhdGluZzogYm9vbGVhblxuXHQvLyByZW1vdmVcblx0c2hvdWxkU2hvd1JlbW92ZURpYWxvZzogYm9vbGVhblxuXHR1c2VyUm9sZVRvUmVtb3ZlPzogVXNlclJvbGVcblx0aXNSZW1vdmluZzogYm9vbGVhblxuXHQvLyBtZXNzYWdlc1xuXHRzdWNjZXNzTWVzc2FnZT86IHN0cmluZ1xuXHRleGlzdGluZ01lc3NhZ2U/OiBzdHJpbmdcblx0YmxvY2tlZE1lc3NhZ2U/OiBzdHJpbmdcblx0ZmFpbE1lc3NhZ2U/OiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGRCdXNpbmVzc01vZGVsIHtcblx0YWRkZWRVc2VyUm9sZXM6IFVzZXJSb2xlW11cblx0ZXhpc3RpbmdVc2VyUm9sZXM6IFVzZXJSb2xlW11cblx0YmxvY2tlZFVzZXJSb2xlcz86IFVzZXJSb2xlW11cblx0aW52YWxpZElkZW50aWZpZXJzOiBzdHJpbmdbXVxuXHRhbGxvd2VkRG9tYWluczogc3RyaW5nXG5cdGludmFsaWREb21haW5JZGVudGlmaWVyczogc3RyaW5nW11cbn1cblxuLyoqXG4gKiBDb21wb25lbnQgdXNlZCB0byBtYW5hZ2UgZWl0aGVyIFVzZXJSb2xlcyAoZ2xvYmFsIHJvbGVzKSBvciBFbnRpdHlVc2VyUm9sZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VyUm9sZXMgZXh0ZW5kcyBDb21wb25lbnQ8VXNlclJvbGVzUHJvcHMsIFVzZXJSb2xlc1N0YXRlPiB7XG5cdHN0YXRlOiBVc2VyUm9sZXNTdGF0ZSA9IHtcblx0XHRzb3J0ZWRVc2VyczogW10sXG5cdFx0Ly8gYWRkXG5cdFx0YWRkVXNlcnNIb29rSWQ6IHV1aWR2NCgpLFxuXHRcdGlzQWRkaW5nOiBmYWxzZSxcblx0XHRpc1VwZGF0aW5nOiBmYWxzZSxcblx0XHRpc1JlbW92aW5nOiBmYWxzZSxcblx0XHRzaG91bGRSZXNldEFkZEZvcm06IGZhbHNlLFxuXHRcdHNob3VsZFNob3dSZW1vdmVEaWFsb2c6IGZhbHNlXG5cdH1cblxuXHRjb21wb25lbnREaWRNb3VudCgpIHtcblx0XHR0aGlzLnNldFN0YXRlRnJvbVByb3BzKHRoaXMucHJvcHMpXG5cdFx0Y29uc3QgeyBhZGRVc2Vyc0hvb2tJZCB9ID0gdGhpcy5zdGF0ZVxuXHRcdG5vU3RvcmVIb29rcy51bnJlZ2lzdGVyTm9TdG9yZUFjdGlvbkhvb2soYWRkVXNlcnNIb29rSWQpXG5cdH1cblxuXHRjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzOiBVc2VyUm9sZXNQcm9wcykge1xuXHRcdGNvbnN0IHsgbW9kZWxBcnJheTogcHJldk1vZGVsQXJyYXksIG1vZGVsU3RhdHVzOiBwcmV2TW9kZWxTdGF0dXMgfSA9IHByZXZQcm9wc1xuXHRcdGNvbnN0IHsgbW9kZWxBcnJheSwgbW9kZWxTdGF0dXMsIGVudGl0eU5hbWUgfSA9IHRoaXMucHJvcHNcblxuXHRcdGlmICghaXNFcXVhbChwcmV2TW9kZWxBcnJheSwgbW9kZWxBcnJheSkpIHtcblx0XHRcdHRoaXMuc2V0U3RhdGVGcm9tUHJvcHModGhpcy5wcm9wcylcblx0XHR9XG5cblx0XHQvLyBsb2FkaW5nIGVycm9yXG5cdFx0aWYgKFxuXHRcdFx0KHByZXZNb2RlbFN0YXR1cyA9PT0gTU9ERUxfU1RBVFVTLlVOSU5JVElBTElaRUQgfHwgcHJldk1vZGVsU3RhdHVzID09PSBNT0RFTF9TVEFUVVMuTE9BRElORykgJiZcblx0XHRcdG1vZGVsU3RhdHVzID09PSBNT0RFTF9TVEFUVVMuRVJST1Jcblx0XHQpIHtcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0XHRmYWlsTWVzc2FnZTogYE9vcHMhIFRoZXJlIHdhcyBhbiBlcnJvciBsb2FkaW5nJHtcblx0XHRcdFx0XHRlbnRpdHlOYW1lID8gYCB0aGUgcGVvcGxlIGZvciB5b3VyICR7ZW50aXR5TmFtZX1gIDogJydcblx0XHRcdFx0fS5cXHJcXG5QbGVhc2UgdHJ5IGFnYWluLmBcblx0XHRcdH0pXG5cdFx0fVxuXG5cdFx0Ly8gdXBkYXRpbmdcblx0XHRpZiAocHJldk1vZGVsU3RhdHVzID09PSBNT0RFTF9TVEFUVVMuVVBEQVRJTkcgJiYgbW9kZWxTdGF0dXMgIT09IE1PREVMX1NUQVRVUy5VUERBVElORykge1xuXHRcdFx0dGhpcy5kaWRVcGRhdGUobW9kZWxTdGF0dXMgPT09IE1PREVMX1NUQVRVUy5SRUFEWSlcblx0XHR9XG5cblx0XHQvLyByZW1vdmluZ1xuXHRcdGlmIChwcmV2TW9kZWxTdGF0dXMgPT09IE1PREVMX1NUQVRVUy5ERUxFVElORyAmJiBtb2RlbFN0YXR1cyAhPT0gTU9ERUxfU1RBVFVTLkRFTEVUSU5HKSB7XG5cdFx0XHR0aGlzLmRpZFJlbW92ZShtb2RlbFN0YXR1cyA9PT0gTU9ERUxfU1RBVFVTLlJFQURZKVxuXHRcdH1cblx0fVxuXG5cdHNldFN0YXRlRnJvbVByb3BzID0gKHByb3BzOiBVc2VyUm9sZXNQcm9wcykgPT4ge1xuXHRcdGNvbnN0IHsgbW9kZWxBcnJheTogdXNlclJvbGVzLCBmaWx0ZXJVc2VycyB9ID0gcHJvcHNcblx0XHRjb25zdCB1c2Vyc1dpdGhSb2xlcyA9IE9iamVjdC52YWx1ZXMoXG5cdFx0XHR1c2VyUm9sZXMucmVkdWNlKChyZXN1bHQ6IERpY3Rpb25hcnk8VXNlcldpdGhSb2xlcz4sIHVzZXJSb2xlOiBVc2VyUm9sZSkgPT4ge1xuXHRcdFx0XHRjb25zdCB1c2VySWQgPSBnZXRVc2VySWQodXNlclJvbGUpXG5cdFx0XHRcdGxldCB1c2VyV2l0aFJvbGVzID0gcmVzdWx0W3VzZXJJZF0gYXMgVXNlcldpdGhSb2xlcyB8IHVuZGVmaW5lZFxuXHRcdFx0XHRpZiAoIXVzZXJXaXRoUm9sZXMpIHtcblx0XHRcdFx0XHR1c2VyV2l0aFJvbGVzID0gY29udmVydFRvVXNlcldpdGhSb2xlcyh1c2VyUm9sZSlcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR1c2VyV2l0aFJvbGVzLnJvbGVzLnB1c2godXNlclJvbGUpXG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzdWx0W3VzZXJJZF0gPSB1c2VyV2l0aFJvbGVzXG5cdFx0XHRcdHJldHVybiByZXN1bHRcblx0XHRcdH0sIHt9KVxuXHRcdClcblx0XHRjb25zdCBmaWx0ZXJlZFVzZXJzID0gZmlsdGVyVXNlcnMgPyBmaWx0ZXJVc2Vycyh1c2Vyc1dpdGhSb2xlcykgOiB1c2Vyc1dpdGhSb2xlc1xuXHRcdGNvbnN0IHNvcnRlZFVzZXJzID0gZmlsdGVyZWRVc2Vycy5zb3J0KHNvcnRCeU5hbWVzKVxuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0c29ydGVkVXNlcnNcblx0XHR9KVxuXHR9XG5cblx0dGV4dEZvclJvbGUgPSAocm9sZTogc3RyaW5nLCBsb3dlcmNhc2UgPSBmYWxzZSkgPT4ge1xuXHRcdGlmIChsb3dlcmNhc2UgJiYgdGhpcy5wcm9wcy5sb3dlcmNhc2VUZXh0Rm9yUm9sZSkge1xuXHRcdFx0cmV0dXJuIHRoaXMucHJvcHMubG93ZXJjYXNlVGV4dEZvclJvbGUocm9sZSlcblx0XHR9XG5cdFx0Y29uc3Qgcm9sZVN0cmluZyA9IHRoaXMucHJvcHMudGV4dEZvclJvbGUgPyB0aGlzLnByb3BzLnRleHRGb3JSb2xlKHJvbGUpIDogdGV4dEZvckJhc2VSb2xlKHJvbGUpXG5cdFx0cmV0dXJuIGxvd2VyY2FzZSA/IHJvbGVTdHJpbmcudG9Mb3dlckNhc2UoKSA6IHJvbGVTdHJpbmdcblx0fVxuXG5cdHNpbmd1bGFyQXJ0aWNsZUZvclJvbGUgPSAocm9sZTogc3RyaW5nKSA9PiB7XG5cdFx0cmV0dXJuIHRoaXMucHJvcHMuc2luZ3VsYXJBcnRpY2xlRm9yUm9sZVxuXHRcdFx0PyB0aGlzLnByb3BzLnNpbmd1bGFyQXJ0aWNsZUZvclJvbGUocm9sZSlcblx0XHRcdDogc2luZ3VsYXJBcnRpY2xlRm9yQmFzZVJvbGUocm9sZSlcblx0fVxuXG5cdC8vI3JlZ2lvbiBBZGQgVXNlcnNcblxuXHRhZGRVc2VyUm9sZXMgPSAoaWRlbnRpZmllcnM6IHN0cmluZ1tdLCByb2xlOiBzdHJpbmcpID0+IHtcblx0XHRjb25zdCB7IGVudGl0eSB9ID0gdGhpcy5wcm9wc1xuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0aWRlbnRpZmllcnNUb0FkZDogaWRlbnRpZmllcnMsXG5cdFx0XHRyb2xlRm9yQWRkOiByb2xlLFxuXHRcdFx0c3VjY2Vzc01lc3NhZ2U6IHVuZGVmaW5lZCxcblx0XHRcdGZhaWxNZXNzYWdlOiB1bmRlZmluZWQsXG5cdFx0XHRleGlzdGluZ01lc3NhZ2U6IHVuZGVmaW5lZCxcblx0XHRcdGJsb2NrZWRNZXNzYWdlOiB1bmRlZmluZWQsXG5cdFx0XHRzaG91bGRSZXNldEFkZEZvcm06IGZhbHNlLFxuXHRcdFx0aXNBZGRpbmc6IHRydWVcblx0XHR9KVxuXHRcdGNvbnN0IHsgYWRkVXNlcnNIb29rSWQgfSA9IHRoaXMuc3RhdGVcblx0XHRub1N0b3JlSG9va3MucmVnaXN0ZXJOb1N0b3JlQWN0aW9uSG9vayhhZGRVc2Vyc0hvb2tJZCwgKGRhdGE6IEFkZEJ1c2luZXNzTW9kZWwgfCBGZXRjaEVycm9yRGF0YSB8IG51bGwpID0+IHtcblx0XHRcdG5vU3RvcmVIb29rcy51bnJlZ2lzdGVyTm9TdG9yZUFjdGlvbkhvb2soYWRkVXNlcnNIb29rSWQpXG5cdFx0XHR0aGlzLmRpZEFkZChkYXRhKVxuXHRcdH0pXG5cdFx0Y29uc3Qgcm9vdE1vZGVsTmFtZSA9IGdldFJvb3RNb2RlbE5hbWUodGhpcy5wcm9wcylcblx0XHRkaXNwYXRjaE1vZGVsRmV0Y2hSZXF1ZXN0KHtcblx0XHRcdG1vZGVsTmFtZTogYCR7cm9vdE1vZGVsTmFtZSA/IGAke3Jvb3RNb2RlbE5hbWV9LmAgOiAnJ31hZGRVc2VyUm9sZXNgLFxuXHRcdFx0cGF0aFBhcmFtczogZW50aXR5ID8gW2VudGl0eS5pZF0gOiB1bmRlZmluZWQsXG5cdFx0XHRib2R5OiB7XG5cdFx0XHRcdGVudGl0eUlkOiBlbnRpdHkgPyBlbnRpdHkuaWQgOiB1bmRlZmluZWQsXG5cdFx0XHRcdGlkZW50aWZpZXJzOiBpZGVudGlmaWVycyxcblx0XHRcdFx0cm9sZU5hbWU6IHJvbGVcblx0XHRcdH0sXG5cdFx0XHRub1N0b3JlOiB0cnVlLFxuXHRcdFx0Z3VpZDogYWRkVXNlcnNIb29rSWRcblx0XHR9KVxuXHR9XG5cblx0ZGlkQWRkID0gKGRhdGE6IEFkZEJ1c2luZXNzTW9kZWwgfCBGZXRjaEVycm9yRGF0YSB8IG51bGwpID0+IHtcblx0XHRjb25zdCB7IGVudGl0eU5hbWUsIG9uQWRkLCBtb2RlbCwgbW9kZWxOYW1lLCBwYXRoUGFyYW1zIH0gPSB0aGlzLnByb3BzXG5cdFx0Y29uc3QgeyByb2xlRm9yQWRkLCBpZGVudGlmaWVyc1RvQWRkIH0gPSB0aGlzLnN0YXRlXG5cdFx0aWYgKCFyb2xlRm9yQWRkIHx8ICFpZGVudGlmaWVyc1RvQWRkIHx8IGlkZW50aWZpZXJzVG9BZGQubGVuZ3RoID09PSAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2RpZEFkZCB3YXMgY2FsbGVkIGluIHRoZSBpbmNvcnJlY3Qgc3RhdGUnKVxuXHRcdH1cblxuXHRcdGlmICghZGF0YSB8fCBpc0ZldGNoRXJyb3JEYXRhKGRhdGEpKSB7XG5cdFx0XHRjb25zdCBmYWlsTWVzc2FnZSA9IGBUaGUgZm9sbG93aW5nIGlkZW50aWZpZXJzIHdlcmUgbm90IGFkZGVkJHtcblx0XHRcdFx0ZW50aXR5TmFtZSA/IGAgdG8geW91ciAke2VudGl0eU5hbWV9YCA6ICcnXG5cdFx0XHR9OlxcclxcbiR7aWRlbnRpZmllcnNUb0FkZC5qb2luKCdcXHJcXG4nKX1gXG5cblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0XHRzaG91bGRSZXNldEFkZEZvcm06IHRydWUsXG5cdFx0XHRcdGlzQWRkaW5nOiBmYWxzZSxcblx0XHRcdFx0aWRlbnRpZmllcnNUb0FkZDogdW5kZWZpbmVkLFxuXHRcdFx0XHRyb2xlRm9yQWRkOiB1bmRlZmluZWQsXG5cdFx0XHRcdGZhaWxNZXNzYWdlXG5cdFx0XHR9KVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXG5cdFx0Y29uc3Qge1xuXHRcdFx0YWRkZWRVc2VyUm9sZXMsXG5cdFx0XHRleGlzdGluZ1VzZXJSb2xlcyxcblx0XHRcdGJsb2NrZWRVc2VyUm9sZXMsXG5cdFx0XHRpbnZhbGlkSWRlbnRpZmllcnMsXG5cdFx0XHRhbGxvd2VkRG9tYWlucyxcblx0XHRcdGludmFsaWREb21haW5JZGVudGlmaWVyc1xuXHRcdH0gPSBkYXRhXG5cdFx0Y29uc3Qgcm9sZVN0cmluZyA9IHRoaXMudGV4dEZvclJvbGUocm9sZUZvckFkZCwgdHJ1ZSlcblx0XHRjb25zdCBzaW5ndWxhckFydGljbGVTdHJpbmcgPSB0aGlzLnNpbmd1bGFyQXJ0aWNsZUZvclJvbGUocm9sZUZvckFkZClcblxuXHRcdGNvbnN0IGFkZGVkTmFtZXMgPVxuXHRcdFx0YWRkZWRVc2VyUm9sZXMubGVuZ3RoID4gMFxuXHRcdFx0XHQ/IGFkZGVkVXNlclJvbGVzXG5cdFx0XHRcdFx0XHQubWFwKChhdTogVXNlcikgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gYCR7ZGlzcGxheU5hbWUoYXUpfSR7YXUudWlkID8gYCAoJHthdS51aWR9KWAgOiAnJ31gXG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0LmpvaW4oJ1xcclxcbicpXG5cdFx0XHRcdDogdW5kZWZpbmVkXG5cblx0XHRjb25zdCBzdWNjZXNzTWVzc2FnZSA9IGFkZGVkTmFtZXNcblx0XHRcdD8gYFRoZSBmb2xsb3dpbmcgJHtyb2xlU3RyaW5nfSR7YWRkZWRVc2VyUm9sZXMubGVuZ3RoID4gMSA/ICdzIHdlcmUnIDogJyB3YXMnfSBzdWNjZXNzZnVsbHkgYWRkZWQke1xuXHRcdFx0XHRcdGVudGl0eU5hbWUgPyBgIHRvIHlvdXIgJHtlbnRpdHlOYW1lfWAgOiAnJ1xuXHRcdFx0XHR9OlxcclxcbiR7YWRkZWROYW1lc31gXG5cdFx0XHQ6IHVuZGVmaW5lZFxuXG5cdFx0Y29uc3QgZXhpc3RpbmdOYW1lcyA9XG5cdFx0XHRleGlzdGluZ1VzZXJSb2xlcy5sZW5ndGggPiAwXG5cdFx0XHRcdD8gZXhpc3RpbmdVc2VyUm9sZXMubWFwKChldTogVXNlcikgPT4gYCR7ZGlzcGxheU5hbWUoZXUpfSR7ZXUudWlkID8gYCAoJHtldS51aWR9KWAgOiAnJ31gKS5qb2luKCdcXHJcXG4nKVxuXHRcdFx0XHQ6IHVuZGVmaW5lZFxuXG5cdFx0Y29uc3QgaGFzTXVsdGlwbGVFeGlzdGluZyA9IGV4aXN0aW5nVXNlclJvbGVzLmxlbmd0aCA+IDFcblx0XHRjb25zdCBleGlzdGluZ01lc3NhZ2UgPSBleGlzdGluZ05hbWVzXG5cdFx0XHQ/IGBUaGUgZm9sbG93aW5nICR7aGFzTXVsdGlwbGVFeGlzdGluZyA/ICdwZW9wbGUgd2VyZScgOiAncGVyc29uIHdhcyd9IGFscmVhZHkgJHtcblx0XHRcdFx0XHRlbnRpdHlOYW1lXG5cdFx0XHRcdFx0XHQ/IGBpbiB5b3VyICR7ZW50aXR5TmFtZX0gYXMgJHtoYXNNdWx0aXBsZUV4aXN0aW5nID8gJycgOiBgJHtzaW5ndWxhckFydGljbGVTdHJpbmd9IGB9YFxuXHRcdFx0XHRcdFx0OiBoYXNNdWx0aXBsZUV4aXN0aW5nXG5cdFx0XHRcdFx0XHRcdD8gJydcblx0XHRcdFx0XHRcdFx0OiBgJHtzaW5ndWxhckFydGljbGVTdHJpbmd9IGBcblx0XHRcdFx0fSR7cm9sZVN0cmluZ30ke2hhc011bHRpcGxlRXhpc3RpbmcgPyAncycgOiAnJ306XFxyXFxuJHtleGlzdGluZ05hbWVzfWBcblx0XHRcdDogdW5kZWZpbmVkXG5cblx0XHRjb25zdCBibG9ja2VkTmFtZXMgPVxuXHRcdFx0ISFibG9ja2VkVXNlclJvbGVzICYmIGJsb2NrZWRVc2VyUm9sZXMubGVuZ3RoID4gMFxuXHRcdFx0XHQ/IGJsb2NrZWRVc2VyUm9sZXMubWFwKChldTogVXNlcikgPT4gYCR7ZGlzcGxheU5hbWUoZXUpfSR7ZXUudWlkID8gYCAoJHtldS51aWR9KWAgOiAnJ31gKS5qb2luKCdcXHJcXG4nKVxuXHRcdFx0XHQ6IHVuZGVmaW5lZFxuXHRcdGNvbnN0IGhhc011bHRpcGxlQmxvY2tlZCA9ICEhYmxvY2tlZFVzZXJSb2xlcyAmJiBibG9ja2VkVXNlclJvbGVzLmxlbmd0aCA+IDFcblx0XHRjb25zdCBibG9ja2VkTWVzc2FnZSA9IGJsb2NrZWROYW1lc1xuXHRcdFx0PyBgVGhlIGZvbGxvd2luZyAke2hhc011bHRpcGxlQmxvY2tlZCA/ICdwZW9wbGUnIDogJ3BlcnNvbid9IGNvdWxkIG5vdCBiZSBhZGRlZCAke1xuXHRcdFx0XHRcdGVudGl0eU5hbWUgPyBgdG8geW91ciAke2VudGl0eU5hbWV9YCA6ICcnXG5cdFx0XHRcdH0gYXMgJHtoYXNNdWx0aXBsZUJsb2NrZWQgPyAnJyA6IGAke3Npbmd1bGFyQXJ0aWNsZVN0cmluZ30gYH0ke3JvbGVTdHJpbmd9JHtcblx0XHRcdFx0XHRoYXNNdWx0aXBsZUJsb2NrZWQgPyAncycgOiAnJ1xuXHRcdFx0XHR9IGJlY2F1c2UgdGhleSBhbHJlYWR5IGhhdmUgYSByb2xlOlxcclxcbiR7YmxvY2tlZE5hbWVzfWBcblx0XHRcdDogdW5kZWZpbmVkXG5cblx0XHRsZXQgZmFpbE1lc3NhZ2UgPVxuXHRcdFx0aW52YWxpZElkZW50aWZpZXJzLmxlbmd0aCA+IDBcblx0XHRcdFx0PyBgVGhlIGZvbGxvd2luZyAke2dldERvbWFpbklkZW50aWZpZXJUeXBlUGx1cmFsU3RyaW5nKCl9IGFyZSBpbnZhbGlkOlxcclxcbiR7aW52YWxpZElkZW50aWZpZXJzLmpvaW4oXG5cdFx0XHRcdFx0XHQnXFxyXFxuJ1xuXHRcdFx0XHRcdCl9YFxuXHRcdFx0XHQ6IHVuZGVmaW5lZFxuXG5cdFx0aWYgKGludmFsaWREb21haW5JZGVudGlmaWVycy5sZW5ndGggPiAwKSB7XG5cdFx0XHRmYWlsTWVzc2FnZSA9IGAke1xuXHRcdFx0XHRmYWlsTWVzc2FnZSA/IGAke2ZhaWxNZXNzYWdlfVxcclxcbmAgOiAnJ1xuXHRcdFx0fVRoZSBmb2xsb3dpbmcgJHtnZXREb21haW5JZGVudGlmaWVyVHlwZVBsdXJhbFN0cmluZygpfSBkbyBub3QgbWF0Y2ggdGhlIGFsbG93ZWQgZG9tYWlucyBvZiAke2FsbG93ZWREb21haW5zLnJlcGxhY2UoXG5cdFx0XHRcdCcsJyxcblx0XHRcdFx0JywgJ1xuXHRcdFx0KX06XFxyXFxuJHtpbnZhbGlkRG9tYWluSWRlbnRpZmllcnMuam9pbignXFxyXFxuJyl9YFxuXHRcdH1cblxuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0c2hvdWxkUmVzZXRBZGRGb3JtOiB0cnVlLFxuXHRcdFx0aXNBZGRpbmc6IGZhbHNlLFxuXHRcdFx0aWRlbnRpZmllcnNUb0FkZDogdW5kZWZpbmVkLFxuXHRcdFx0cm9sZUZvckFkZDogdW5kZWZpbmVkLFxuXHRcdFx0c3VjY2Vzc01lc3NhZ2UsXG5cdFx0XHRleGlzdGluZ01lc3NhZ2UsXG5cdFx0XHRibG9ja2VkTWVzc2FnZSxcblx0XHRcdGZhaWxNZXNzYWdlXG5cdFx0fSlcblxuXHRcdC8vIG9ubHkgcmVsb2FkIGlmIHdlIGhhZCBzb21lIHN1Y2Nlc3NmdWwgYWRkc1xuXHRcdGlmIChhZGRlZE5hbWVzKSB7XG5cdFx0XHQvLyB1cGRhdGUgcmVkdXggd2l0aCBhZGRlZCB1c2VyUm9sZXNcblx0XHRcdGNvbnN0IHVwZGF0ZWRNb2RlbCA9IGNsb25lRGVlcChtb2RlbClcblx0XHRcdGFkZGVkVXNlclJvbGVzLmZvckVhY2godXNlclJvbGUgPT4gKHVwZGF0ZWRNb2RlbFt1c2VyUm9sZS5pZF0gPSBjbG9uZURlZXAodXNlclJvbGUpKSlcblxuXHRcdFx0Ly8gY3JlYXRlIGEgZHVtbXkgYWN0aW9uIGFuZCBjYWxsIGBwcmVwYXJlRmV0Y2hgIHRvIGdldCB0aGUgZmluYWwgYG1vZGVsUGF0aGBcblx0XHRcdGNvbnN0IHsgbW9kZWxQYXRoIH0gPSBwcmVwYXJlRmV0Y2goXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0eXBlOiBNT0RFTF9GRVRDSF9SRVFVRVNUX0FDVElPTl9UWVBFLkZFVENIX1JFUVVFU1QsXG5cdFx0XHRcdFx0bW9kZWxOYW1lLFxuXHRcdFx0XHRcdHBhdGhQYXJhbXNcblx0XHRcdFx0fSxcblx0XHRcdFx0Z2V0RW5kcG9pbnRNYXBwaW5ncygpXG5cdFx0XHQpXG5cdFx0XHRkaXNwYXRjaEFjdGlvbjxNb2RlbEZldGNoUmVzdWx0QWN0aW9uPih7XG5cdFx0XHRcdHR5cGU6IE1PREVMX0ZFVENIX1JFU1VMVF9BQ1RJT05fVFlQRS5GRVRDSF9SRVNVTFRfUkVDRUlWRUQsXG5cdFx0XHRcdG1vZGVsUGF0aCxcblx0XHRcdFx0ZGF0YTogdXBkYXRlZE1vZGVsXG5cdFx0XHR9KVxuXG5cdFx0XHRpZiAob25BZGQpIHtcblx0XHRcdFx0b25BZGQoYWRkZWRVc2VyUm9sZXMpXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8jZW5kcmVnaW9uIEFkZCBVc2Vyc1xuXG5cdC8vI3JlZ2lvbiBVcGRhdGVcblxuXHR1cGRhdGVVc2VyUm9sZSA9ICh1c2VyUm9sZVRvVXBkYXRlOiBVc2VyUm9sZSwgbmV3Um9sZTogc3RyaW5nKSA9PiB7XG5cdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHRpc1VwZGF0aW5nOiB0cnVlLFxuXHRcdFx0dXNlclJvbGVUb1VwZGF0ZSxcblx0XHRcdHJvbGVGb3JVcGRhdGU6IG5ld1JvbGUsXG5cdFx0XHRzdWNjZXNzTWVzc2FnZTogdW5kZWZpbmVkLFxuXHRcdFx0ZmFpbE1lc3NhZ2U6IHVuZGVmaW5lZFxuXHRcdH0pXG5cdFx0dGhpcy5wcm9wcy51cGRhdGUoe1xuXHRcdFx0aWQ6IHVzZXJSb2xlVG9VcGRhdGUuaWQsXG5cdFx0XHRib2R5OiB7fSxcblx0XHRcdHF1ZXJ5UGFyYW1zOiB7XG5cdFx0XHRcdHJvbGVOYW1lOiBuZXdSb2xlXG5cdFx0XHR9XG5cdFx0fSlcblx0fVxuXG5cdGRpZFVwZGF0ZSA9IChpc1N1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcblx0XHRjb25zdCB7IGVudGl0eU5hbWUsIG9uVXBkYXRlIH0gPSB0aGlzLnByb3BzXG5cdFx0Y29uc3QgeyB1c2VyUm9sZVRvVXBkYXRlLCByb2xlRm9yVXBkYXRlIH0gPSB0aGlzLnN0YXRlXG5cdFx0aWYgKHVzZXJSb2xlVG9VcGRhdGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdgZGlkVXBkYXRlYCB3YXMgY2FsbGVkIHdpdGhvdXQgc2V0dGluZyBgdXNlclJvbGVUb1VwZGF0ZWAgaW4gc3RhdGUnKVxuXHRcdH1cblx0XHRpZiAocm9sZUZvclVwZGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2BkaWRVcGRhdGVgIHdhcyBjYWxsZWQgd2l0aG91dCBzZXR0aW5nIGByb2xlRm9yVXBkYXRlYCBpbiBzdGF0ZScpXG5cdFx0fVxuXG5cdFx0Y29uc3QgbmFtZSA9IGRpc3BsYXlOYW1lKHVzZXJSb2xlVG9VcGRhdGUpXG5cdFx0Y29uc3Qgcm9sZVN0cmluZyA9IHRoaXMudGV4dEZvclJvbGUocm9sZUZvclVwZGF0ZSwgdHJ1ZSlcblx0XHRjb25zdCBzaW5ndWxhckFydGljbGVTdHJpbmcgPSB0aGlzLnNpbmd1bGFyQXJ0aWNsZUZvclJvbGUocm9sZUZvclVwZGF0ZSlcblxuXHRcdGlmICghaXNTdWNjZXNzKSB7XG5cdFx0XHRjb25zdCBmYWlsTWVzc2FnZSA9IGBPb3BzISBUaGVyZSB3YXMgYW4gZXJyb3IgdXBkYXRpbmcgJHtuYW1lfSB0byAke3Npbmd1bGFyQXJ0aWNsZVN0cmluZ30gJHtyb2xlU3RyaW5nfSR7XG5cdFx0XHRcdGVudGl0eU5hbWUgPyBgIGluIHlvdXIgJHtlbnRpdHlOYW1lfWAgOiAnJ1xuXHRcdFx0fS4gUGxlYXNlIHRyeSBhZ2Fpbi5gXG5cdFx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdFx0aXNVcGRhdGluZzogZmFsc2UsXG5cdFx0XHRcdHVzZXJSb2xlVG9VcGRhdGU6IHVuZGVmaW5lZCxcblx0XHRcdFx0cm9sZUZvclVwZGF0ZTogdW5kZWZpbmVkLFxuXHRcdFx0XHRmYWlsTWVzc2FnZVxuXHRcdFx0fSlcblx0XHRcdHJldHVyblxuXHRcdH1cblxuXHRcdGNvbnN0IHN1Y2Nlc3NNZXNzYWdlID0gYCR7bmFtZX0gd2FzIHN1Y2Nlc3NmdWxseSB1cGRhdGVkIHRvICR7c2luZ3VsYXJBcnRpY2xlU3RyaW5nfSAke3JvbGVTdHJpbmd9JHtcblx0XHRcdGVudGl0eU5hbWUgPyBgIGluIHlvdXIgJHtlbnRpdHlOYW1lfWAgOiAnJ1xuXHRcdH0uYFxuXG5cdFx0aWYgKG9uVXBkYXRlKSB7XG5cdFx0XHRvblVwZGF0ZSh1c2VyUm9sZVRvVXBkYXRlLCByb2xlRm9yVXBkYXRlKVxuXHRcdH1cblxuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0aXNVcGRhdGluZzogZmFsc2UsXG5cdFx0XHR1c2VyUm9sZVRvVXBkYXRlOiB1bmRlZmluZWQsXG5cdFx0XHRyb2xlRm9yVXBkYXRlOiB1bmRlZmluZWQsXG5cdFx0XHRzdWNjZXNzTWVzc2FnZVxuXHRcdH0pXG5cdH1cblxuXHQvLyNlbmRyZWdpb24gVXBkYXRlXG5cblx0Ly8jcmVnaW9uIFJlbW92ZSBVc2VyXG5cblx0YWxlcnRSZW1vdmVVc2VyUm9sZSA9ICh1c2VyUm9sZVRvUmVtb3ZlOiBVc2VyUm9sZSkgPT4ge1xuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0dXNlclJvbGVUb1JlbW92ZSxcblx0XHRcdHNob3VsZFNob3dSZW1vdmVEaWFsb2c6IHRydWVcblx0XHR9KVxuXHR9XG5cblx0cmVtb3ZlVXNlclJvbGVUaXRsZSA9IChyb2xlRm9yUmVtb3ZlOiBzdHJpbmcpID0+IHtcblx0XHRyZXR1cm4gYFJlbW92ZSAke3RoaXMudGV4dEZvclJvbGUocm9sZUZvclJlbW92ZSl9YFxuXHR9XG5cblx0cmVuZGVyUmVtb3ZlVXNlclJvbGVEZXNjcmlwdGlvbiA9ICh1c2VyUm9sZVRvUmVtb3ZlOiBVc2VyUm9sZSwgd2FybmluZz86IFJlYWN0LkpTWC5FbGVtZW50KSA9PiB7XG5cdFx0Y29uc3QgeyBlbnRpdHksIGV4dGVybmFsUHJvdmlkZXJzIH0gPSB0aGlzLnByb3BzXG5cdFx0Y29uc3QgZ3JvdXAgPSBlbnRpdHkgJiYgJ2V4dGVybmFsR3JvdXBzJyBpbiBlbnRpdHkgPyAoZW50aXR5IGFzIEdyb3VwKSA6IHVuZGVmaW5lZFxuXG5cdFx0Y29uc3Qgcm9sZVN0cmluZyA9IHRoaXMudGV4dEZvclJvbGUodXNlclJvbGVUb1JlbW92ZS5yb2xlLCB0cnVlKVxuXHRcdGNvbnN0IHNpbmd1bGFyQXJ0aWNsZVN0cmluZyA9IHRoaXMuc2luZ3VsYXJBcnRpY2xlRm9yUm9sZSh1c2VyUm9sZVRvUmVtb3ZlLnJvbGUpXG5cdFx0Y29uc3QgZGVmYXVsdFdhcm5pbmcgPSB3YXJuaW5nID8/IChcblx0XHRcdDxwIGNsYXNzTmFtZT1cIm1hMFwiPlxuXHRcdFx0XHRBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gPHN0cm9uZz5yZW1vdmUge2Rpc3BsYXlOYW1lKHVzZXJSb2xlVG9SZW1vdmUpfTwvc3Ryb25nPiBhc3snICd9XG5cdFx0XHRcdHtzaW5ndWxhckFydGljbGVTdHJpbmd9IHtyb2xlU3RyaW5nfT9cblx0XHRcdDwvcD5cblx0XHQpXG5cblx0XHRjb25zdCBleHRlcm5hbEdyb3Vwc1RvUmVtb3ZlID0gZ3JvdXA/LmV4dGVybmFsR3JvdXBzLmZpbHRlcihlZyA9PiBlZy51c2VySWQgPT09IHVzZXJSb2xlVG9SZW1vdmUuaWQpXG5cblx0XHRpZiAoXG5cdFx0XHQhZXh0ZXJuYWxHcm91cHNUb1JlbW92ZSB8fFxuXHRcdFx0ZXh0ZXJuYWxHcm91cHNUb1JlbW92ZS5sZW5ndGggPT09IDAgfHxcblx0XHRcdHVzZXJSb2xlVG9SZW1vdmUucm9sZSAhPT0gQkFTRV9ST0xFLkdST1VQX09XTkVSXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gZGVmYXVsdFdhcm5pbmdcblx0XHR9XG5cblx0XHRjb25zdCBleHRlcm5hbEdyb3Vwc1RvUmVtb3ZlV2l0aFJvc3RlclN5bmMgPSBleHRlcm5hbEdyb3Vwc1RvUmVtb3ZlLmZpbHRlcihcblx0XHRcdGVnID0+IGV4dGVybmFsUHJvdmlkZXJzPy5bZWcuZXh0ZXJuYWxQcm92aWRlcklkXT8ucm9zdGVyU3luY0VuYWJsZWRcblx0XHQpXG5cblx0XHRyZXR1cm4gKFxuXHRcdFx0PGRpdj5cblx0XHRcdFx0PHA+XG5cdFx0XHRcdFx0VGhlIGZvbGxvd2luZyBjb3Vyc2Ugc2VjdGlvbnMgd2lsbCBiZSA8c3Ryb25nPmRpc2Nvbm5lY3RlZDwvc3Ryb25nPi57JyAnfVxuXHRcdFx0XHRcdHtleHRlcm5hbEdyb3Vwc1RvUmVtb3ZlV2l0aFJvc3RlclN5bmMubGVuZ3RoID4gMCAmJiAoXG5cdFx0XHRcdFx0XHQ8c3Bhbj5cblx0XHRcdFx0XHRcdFx0QW55IGF1dG9tYXRpY2FsbHkgYWRkZWQgc3R1ZGVudHMgd2lsbCBiZSA8c3Ryb25nPnJlbW92ZWQ8L3N0cm9uZz4uXG5cdFx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdFx0KX1cblx0XHRcdFx0PC9wPlxuXHRcdFx0XHQ8dWw+XG5cdFx0XHRcdFx0e2V4dGVybmFsR3JvdXBzVG9SZW1vdmUubWFwKGVnID0+IChcblx0XHRcdFx0XHRcdDxsaSBrZXk9e2VnLmlkfT57ZWcuZGVzY3JpcHRpb259PC9saT5cblx0XHRcdFx0XHQpKX1cblx0XHRcdFx0PC91bD5cblx0XHRcdFx0e2RlZmF1bHRXYXJuaW5nfVxuXHRcdFx0PC9kaXY+XG5cdFx0KVxuXHR9XG5cblx0cmVtb3ZlVXNlclJvbGUgPSAoc2hvdWxkUmVtb3ZlOiBib29sZWFuKSA9PiB7XG5cdFx0Y29uc3QgeyB1c2VyUm9sZVRvUmVtb3ZlIH0gPSB0aGlzLnN0YXRlXG5cdFx0aWYgKHVzZXJSb2xlVG9SZW1vdmUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdgcmVtb3ZlVXNlcmAgd2FzIGNhbGxlZCB3aXRob3V0IHNldHRpbmcgYHVzZXJSb2xlVG9SZW1vdmVgIGluIHN0YXRlJylcblx0XHR9XG5cdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHRpc1JlbW92aW5nOiBzaG91bGRSZW1vdmUsXG5cdFx0XHRzaG91bGRTaG93UmVtb3ZlRGlhbG9nOiBmYWxzZSxcblx0XHRcdHN1Y2Nlc3NNZXNzYWdlOiB1bmRlZmluZWQsXG5cdFx0XHRmYWlsTWVzc2FnZTogdW5kZWZpbmVkLFxuXHRcdFx0Ly8gY2xlYXIgaWYgY2FuY2VsbGVkXG5cdFx0XHR1c2VyUm9sZVRvUmVtb3ZlOiBzaG91bGRSZW1vdmUgPyB1c2VyUm9sZVRvUmVtb3ZlIDogdW5kZWZpbmVkXG5cdFx0fSlcblx0XHRpZiAoIXNob3VsZFJlbW92ZSkge1xuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHRcdHRoaXMucHJvcHMuZGVsZXRlKHtcblx0XHRcdGlkOiB1c2VyUm9sZVRvUmVtb3ZlLmlkXG5cdFx0fSlcblx0fVxuXG5cdGRpZFJlbW92ZSA9IChpc1N1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcblx0XHRjb25zdCB7IGVudGl0eU5hbWUsIG9uUmVtb3ZlIH0gPSB0aGlzLnByb3BzXG5cdFx0Y29uc3QgeyB1c2VyUm9sZVRvUmVtb3ZlIH0gPSB0aGlzLnN0YXRlXG5cdFx0aWYgKHVzZXJSb2xlVG9SZW1vdmUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdgZGlkUmVtb3ZlYCB3YXMgY2FsbGVkIHdpdGhvdXQgc2V0dGluZyBgdXNlclJvbGVUb1JlbW92ZWAgaW4gc3RhdGUnKVxuXHRcdH1cblxuXHRcdGNvbnN0IG5hbWUgPSBkaXNwbGF5TmFtZSh1c2VyUm9sZVRvUmVtb3ZlKVxuXHRcdGlmICghaXNTdWNjZXNzKSB7XG5cdFx0XHRjb25zdCBmYWlsTWVzc2FnZSA9IGBPb3BzISBUaGVyZSB3YXMgYW4gZXJyb3IgcmVtb3ZpbmcgJHtuYW1lfSR7XG5cdFx0XHRcdGVudGl0eU5hbWUgPyBgIGZyb20geW91ciAke2VudGl0eU5hbWV9YCA6ICcnXG5cdFx0XHR9LiBQbGVhc2UgdHJ5IGFnYWluLmBcblx0XHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0XHRpc1JlbW92aW5nOiBmYWxzZSxcblx0XHRcdFx0dXNlclJvbGVUb1JlbW92ZTogdW5kZWZpbmVkLFxuXHRcdFx0XHRmYWlsTWVzc2FnZVxuXHRcdFx0fSlcblx0XHRcdHJldHVyblxuXHRcdH1cblxuXHRcdGNvbnN0IHN1Y2Nlc3NNZXNzYWdlID0gYCR7bmFtZX0gd2FzIHN1Y2Nlc3NmdWxseSByZW1vdmVkJHtlbnRpdHlOYW1lID8gYCBmcm9tIHlvdXIgJHtlbnRpdHlOYW1lfWAgOiAnJ30uYFxuXG5cdFx0aWYgKG9uUmVtb3ZlKSB7XG5cdFx0XHRvblJlbW92ZSh1c2VyUm9sZVRvUmVtb3ZlKVxuXHRcdH1cblxuXHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0aXNSZW1vdmluZzogZmFsc2UsXG5cdFx0XHR1c2VyUm9sZVRvUmVtb3ZlOiB1bmRlZmluZWQsXG5cdFx0XHRzdWNjZXNzTWVzc2FnZVxuXHRcdH0pXG5cdH1cblxuXHQvLyNlbmRyZWdpb24gUmVtb3ZlIFVzZXJcblxuXHRyZW5kZXIoKSB7XG5cdFx0Y29uc3Qge1xuXHRcdFx0bW9kZWxTdGF0dXMsXG5cdFx0XHRjYW5Nb2RpZnksXG5cdFx0XHRyZWFkT25seSxcblx0XHRcdGNhbkRlbGV0ZVNlbGYsXG5cdFx0XHRhbGxvd011bHRpcGxlUm9sZXMsXG5cdFx0XHRpc0FkZERpc2FibGVkLFxuXHRcdFx0aXNVcGRhdGVEaXNhYmxlZCxcblx0XHRcdGlzRGVsZXRlRGlzYWJsZWQsXG5cdFx0XHRkZWZhdWx0Um9sZSxcblx0XHRcdHJlcXVpcmVkUm9sZSxcblx0XHRcdHJvbGVEZXNjcmlwdGlvbnMsXG5cdFx0XHRhZGRSb2xlRXhjbHVkZUxpc3QsXG5cdFx0XHRlbnRpdHlOYW1lLFxuXHRcdFx0cmVuZGVyVGFibGVEZXNjcmlwdGlvbixcblx0XHRcdHJlbmRlckFkZERlc2NyaXB0aW9uXG5cdFx0fSA9IHRoaXMucHJvcHNcblx0XHRjb25zdCB7XG5cdFx0XHRzb3J0ZWRVc2Vycyxcblx0XHRcdGlzQWRkaW5nLFxuXHRcdFx0aXNVcGRhdGluZyxcblx0XHRcdGlzUmVtb3ZpbmcsXG5cdFx0XHRzaG91bGRSZXNldEFkZEZvcm0sXG5cdFx0XHRzaG91bGRTaG93UmVtb3ZlRGlhbG9nLFxuXHRcdFx0dXNlclJvbGVUb1VwZGF0ZSxcblx0XHRcdHVzZXJSb2xlVG9SZW1vdmUsXG5cdFx0XHRzdWNjZXNzTWVzc2FnZSxcblx0XHRcdGV4aXN0aW5nTWVzc2FnZSxcblx0XHRcdGJsb2NrZWRNZXNzYWdlLFxuXHRcdFx0ZmFpbE1lc3NhZ2Vcblx0XHR9ID0gdGhpcy5zdGF0ZVxuXG5cdFx0Y29uc3QgYWRkYWJsZVJvbGVEZXNjcmlwdGlvbnMgPSBhZGRSb2xlRXhjbHVkZUxpc3Rcblx0XHRcdD8gcGlja0J5KHJvbGVEZXNjcmlwdGlvbnMsIChfLCBrZXkpID0+ICFhZGRSb2xlRXhjbHVkZUxpc3QuaW5jbHVkZXMoa2V5KSlcblx0XHRcdDogcm9sZURlc2NyaXB0aW9uc1xuXHRcdGNvbnN0IHJvbGVzID0gT2JqZWN0LmtleXMocm9sZURlc2NyaXB0aW9ucylcblx0XHRjb25zdCBzaG91bGRSZW5kZXJBc011dGFibGUgPSAhcmVhZE9ubHkgJiYgY2FuTW9kaWZ5XG5cblx0XHRyZXR1cm4gKFxuXHRcdFx0PD5cblx0XHRcdFx0eyEhc3VjY2Vzc01lc3NhZ2UgJiYgKFxuXHRcdFx0XHRcdDxBbGVydFdpdGhJY29uXG5cdFx0XHRcdFx0XHRpZD1cInN1Y2Nlc3NNZXNzYWdlQWxlcnRcIlxuXHRcdFx0XHRcdFx0dmFyaWFudD1cInN1Y2Nlc3NcIlxuXHRcdFx0XHRcdFx0ZGlzbWlzc2libGVcblx0XHRcdFx0XHRcdG9uQ2xvc2U9eygpID0+XG5cdFx0XHRcdFx0XHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0XHRcdFx0XHRcdHN1Y2Nlc3NNZXNzYWdlOiB1bmRlZmluZWRcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdH0+XG5cdFx0XHRcdFx0XHQ8cCBjbGFzc05hbWU9XCJwcmUtd3JhcFwiPntzdWNjZXNzTWVzc2FnZX08L3A+XG5cdFx0XHRcdFx0PC9BbGVydFdpdGhJY29uPlxuXHRcdFx0XHQpfVxuXHRcdFx0XHR7ISFleGlzdGluZ01lc3NhZ2UgJiYgKFxuXHRcdFx0XHRcdDxBbGVydFdpdGhJY29uXG5cdFx0XHRcdFx0XHRpZD1cImV4aXN0aW5nTWVzc2FnZUFsZXJ0XCJcblx0XHRcdFx0XHRcdHZhcmlhbnQ9XCJpbmZvXCJcblx0XHRcdFx0XHRcdGRpc21pc3NpYmxlXG5cdFx0XHRcdFx0XHRvbkNsb3NlPXsoKSA9PlxuXHRcdFx0XHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdFx0XHRcdFx0XHRleGlzdGluZ01lc3NhZ2U6IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0fT5cblx0XHRcdFx0XHRcdDxwIGNsYXNzTmFtZT1cInByZS13cmFwXCI+e2V4aXN0aW5nTWVzc2FnZX08L3A+XG5cdFx0XHRcdFx0PC9BbGVydFdpdGhJY29uPlxuXHRcdFx0XHQpfVxuXHRcdFx0XHR7ISFibG9ja2VkTWVzc2FnZSAmJiAoXG5cdFx0XHRcdFx0PEFsZXJ0V2l0aEljb25cblx0XHRcdFx0XHRcdGlkPVwiYmxvY2tlZE1lc3NhZ2VBbGVydFwiXG5cdFx0XHRcdFx0XHR2YXJpYW50PVwid2FybmluZ1wiXG5cdFx0XHRcdFx0XHRkaXNtaXNzaWJsZVxuXHRcdFx0XHRcdFx0b25DbG9zZT17KCkgPT5cblx0XHRcdFx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHRcdFx0XHRcdFx0YmxvY2tlZE1lc3NhZ2U6IHVuZGVmaW5lZFxuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0fT5cblx0XHRcdFx0XHRcdDxwIGNsYXNzTmFtZT1cInByZS13cmFwXCI+e2Jsb2NrZWRNZXNzYWdlfTwvcD5cblx0XHRcdFx0XHQ8L0FsZXJ0V2l0aEljb24+XG5cdFx0XHRcdCl9XG5cdFx0XHRcdHshIWZhaWxNZXNzYWdlICYmIChcblx0XHRcdFx0XHQ8QWxlcnRXaXRoSWNvblxuXHRcdFx0XHRcdFx0aWQ9XCJmYWlsTWVzc2FnZUFsZXJ0XCJcblx0XHRcdFx0XHRcdHZhcmlhbnQ9XCJ3YXJuaW5nXCJcblx0XHRcdFx0XHRcdGRpc21pc3NpYmxlXG5cdFx0XHRcdFx0XHRvbkNsb3NlPXsoKSA9PlxuXHRcdFx0XHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdFx0XHRcdFx0XHRmYWlsTWVzc2FnZTogdW5kZWZpbmVkXG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHR9PlxuXHRcdFx0XHRcdFx0PHAgY2xhc3NOYW1lPVwicHJlLXdyYXBcIj57ZmFpbE1lc3NhZ2V9PC9wPlxuXHRcdFx0XHRcdDwvQWxlcnRXaXRoSWNvbj5cblx0XHRcdFx0KX1cblx0XHRcdFx0e3Nob3VsZFJlbmRlckFzTXV0YWJsZSAmJiAoXG5cdFx0XHRcdFx0PFVzZXJSb2xlc0FkZFxuXHRcdFx0XHRcdFx0aWQ9XCJlbnRpdHlVc2VyUm9sZXNBZGRcIlxuXHRcdFx0XHRcdFx0ZGlzYWJsZWQ9e2lzQWRkRGlzYWJsZWR9XG5cdFx0XHRcdFx0XHRlbnRpdHlOYW1lPXtlbnRpdHlOYW1lfVxuXHRcdFx0XHRcdFx0ZGVmYXVsdFJvbGU9e2RlZmF1bHRSb2xlfVxuXHRcdFx0XHRcdFx0cm9sZURlc2NyaXB0aW9ucz17YWRkYWJsZVJvbGVEZXNjcmlwdGlvbnN9XG5cdFx0XHRcdFx0XHRyZW5kZXJBZGREZXNjcmlwdGlvbj17cmVuZGVyQWRkRGVzY3JpcHRpb259XG5cdFx0XHRcdFx0XHR0ZXh0Rm9yUm9sZT17dGhpcy50ZXh0Rm9yUm9sZX1cblx0XHRcdFx0XHRcdGlzQWRkaW5nVXNlcnNUb1JvbGU9e2lzQWRkaW5nfVxuXHRcdFx0XHRcdFx0c2hvdWxkUmVzZXQ9e3Nob3VsZFJlc2V0QWRkRm9ybX1cblx0XHRcdFx0XHRcdGFkZFVzZXJSb2xlcz17dGhpcy5hZGRVc2VyUm9sZXN9XG5cdFx0XHRcdFx0Lz5cblx0XHRcdFx0KX1cblx0XHRcdFx0eyEhcmVuZGVyVGFibGVEZXNjcmlwdGlvbiAmJiByZW5kZXJUYWJsZURlc2NyaXB0aW9uKHNob3VsZFJlbmRlckFzTXV0YWJsZSl9XG5cdFx0XHRcdDxSb3cgY2xhc3NOYW1lPVwibXQzXCI+XG5cdFx0XHRcdFx0PENvbCB4cz17MTJ9PlxuXHRcdFx0XHRcdFx0e21vZGVsU3RhdHVzID09PSBNT0RFTF9TVEFUVVMuTE9BRElORyA/IChcblx0XHRcdFx0XHRcdFx0PExvYWRpbmcgLz5cblx0XHRcdFx0XHRcdCkgOiBzb3J0ZWRVc2Vycy5sZW5ndGggPiAwID8gKFxuXHRcdFx0XHRcdFx0XHQ8VXNlclJvbGVzQ29udGV4dC5Qcm92aWRlclxuXHRcdFx0XHRcdFx0XHRcdHZhbHVlPXt7XG5cdFx0XHRcdFx0XHRcdFx0XHRpc1VwZGF0ZURpc2FibGVkOiBpc1VwZGF0ZURpc2FibGVkIHx8IHJlYWRPbmx5LFxuXHRcdFx0XHRcdFx0XHRcdFx0aXNEZWxldGVEaXNhYmxlZDogaXNEZWxldGVEaXNhYmxlZCB8fCByZWFkT25seSxcblx0XHRcdFx0XHRcdFx0XHRcdGNhbk1vZGlmeTogc2hvdWxkUmVuZGVyQXNNdXRhYmxlLFxuXHRcdFx0XHRcdFx0XHRcdFx0Y2FuRGVsZXRlU2VsZixcblx0XHRcdFx0XHRcdFx0XHRcdGFsbG93TXVsdGlwbGVSb2xlcyxcblx0XHRcdFx0XHRcdFx0XHRcdHJvbGVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0cmVxdWlyZWRSb2xlLFxuXHRcdFx0XHRcdFx0XHRcdFx0dGV4dEZvclJvbGU6IHRoaXMudGV4dEZvclJvbGUsXG5cdFx0XHRcdFx0XHRcdFx0XHR1c2VyUm9sZVRvVXBkYXRlLFxuXHRcdFx0XHRcdFx0XHRcdFx0aXNVcGRhdGluZyxcblx0XHRcdFx0XHRcdFx0XHRcdHVwZGF0ZVVzZXJSb2xlOiB0aGlzLnVwZGF0ZVVzZXJSb2xlLFxuXHRcdFx0XHRcdFx0XHRcdFx0dXNlclJvbGVUb1JlbW92ZSxcblx0XHRcdFx0XHRcdFx0XHRcdGlzUmVtb3ZpbmcsXG5cdFx0XHRcdFx0XHRcdFx0XHRyZW1vdmVVc2VyUm9sZTogdGhpcy5hbGVydFJlbW92ZVVzZXJSb2xlXG5cdFx0XHRcdFx0XHRcdFx0fX0+XG5cdFx0XHRcdFx0XHRcdFx0PFVzZXJSb2xlc1RhYmxlIGlkPVwiZW50aXR5VXNlclJvbGVzVGFibGVcIiB1c2Vycz17c29ydGVkVXNlcnN9IC8+XG5cdFx0XHRcdFx0XHRcdDwvVXNlclJvbGVzQ29udGV4dC5Qcm92aWRlcj5cblx0XHRcdFx0XHRcdCkgOiBudWxsfVxuXHRcdFx0XHRcdDwvQ29sPlxuXHRcdFx0XHQ8L1Jvdz5cblx0XHRcdFx0eyEhdXNlclJvbGVUb1JlbW92ZSAmJiAoXG5cdFx0XHRcdFx0PEFsZXJ0RGlhbG9nXG5cdFx0XHRcdFx0XHRpZD1cInJlbW92ZVVzZXJBbGVydFwiXG5cdFx0XHRcdFx0XHRpc09wZW49e3Nob3VsZFNob3dSZW1vdmVEaWFsb2d9XG5cdFx0XHRcdFx0XHR0aXRsZT17dGhpcy5yZW1vdmVVc2VyUm9sZVRpdGxlKHVzZXJSb2xlVG9SZW1vdmUucm9sZSl9XG5cdFx0XHRcdFx0XHRkZXNjcmlwdGlvbj17dGhpcy5yZW5kZXJSZW1vdmVVc2VyUm9sZURlc2NyaXB0aW9uKHVzZXJSb2xlVG9SZW1vdmUpfVxuXHRcdFx0XHRcdFx0b25EZXN0cm95PXsoKSA9PiB0aGlzLnJlbW92ZVVzZXJSb2xlKHRydWUpfVxuXHRcdFx0XHRcdFx0ZGVzdHJveVRleHQ9XCJZZXMsIHJlbW92ZSB0aGUgdXNlclwiXG5cdFx0XHRcdFx0XHRvbkNhbmNlbD17KCkgPT4gdGhpcy5yZW1vdmVVc2VyUm9sZShmYWxzZSl9XG5cdFx0XHRcdFx0XHRjYW5jZWxUZXh0PVwiTm8sIEkgY2hhbmdlZCBteSBtaW5kXCJcblx0XHRcdFx0XHQvPlxuXHRcdFx0XHQpfVxuXHRcdFx0PC8+XG5cdFx0KVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoc3RhdGU6IEJhc2VSZWR1eFN0YXRlLCBvd25Qcm9wczogVXNlclJvbGVzT3duUHJvcHMpOiBVc2VyUm9sZXNSZWR1eFByb3BzID0+IHtcblx0Y29uc3QgY2FuTW9kaWZ5R2xvYmFsbHkgPSBjYW5QZXJmb3JtQWN0aXZpdHlHbG9iYWxseShvd25Qcm9wcy5tb2RpZnlVc2VyUm9sZUFjdGl2aXR5TmFtZSwgZGVmYXVsdE9wdGlvbnMoc3RhdGUpKVxuXG5cdGNvbnN0IGNhbk1vZGlmeSA9XG5cdFx0Y2FuTW9kaWZ5R2xvYmFsbHkgfHxcblx0XHQob3duUHJvcHMuZW50aXR5XG5cdFx0XHQ/IGNhblBlcmZvcm1BY3Rpdml0eU9uRW50aXR5KG93blByb3BzLm1vZGlmeVVzZXJSb2xlQWN0aXZpdHlOYW1lLCBkZWZhdWx0T3B0aW9ucyhzdGF0ZSwgb3duUHJvcHMsICdlbnRpdHknKSlcblx0XHRcdDogZmFsc2UpXG5cblx0cmV0dXJuIHtcblx0XHRjYW5Nb2RpZnksXG5cdFx0Y2FuRGVsZXRlU2VsZjpcblx0XHRcdGNhbk1vZGlmeSB8fFxuXHRcdFx0KG93blByb3BzLmVudGl0eSAmJiBvd25Qcm9wcy5kZWxldGVPd25Vc2VyUm9sZUFjdGl2aXR5TmFtZVxuXHRcdFx0XHQ/IGNhblBlcmZvcm1BY3Rpdml0eU9uRW50aXR5KFxuXHRcdFx0XHRcdFx0b3duUHJvcHMuZGVsZXRlT3duVXNlclJvbGVBY3Rpdml0eU5hbWUsXG5cdFx0XHRcdFx0XHRkZWZhdWx0T3B0aW9ucyhzdGF0ZSwgb3duUHJvcHMsICdlbnRpdHknKVxuXHRcdFx0XHRcdClcblx0XHRcdFx0OiBmYWxzZSlcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcykoVXNlclJvbGVzKVxuIl0sIm1hcHBpbmdzIjoiO0FBQUEsU0FBU0EsU0FBUyxFQUFjQyxPQUFPLEVBQUVDLE1BQU0sUUFBUSxRQUFRO0FBQy9ELE9BQU9DLEtBQUssSUFBSUMsU0FBUyxRQUFRLE9BQU87QUFDeEMsU0FBU0MsR0FBRyxFQUFFQyxHQUFHLFFBQVEsaUJBQWlCO0FBQzFDLFNBQVNDLE9BQU8sUUFBUSxhQUFhO0FBQ3JDLFNBQVNDLEVBQUUsSUFBSUMsTUFBTSxRQUFRLE1BQU07QUFDbkMsU0FBU0MsV0FBVyxRQUFRLDhCQUE4QjtBQUMxRCxTQUFTQyxPQUFPLFFBQVEsMEJBQTBCO0FBQ2xELFNBQVNDLFlBQVksUUFBUSxnQ0FBZ0M7QUFDN0QsU0FBU0MsY0FBYyxRQUFRLGtDQUFrQztBQUNqRSxTQUFTQyxtQkFBbUIsUUFBUSxpQkFBaUI7QUFDckQsU0FBU0MsU0FBUyxRQUFRLDBCQUEwQjtBQUNwRCxTQUFTQyxZQUFZLFFBQVEsNkJBQTZCO0FBQzFELFNBQVNDLGNBQWMsRUFBRUMseUJBQXlCLFFBQVEsMkJBQTJCO0FBQ3JGLFNBQ0NDLCtCQUErQixFQUMvQkMsOEJBQThCLFFBRXhCLHFCQUFxQjtBQUM1QixTQUFTQyxZQUFZLFFBQVEsK0JBQStCO0FBYTVELFNBQVNDLDBCQUEwQixFQUFFQywwQkFBMEIsRUFBRUMsY0FBYyxRQUFRLDBCQUEwQjtBQUNqSCxTQUFTQywwQkFB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