studiokit-scaffolding-js 7.0.12-next.1.4 → 7.0.12-next.2.2

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