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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/lib/components/ActionList.js +164 -37
  2. package/lib/components/AlertDialog.js +128 -12
  3. package/lib/components/AlertWithIcon.js +88 -29
  4. package/lib/components/ConnectedModal.js +35 -12
  5. package/lib/components/Dropdowns/GroupsDropdown.js +63 -45
  6. package/lib/components/Dropdowns/ManagedNavDropdown.js +92 -67
  7. package/lib/components/Dropdowns/UserDropdown.js +105 -24
  8. package/lib/components/Dropdowns/index.js +4 -10
  9. package/lib/components/EntityOwnerList.js +47 -21
  10. package/lib/components/Error.js +101 -12
  11. package/lib/components/ErrorBoundary.js +127 -38
  12. package/lib/components/ErrorMessage.js +39 -12
  13. package/lib/components/Forms/DateField.js +56 -45
  14. package/lib/components/Forms/TimeField.js +76 -45
  15. package/lib/components/Forms/index.js +3 -5
  16. package/lib/components/Groups/CreateEditCopySaveButtons.js +109 -14
  17. package/lib/components/Groups/ExternalGroups/Attach.js +206 -151
  18. package/lib/components/Groups/ExternalGroups/Table.js +176 -48
  19. package/lib/components/Groups/GroupCreateOrEditCommonProps.js +2 -2
  20. package/lib/components/Groups/RosterSyncInfo.js +142 -23
  21. package/lib/components/HOC/AccessibleAppComponent.js +88 -72
  22. package/lib/components/HOC/ActivityRequiredComponent.js +68 -33
  23. package/lib/components/HOC/AsyncComponent.js +49 -41
  24. package/lib/components/HOC/AuthenticatedComponent.js +55 -44
  25. package/lib/components/HOC/CollectionComponent.js +154 -104
  26. package/lib/components/HOC/CollectionFirstItemComponent.js +45 -40
  27. package/lib/components/HOC/CollectionItemComponent.js +152 -100
  28. package/lib/components/HOC/ConnectedModalComponent.js +87 -69
  29. package/lib/components/HOC/DataDependentComponent.js +26 -27
  30. package/lib/components/HOC/EntityComponent.js +57 -53
  31. package/lib/components/HOC/FullscreenModalComponent.js +139 -108
  32. package/lib/components/HOC/GroupActivityRequiredComponent.js +27 -20
  33. package/lib/components/HOC/GuidComponent.js +20 -20
  34. package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +32 -29
  35. package/lib/components/HOC/ModelErrorRedirectComponent.js +37 -39
  36. package/lib/components/HOC/SearchPersistorComponent.js +237 -173
  37. package/lib/components/HOC/UnauthenticatedComponent.js +32 -30
  38. package/lib/components/HOC/UserComponent.js +6 -8
  39. package/lib/components/Icons/IconAlphaList.js +28 -8
  40. package/lib/components/Icons/IconExternalUser.js +28 -8
  41. package/lib/components/Icons/IconImpersonation.js +28 -8
  42. package/lib/components/Icons/IconStopImpersonating.js +28 -8
  43. package/lib/components/Icons/IconTable.js +29 -9
  44. package/lib/components/Icons/IconTableDeleteCol.js +28 -8
  45. package/lib/components/Icons/IconTableDeleteRow.js +28 -8
  46. package/lib/components/Icons/IconTableInsertCol.js +28 -8
  47. package/lib/components/Icons/IconTableInsertRow.js +28 -8
  48. package/lib/components/Impersonation/Button.js +71 -16
  49. package/lib/components/Impersonation/Link.js +72 -16
  50. package/lib/components/Impersonation/UserDetail.js +60 -11
  51. package/lib/components/Loading.js +23 -8
  52. package/lib/components/LockDownBrowser/Check.js +188 -51
  53. package/lib/components/LockDownBrowser/ExitButton.js +22 -13
  54. package/lib/components/LockDownBrowser/Launch.js +64 -64
  55. package/lib/components/Lti/Confirm.js +147 -14
  56. package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +165 -36
  57. package/lib/components/Lti/Launch.js +99 -25
  58. package/lib/components/Lti/LaunchGroup.js +81 -16
  59. package/lib/components/ManageTable.js +304 -90
  60. package/lib/components/ManageTableNoDataComponent.js +38 -7
  61. package/lib/components/NewVersionAlert.js +76 -49
  62. package/lib/components/NotFound.js +81 -11
  63. package/lib/components/Notifications.js +179 -129
  64. package/lib/components/PaginationNextButton.js +28 -9
  65. package/lib/components/PaginationPreviousButton.js +28 -9
  66. package/lib/components/Quill/CustomToolbar.js +427 -222
  67. package/lib/components/Quill/Formats/Image.js +67 -67
  68. package/lib/components/Quill/Formats/List.js +38 -47
  69. package/lib/components/Quill/Formats/Video.js +23 -26
  70. package/lib/components/Quill/ImageDropModule.js +136 -114
  71. package/lib/components/Quill/ImageWarning.js +41 -12
  72. package/lib/components/Quill/ImageWithAltTextModal.js +420 -89
  73. package/lib/components/Quill/Specs/CustomImageSpec.js +32 -31
  74. package/lib/components/Quill/Specs/CustomVideoSpec.js +22 -23
  75. package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +89 -97
  76. package/lib/components/Quill/TableModule/Blots/TableBlot.js +47 -50
  77. package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +48 -51
  78. package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +219 -224
  79. package/lib/components/Quill/TableModule/Blots/TableContainer.js +75 -86
  80. package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +70 -73
  81. package/lib/components/Quill/TableModule/constants.js +40 -42
  82. package/lib/components/Quill/TableModule/index.js +357 -305
  83. package/lib/components/Quill/TableModule/utils.js +39 -48
  84. package/lib/components/Quill/accessibilityFix.js +219 -223
  85. package/lib/components/Quill/index.js +30 -33
  86. package/lib/components/RefreshIndicator/Bordered.js +44 -10
  87. package/lib/components/RefreshIndicator/Inline.js +43 -12
  88. package/lib/components/RefreshIndicator/index.js +257 -62
  89. package/lib/components/SearchControls.js +211 -14
  90. package/lib/components/SentryRoute.js +5 -7
  91. package/lib/components/Tables/RoleFilter.js +66 -38
  92. package/lib/components/Tables/TextFilter.js +58 -18
  93. package/lib/components/UserRoles/Add.js +193 -99
  94. package/lib/components/UserRoles/Context.js +3 -6
  95. package/lib/components/UserRoles/RoleCell.js +176 -75
  96. package/lib/components/UserRoles/Select.js +151 -20
  97. package/lib/components/UserRoles/Table.js +215 -82
  98. package/lib/components/UserRoles/index.js +526 -386
  99. package/lib/config/eslint/index.js +26 -29
  100. package/lib/config/eslint/lib/order.js +21 -28
  101. package/lib/config/eslint/lib/prettier.js +15 -19
  102. package/lib/config/eslint/lib/typescript.js +87 -113
  103. package/lib/config/eslint/react.js +18 -15
  104. package/lib/constants/baseActivity.js +26 -28
  105. package/lib/constants/baseRole.js +10 -12
  106. package/lib/constants/configuration.js +43 -55
  107. package/lib/constants/externalProviderType.js +6 -8
  108. package/lib/constants/fetchErrorData.js +10 -12
  109. package/lib/constants/index.js +13 -15
  110. package/lib/constants/lockDownBrowser.js +23 -25
  111. package/lib/constants/mockData.js +370 -300
  112. package/lib/constants/modelStatus.js +11 -13
  113. package/lib/constants/notificationType.js +8 -10
  114. package/lib/constants/operatingSystem.js +8 -10
  115. package/lib/constants/shard.js +7 -9
  116. package/lib/constants/table.js +18 -22
  117. package/lib/constants/tier.js +8 -10
  118. package/lib/constants/userRole.js +11 -8
  119. package/lib/endpointMappings.js +191 -182
  120. package/lib/hooks/useCollection.js +79 -65
  121. package/lib/hooks/useCollectionConfiguration.js +220 -80
  122. package/lib/hooks/useCollectionItem.js +151 -57
  123. package/lib/hooks/useGuid.js +16 -9
  124. package/lib/hooks/usePrevious.js +14 -13
  125. package/lib/index.js +11 -26
  126. package/lib/redux/actionCreator.js +44 -35
  127. package/lib/redux/actions/AuthAction.js +45 -32
  128. package/lib/redux/actions/ModalAction.js +6 -8
  129. package/lib/redux/actions/ModelAction.js +95 -43
  130. package/lib/redux/actions/NotificationAction.js +6 -8
  131. package/lib/redux/actions/SearchAction.js +5 -7
  132. package/lib/redux/actions/index.js +6 -8
  133. package/lib/redux/configureReducers.js +48 -46
  134. package/lib/redux/configureStore.js +77 -91
  135. package/lib/redux/helpers.js +2 -5
  136. package/lib/redux/reducers/authReducer.js +44 -43
  137. package/lib/redux/reducers/index.js +7 -14
  138. package/lib/redux/reducers/modalsReducer.js +43 -31
  139. package/lib/redux/reducers/modelsReducer.js +131 -137
  140. package/lib/redux/reducers/notificationsReducer.js +20 -20
  141. package/lib/redux/reducers/searchReducer.js +13 -13
  142. package/lib/redux/sagas/appInsightsSaga.js +19 -21
  143. package/lib/redux/sagas/authSaga.js +248 -234
  144. package/lib/redux/sagas/caliperSaga.js +142 -131
  145. package/lib/redux/sagas/clockOffsetSaga.js +29 -32
  146. package/lib/redux/sagas/configurationSaga.js +8 -10
  147. package/lib/redux/sagas/downtimeApiErrorSaga.js +16 -19
  148. package/lib/redux/sagas/errorSaga.js +23 -24
  149. package/lib/redux/sagas/googleAnalyticsSaga.js +24 -27
  150. package/lib/redux/sagas/identityProviderSaga.js +19 -21
  151. package/lib/redux/sagas/initialDataLoadSaga.js +34 -31
  152. package/lib/redux/sagas/lockDownBrowserErrorSaga.js +25 -22
  153. package/lib/redux/sagas/modelFetchSaga.js +302 -286
  154. package/lib/redux/sagas/noStoreSaga.js +60 -61
  155. package/lib/redux/sagas/postLoginDataSaga.js +37 -32
  156. package/lib/redux/sagas/postLoginRedirectSaga.js +22 -27
  157. package/lib/redux/sagas/rootSaga.js +77 -60
  158. package/lib/redux/sagas/sentrySaga.js +25 -28
  159. package/lib/redux/sagas/userIdSaga.js +13 -15
  160. package/lib/services/codeProviderService.js +21 -21
  161. package/lib/services/dateService.js +6 -8
  162. package/lib/services/documentService.js +10 -11
  163. package/lib/services/fetchService.js +103 -95
  164. package/lib/services/persistenceService.js +27 -30
  165. package/lib/services/ticketProviderService.js +25 -25
  166. package/lib/services/tokenPersistenceService.js +8 -10
  167. package/lib/services/windowService.js +14 -16
  168. package/lib/startup.js +110 -101
  169. package/lib/types/AppConfiguration.js +2 -2
  170. package/lib/types/Artifact.js +7 -9
  171. package/lib/types/BaseReduxState.js +2 -2
  172. package/lib/types/Client.js +2 -2
  173. package/lib/types/Collection.js +2 -2
  174. package/lib/types/Configuration.js +2 -2
  175. package/lib/types/DeepLinkingResponseRequest.js +2 -2
  176. package/lib/types/DeletableModel.js +2 -2
  177. package/lib/types/Event.js +2 -2
  178. package/lib/types/ExternalGroup.js +2 -2
  179. package/lib/types/ExternalProvider.js +2 -2
  180. package/lib/types/ExternalTerm.js +2 -2
  181. package/lib/types/Group.js +2 -2
  182. package/lib/types/IdentityProvider.js +2 -2
  183. package/lib/types/LtiLaunch.js +2 -2
  184. package/lib/types/NameOnlyEntity.js +2 -2
  185. package/lib/types/Notification.js +2 -2
  186. package/lib/types/OptionalRecord.js +2 -2
  187. package/lib/types/OwnerSchedule.js +2 -2
  188. package/lib/types/PropertyOfType.js +2 -2
  189. package/lib/types/Quill.js +2 -2
  190. package/lib/types/RoleDescription.js +2 -2
  191. package/lib/types/Search.js +2 -2
  192. package/lib/types/SimpleLocation.js +2 -2
  193. package/lib/types/UniTime.js +2 -2
  194. package/lib/types/User.js +2 -2
  195. package/lib/types/UserRole.js +2 -2
  196. package/lib/types/auth/AuthState.js +2 -2
  197. package/lib/types/auth/CasV1LoginRequestBody.js +2 -2
  198. package/lib/types/auth/ClientCredentials.js +2 -2
  199. package/lib/types/auth/CodeProviderService.js +2 -2
  200. package/lib/types/auth/LocalLoginRequestBody.js +2 -2
  201. package/lib/types/auth/TicketProviderService.js +2 -2
  202. package/lib/types/auth/TokenPersistenceService.js +2 -2
  203. package/lib/types/auth/index.js +8 -10
  204. package/lib/types/externals.d.js +2 -0
  205. package/lib/types/index.js +29 -31
  206. package/lib/types/net/EndpointConfig.js +2 -2
  207. package/lib/types/net/EndpointMapping.js +2 -2
  208. package/lib/types/net/EndpointMappings.js +2 -2
  209. package/lib/types/net/ErrorHandler.js +2 -2
  210. package/lib/types/net/FetchConfig.js +2 -2
  211. package/lib/types/net/FetchErrorData.js +6 -8
  212. package/lib/types/net/FetchResult.js +2 -2
  213. package/lib/types/net/HTTPMethod.js +2 -2
  214. package/lib/types/net/HTTPStatusCode.js +12 -14
  215. package/lib/types/net/Metadata.js +2 -2
  216. package/lib/types/net/Model.js +2 -2
  217. package/lib/types/net/ModelCollection.js +2 -2
  218. package/lib/types/net/ModelsState.js +2 -2
  219. package/lib/types/net/OAuthToken.js +2 -2
  220. package/lib/types/net/OAuthTokenOrNull.js +2 -2
  221. package/lib/types/net/TokenAccessFunction.js +2 -2
  222. package/lib/types/net/index.js +17 -19
  223. package/lib/utils/baseActivity.js +83 -85
  224. package/lib/utils/baseRole.js +32 -36
  225. package/lib/utils/collection.js +403 -297
  226. package/lib/utils/cookies.js +19 -23
  227. package/lib/utils/date.js +188 -205
  228. package/lib/utils/dom.js +130 -131
  229. package/lib/utils/domainIdentifier.js +4 -8
  230. package/lib/utils/entityUserRole.js +2 -5
  231. package/lib/utils/error.js +14 -19
  232. package/lib/utils/events.js +32 -31
  233. package/lib/utils/externalGroup.js +20 -25
  234. package/lib/utils/externalProviders.js +4 -7
  235. package/lib/utils/externalTerms.js +6 -6
  236. package/lib/utils/fetch.js +168 -176
  237. package/lib/utils/group.js +14 -11
  238. package/lib/utils/groupDates.js +38 -46
  239. package/lib/utils/groupRoles.js +23 -32
  240. package/lib/utils/lockDownBrowser.js +12 -15
  241. package/lib/utils/logger.js +23 -28
  242. package/lib/utils/lti.js +4 -7
  243. package/lib/utils/model.js +28 -43
  244. package/lib/utils/number.js +9 -13
  245. package/lib/utils/promise.js +23 -26
  246. package/lib/utils/quill.js +55 -60
  247. package/lib/utils/route.js +52 -60
  248. package/lib/utils/search.js +72 -87
  249. package/lib/utils/shard.js +33 -42
  250. package/lib/utils/sort.js +47 -50
  251. package/lib/utils/string.js +10 -12
  252. package/lib/utils/table.js +29 -33
  253. package/lib/utils/timezone.js +7 -12
  254. package/lib/utils/url.js +130 -144
  255. package/lib/utils/user.js +54 -64
  256. package/lib/utils/userAgent.js +7 -14
  257. package/lib/utils/userRole.js +36 -39
  258. package/package.json +17 -3
package/lib/utils/date.js CHANGED
@@ -1,121 +1,73 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isTimeInputSupported = exports.isDateInputSupported = exports.getDateMinusTime = exports.getLocalDateTimeFromUtc = exports.getLocalMomentFromUtc = exports.getZonedMomentFromLocalDateTime = exports.getZonedMomentFromUtcInDefaultZone = exports.getZonedMomentFromUtc = exports.getOffsetDate = exports.getServerNowUtc = exports.setClockOffset = void 0;
4
- exports.getEndOfDay = getEndOfDay;
5
- exports.getEndOfMinute = getEndOfMinute;
6
- exports.isNowEqualOrAfterDate = isNowEqualOrAfterDate;
7
- exports.isNowEqualOrBeforeDate = isNowEqualOrBeforeDate;
8
- exports.isNowAfterDate = isNowAfterDate;
9
- exports.isNowBeforeDate = isNowBeforeDate;
10
- exports.getFormattedFullDateAndTime = getFormattedFullDateAndTime;
11
- exports.getFormattedFullDateWithWeek = getFormattedFullDateWithWeek;
12
- exports.getFormattedNumberedDateAndTime = getFormattedNumberedDateAndTime;
13
- exports.getFormattedNumberedDateAndTimeWithoutYear = getFormattedNumberedDateAndTimeWithoutYear;
14
- exports.getFormattedSimplifiedDate = getFormattedSimplifiedDate;
15
- exports.getFormattedSimplifiedDateWithoutYear = getFormattedSimplifiedDateWithoutYear;
16
- exports.getFormattedSimplifiedDateWithYearIfNotCurrent = getFormattedSimplifiedDateWithYearIfNotCurrent;
17
- exports.getFormattedNumberedDate = getFormattedNumberedDate;
18
- exports.getFormattedNumberedDateWithFullYear = getFormattedNumberedDateWithFullYear;
19
- exports.getFormattedNumberedDateForInput = getFormattedNumberedDateForInput;
20
- exports.getFormattedNumberedDateWithoutYear = getFormattedNumberedDateWithoutYear;
21
- exports.getFormattedNumberedTime = getFormattedNumberedTime;
22
- exports.getFormattedNumberedTimeWithFullZone = getFormattedNumberedTimeWithFullZone;
23
- exports.getFormattedNumberedTimeWithoutZone = getFormattedNumberedTimeWithoutZone;
24
- exports.getFormattedNumberedTimeWithoutZoneOrMeridian = getFormattedNumberedTimeWithoutZoneOrMeridian;
25
- exports.getFullFormattedTimeZone = getFullFormattedTimeZone;
26
- exports.getFormattedTimeZone = getFormattedTimeZone;
27
- exports.isDateTimeValid = isDateTimeValid;
28
- const tslib_1 = require("tslib");
29
- const moment_timezone_1 = tslib_1.__importDefault(require("moment-timezone"));
30
- const moment_timezone_utils_1 = tslib_1.__importDefault(require("moment-timezone/moment-timezone-utils"));
31
- const timezone_1 = require("./timezone");
1
+ import moment from 'moment-timezone';
2
+ import momentUtils from 'moment-timezone/moment-timezone-utils';
3
+ import { getDefaultTimeZoneId, guessTimeZoneId } from './timezone';
4
+
32
5
  /**
33
6
  * This value is used by time-sensitive functions in this module and other date/time utils. Any time
34
7
  * a new Date object is constructed, it will use this value to adjust the time by this offset (to
35
8
  * make it consistent with a known time)
36
9
  */
37
10
  let clockOffset = 0;
11
+
38
12
  /**
39
13
  * When a GroupAssessment comes in the door, it includes the current UTC datetime. This method is
40
14
  * used to update the difference between the (accurate) server time and the browser time
41
15
  */
42
- const setClockOffset = function (offset) {
43
- clockOffset = offset;
16
+ export const setClockOffset = function (offset) {
17
+ clockOffset = offset;
44
18
  };
45
- exports.setClockOffset = setClockOffset;
19
+
46
20
  /**
47
21
  * Get the current UTC time, calibrated to the API server's clock
48
22
  */
49
- const getServerNowUtc = function () {
50
- return new Date(Date.now() + clockOffset);
23
+ export const getServerNowUtc = function () {
24
+ return new Date(Date.now() + clockOffset);
51
25
  };
52
- exports.getServerNowUtc = getServerNowUtc;
26
+
53
27
  /**
54
28
  * Return the provided date, offset by the clockOffset
55
29
  */
56
- const getOffsetDate = (date) => {
57
- return new Date(date.getTime() + clockOffset);
30
+ export const getOffsetDate = date => {
31
+ return new Date(date.getTime() + clockOffset);
58
32
  };
59
- exports.getOffsetDate = getOffsetDate;
60
- const getZonedMomentFromUtc = (dateTimeUtc = (0, exports.getServerNowUtc)().toISOString(), timeZoneId = (0, timezone_1.guessTimeZoneId)()) => {
61
- return moment_timezone_1.default.utc(dateTimeUtc).tz(timeZoneId);
33
+ export const getZonedMomentFromUtc = function () {
34
+ let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
35
+ let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : guessTimeZoneId();
36
+ return moment.utc(dateTimeUtc).tz(timeZoneId);
62
37
  };
63
- exports.getZonedMomentFromUtc = getZonedMomentFromUtc;
64
- const getZonedMomentFromUtcInDefaultZone = (dateTimeUtc = (0, exports.getServerNowUtc)().toISOString()) => {
65
- const timeZoneId = (0, timezone_1.getDefaultTimeZoneId)();
66
- return (0, exports.getZonedMomentFromUtc)(dateTimeUtc, timeZoneId);
38
+ export const getZonedMomentFromUtcInDefaultZone = function () {
39
+ let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
40
+ const timeZoneId = getDefaultTimeZoneId();
41
+ return getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
67
42
  };
68
- exports.getZonedMomentFromUtcInDefaultZone = getZonedMomentFromUtcInDefaultZone;
69
- const getZonedMomentFromLocalDateTime = (localDateTime, timeZoneId = (0, timezone_1.guessTimeZoneId)()) => {
70
- const localMoment = (0, moment_timezone_1.default)(localDateTime);
71
- const zonedMoment = moment_timezone_1.default.tz([
72
- localMoment.year(),
73
- localMoment.month(),
74
- localMoment.date(),
75
- localMoment.hour(),
76
- localMoment.minute(),
77
- localMoment.second(),
78
- localMoment.millisecond()
79
- ], timeZoneId);
80
- return zonedMoment;
43
+ export const getZonedMomentFromLocalDateTime = function (localDateTime) {
44
+ let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : guessTimeZoneId();
45
+ const localMoment = moment(localDateTime);
46
+ const zonedMoment = moment.tz([localMoment.year(), localMoment.month(), localMoment.date(), localMoment.hour(), localMoment.minute(), localMoment.second(), localMoment.millisecond()], timeZoneId);
47
+ return zonedMoment;
81
48
  };
82
- exports.getZonedMomentFromLocalDateTime = getZonedMomentFromLocalDateTime;
83
- const getLocalMomentFromUtc = (dateTimeUtc = (0, exports.getServerNowUtc)().toISOString(), timeZoneId = (0, timezone_1.guessTimeZoneId)()) => {
84
- const zonedMoment = (0, exports.getZonedMomentFromUtc)(dateTimeUtc, timeZoneId);
85
- const localMoment = (0, moment_timezone_1.default)([
86
- zonedMoment.year(),
87
- zonedMoment.month(),
88
- zonedMoment.date(),
89
- zonedMoment.hour(),
90
- zonedMoment.minute(),
91
- zonedMoment.second(),
92
- zonedMoment.millisecond()
93
- ]);
94
- return localMoment;
49
+ export const getLocalMomentFromUtc = function () {
50
+ let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
51
+ let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : guessTimeZoneId();
52
+ const zonedMoment = getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
53
+ const localMoment = moment([zonedMoment.year(), zonedMoment.month(), zonedMoment.date(), zonedMoment.hour(), zonedMoment.minute(), zonedMoment.second(), zonedMoment.millisecond()]);
54
+ return localMoment;
95
55
  };
96
- exports.getLocalMomentFromUtc = getLocalMomentFromUtc;
97
- const getLocalDateTimeFromUtc = (dateTimeUtc) => {
98
- return (0, exports.getLocalMomentFromUtc)(dateTimeUtc).toDate();
56
+ export const getLocalDateTimeFromUtc = dateTimeUtc => {
57
+ return getLocalMomentFromUtc(dateTimeUtc).toDate();
99
58
  };
100
- exports.getLocalDateTimeFromUtc = getLocalDateTimeFromUtc;
101
- const getDateMinusTime = (dateTime) => {
102
- return new Date(dateTime.getFullYear(), dateTime.getMonth(), dateTime.getDate());
59
+ export const getDateMinusTime = dateTime => {
60
+ return new Date(dateTime.getFullYear(), dateTime.getMonth(), dateTime.getDate());
103
61
  };
104
- exports.getDateMinusTime = getDateMinusTime;
105
- function getEndOfDay(dateTimeUtc) {
106
- return (0, moment_timezone_1.default)(dateTimeUtc)
107
- .startOf('day')
108
- .add(1, 'days')
109
- .subtract(3, 'milliseconds') // must be minus 3 for SQL date
110
- .toDate();
62
+ export function getEndOfDay(dateTimeUtc) {
63
+ return moment(dateTimeUtc).startOf('day').add(1, 'days').subtract(3, 'milliseconds') // must be minus 3 for SQL date
64
+ .toDate();
111
65
  }
112
- function getEndOfMinute(dateTimeUtc) {
113
- return (0, moment_timezone_1.default)(dateTimeUtc)
114
- .startOf('minute')
115
- .add(1, 'minute')
116
- .subtract(3, 'milliseconds') // must be minus 3 for SQL date
117
- .toDate();
66
+ export function getEndOfMinute(dateTimeUtc) {
67
+ return moment(dateTimeUtc).startOf('minute').add(1, 'minute').subtract(3, 'milliseconds') // must be minus 3 for SQL date
68
+ .toDate();
118
69
  }
70
+
119
71
  /**
120
72
  * Is the current time, "now", **after or equal to** the given date.
121
73
  *
@@ -124,14 +76,16 @@ function getEndOfMinute(dateTimeUtc) {
124
76
  *
125
77
  * @returns Whether or not "now" is **after or equal to** `dateTimeUtc`
126
78
  */
127
- function isNowEqualOrAfterDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
128
- if (!dateTimeUtc) {
129
- return false;
130
- }
131
- const adjustedDateTimeMoment = (0, exports.getLocalMomentFromUtc)(dateTimeUtc);
132
- const currentMoment = (0, exports.getLocalMomentFromUtc)(nowUtc);
133
- return currentMoment.isSameOrAfter(adjustedDateTimeMoment);
79
+ export function isNowEqualOrAfterDate(dateTimeUtc) {
80
+ let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
81
+ if (!dateTimeUtc) {
82
+ return false;
83
+ }
84
+ const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
85
+ const currentMoment = getLocalMomentFromUtc(nowUtc);
86
+ return currentMoment.isSameOrAfter(adjustedDateTimeMoment);
134
87
  }
88
+
135
89
  /**
136
90
  * Is the current time, "now", **before or equal to** the given date.
137
91
  *
@@ -140,14 +94,16 @@ function isNowEqualOrAfterDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc
140
94
  *
141
95
  * @returns Whether or not "now" is **before or equal to** `dateTimeUtc`.
142
96
  */
143
- function isNowEqualOrBeforeDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
144
- if (!dateTimeUtc) {
145
- return false;
146
- }
147
- const adjustedDateTimeMoment = (0, exports.getLocalMomentFromUtc)(dateTimeUtc);
148
- const currentMoment = (0, exports.getLocalMomentFromUtc)(nowUtc);
149
- return currentMoment.isSameOrBefore(adjustedDateTimeMoment);
97
+ export function isNowEqualOrBeforeDate(dateTimeUtc) {
98
+ let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
99
+ if (!dateTimeUtc) {
100
+ return false;
101
+ }
102
+ const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
103
+ const currentMoment = getLocalMomentFromUtc(nowUtc);
104
+ return currentMoment.isSameOrBefore(adjustedDateTimeMoment);
150
105
  }
106
+
151
107
  /**
152
108
  * Is the current time, "now", **after** the given date.
153
109
  *
@@ -156,14 +112,16 @@ function isNowEqualOrBeforeDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUt
156
112
  *
157
113
  * @returns Whether or not "now" is **after** `dateTimeUtc`.
158
114
  */
159
- function isNowAfterDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
160
- if (!dateTimeUtc) {
161
- return false;
162
- }
163
- const adjustedDateTimeMoment = (0, exports.getLocalMomentFromUtc)(dateTimeUtc);
164
- const currentMoment = (0, exports.getLocalMomentFromUtc)(nowUtc);
165
- return currentMoment > adjustedDateTimeMoment;
115
+ export function isNowAfterDate(dateTimeUtc) {
116
+ let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
117
+ if (!dateTimeUtc) {
118
+ return false;
119
+ }
120
+ const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
121
+ const currentMoment = getLocalMomentFromUtc(nowUtc);
122
+ return currentMoment > adjustedDateTimeMoment;
166
123
  }
124
+
167
125
  /**
168
126
  * Is the current time, "now", **before** the given date.
169
127
  *
@@ -172,139 +130,162 @@ function isNowAfterDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toI
172
130
  *
173
131
  * @returns Whether or not "now" is **before** `dateTimeUtc`.
174
132
  */
175
- function isNowBeforeDate(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
176
- if (!dateTimeUtc) {
177
- return false;
178
- }
179
- const adjustedDateTimeMoment = (0, exports.getLocalMomentFromUtc)(dateTimeUtc);
180
- const currentMoment = (0, exports.getLocalMomentFromUtc)(nowUtc);
181
- return currentMoment < adjustedDateTimeMoment;
133
+ export function isNowBeforeDate(dateTimeUtc) {
134
+ let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
135
+ if (!dateTimeUtc) {
136
+ return false;
137
+ }
138
+ const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
139
+ const currentMoment = getLocalMomentFromUtc(nowUtc);
140
+ return currentMoment < adjustedDateTimeMoment;
182
141
  }
142
+
183
143
  /**
184
144
  * Returns a date and time string with full date, e.g. `March 5, 2018 @ 4:05 PM EDT`
185
145
  * @param dateTimeUtc A UTC date time string
186
146
  * @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
187
147
  */
188
- function getFormattedFullDateAndTime(dateTimeUtc, withTimeZone = true) {
189
- return applyFormat(dateTimeUtc, `MMMM D, YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
148
+ export function getFormattedFullDateAndTime(dateTimeUtc) {
149
+ let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
150
+ return applyFormat(dateTimeUtc, `MMMM D, YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
190
151
  }
152
+
191
153
  /**
192
154
  * Returns a date and time string with day of week and American slash dates, e.g. `Mon, 3/5/2018 @ 4:05 PM EDT`
193
155
  * @param dateTimeUtc A UTC date time string
194
156
  * @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
195
157
  */
196
- function getFormattedFullDateWithWeek(dateTimeUtc, withTimeZone = true) {
197
- return applyFormat(dateTimeUtc, `ddd, M/D/YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
158
+ export function getFormattedFullDateWithWeek(dateTimeUtc) {
159
+ let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
160
+ return applyFormat(dateTimeUtc, `ddd, M/D/YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
198
161
  }
162
+
199
163
  /**
200
164
  * Returns a date and time string with American slash dates, and no leading zeroes, e.g. `3/5/18 4:05 PM EDT`
201
165
  * @param dateTimeUtc A UTC date time string
202
166
  * @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
203
167
  */
204
- function getFormattedNumberedDateAndTime(dateTimeUtc, withTimeZone = true) {
205
- return applyFormat(dateTimeUtc, `M/D/YY h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
168
+ export function getFormattedNumberedDateAndTime(dateTimeUtc) {
169
+ let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
170
+ return applyFormat(dateTimeUtc, `M/D/YY h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
206
171
  }
172
+
207
173
  /**
208
174
  * Returns a date and time string with American slash dates, no leading zeroes, and no year, e.g. `3/5 4:05 PM EDT`
209
175
  * @param dateTimeUtc A UTC date time string
210
176
  * @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
211
177
  */
212
- function getFormattedNumberedDateAndTimeWithoutYear(dateTimeUtc, withTimeZone = true) {
213
- return applyFormat(dateTimeUtc, `M/D h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
178
+ export function getFormattedNumberedDateAndTimeWithoutYear(dateTimeUtc) {
179
+ let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
180
+ return applyFormat(dateTimeUtc, `M/D h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
214
181
  }
182
+
215
183
  /**
216
184
  * Returns a date string with short month and full year, e.g. `Mar 5, 2018`
217
185
  * @param dateTimeUtc A UTC date time string
218
186
  */
219
- function getFormattedSimplifiedDate(dateTimeUtc) {
220
- return applyFormat(dateTimeUtc, 'MMM D, YYYY');
187
+ export function getFormattedSimplifiedDate(dateTimeUtc) {
188
+ return applyFormat(dateTimeUtc, 'MMM D, YYYY');
221
189
  }
190
+
222
191
  /**
223
192
  * Returns a date string with short month and no year, e.g. `Mar 5`
224
193
  * @param dateTimeUtc A UTC date time string
225
194
  */
226
- function getFormattedSimplifiedDateWithoutYear(dateTimeUtc) {
227
- return applyFormat(dateTimeUtc, 'MMM D');
195
+ export function getFormattedSimplifiedDateWithoutYear(dateTimeUtc) {
196
+ return applyFormat(dateTimeUtc, 'MMM D');
228
197
  }
198
+
229
199
  /**
230
200
  * Returns a date string as either 'MMM D, YYYY' or 'MMM D' if the date's year is the same as the current year
231
201
  * @param dateTimeUtc A UTC date time string
232
202
  * @param nowUtc (optional) A UTC date time string of "now". Used for testing.
233
203
  */
234
- function getFormattedSimplifiedDateWithYearIfNotCurrent(dateTimeUtc, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
235
- const nowUtcMoment = (0, moment_timezone_1.default)(nowUtc);
236
- const dateTimeMoment = (0, moment_timezone_1.default)(dateTimeUtc);
237
- return Math.abs(nowUtcMoment.year() - dateTimeMoment.year()) === 0
238
- ? getFormattedSimplifiedDateWithoutYear(dateTimeUtc)
239
- : getFormattedSimplifiedDate(dateTimeUtc);
204
+ export function getFormattedSimplifiedDateWithYearIfNotCurrent(dateTimeUtc) {
205
+ let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
206
+ const nowUtcMoment = moment(nowUtc);
207
+ const dateTimeMoment = moment(dateTimeUtc);
208
+ return Math.abs(nowUtcMoment.year() - dateTimeMoment.year()) === 0 ? getFormattedSimplifiedDateWithoutYear(dateTimeUtc) : getFormattedSimplifiedDate(dateTimeUtc);
240
209
  }
210
+
241
211
  /**
242
212
  * Returns a date string with American slash dates, no leading zeroes, and short year, e.g. `3/5/18`
243
213
  * @param dateTimeUtc A UTC date time string
244
214
  */
245
- function getFormattedNumberedDate(dateTimeUtc) {
246
- return applyFormat(dateTimeUtc, 'M/D/YY');
215
+ export function getFormattedNumberedDate(dateTimeUtc) {
216
+ return applyFormat(dateTimeUtc, 'M/D/YY');
247
217
  }
218
+
248
219
  /**
249
220
  * Returns a date string with American slash dates, no leading zeroes, and full year, e.g. `3/5/2018`
250
221
  * @param dateTimeUtc A UTC date time string
251
222
  */
252
- function getFormattedNumberedDateWithFullYear(dateTimeUtc) {
253
- return applyFormat(dateTimeUtc, 'M/D/YYYY');
223
+ export function getFormattedNumberedDateWithFullYear(dateTimeUtc) {
224
+ return applyFormat(dateTimeUtc, 'M/D/YYYY');
254
225
  }
226
+
255
227
  /**
256
228
  * Returns a date string for use in HTML inputs, e.g. `2018-03-05`
257
229
  * @param dateTimeUtc A UTC date time string
258
230
  */
259
- function getFormattedNumberedDateForInput(dateTimeUtc) {
260
- return applyFormat(dateTimeUtc, 'YYYY-MM-DD');
231
+ export function getFormattedNumberedDateForInput(dateTimeUtc) {
232
+ return applyFormat(dateTimeUtc, 'YYYY-MM-DD');
261
233
  }
234
+
262
235
  /**
263
236
  * Returns a date string with American slash dates and no year and no leading zeroes, e.g. `3/5`
264
237
  * @param dateTimeUtc A UTC date time string
265
238
  */
266
- function getFormattedNumberedDateWithoutYear(dateTimeUtc) {
267
- return applyFormat(dateTimeUtc, 'M/D');
239
+ export function getFormattedNumberedDateWithoutYear(dateTimeUtc) {
240
+ return applyFormat(dateTimeUtc, 'M/D');
268
241
  }
242
+
269
243
  /**
270
244
  * Returns a time string, e.g. `4:05 PM EDT`
271
245
  * @param dateTimeUtc A UTC date time string
272
246
  * @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
273
247
  */
274
- function getFormattedNumberedTime(dateTimeUtc, withTimeZone = true) {
275
- return applyFormat(dateTimeUtc, `h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
248
+ export function getFormattedNumberedTime(dateTimeUtc) {
249
+ let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
250
+ return applyFormat(dateTimeUtc, `h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
276
251
  }
252
+
277
253
  /**
278
254
  * Returns a time string with possibly full time zone name, e.g. `4:05 PM EDT` or `4:05 PM CST (Asia/Taipei)`
279
255
  * @param dateTimeUtc A UTC date time string
280
256
  * @param showEasternZoneId (optional) Whether or not to include the timeZoneId in the result for EST/EDT. Defaults to `false`.
281
257
  * @param timeZoneId (optional) A time zone Id. Defaults to the current time zone id, using `guessTimeZoneId()`.
282
258
  */
283
- function getFormattedNumberedTimeWithFullZone(dateTimeUtc, showEasternZoneId = false, timeZoneId = (0, timezone_1.guessTimeZoneId)()) {
284
- const zonedMoment = (0, exports.getZonedMomentFromUtc)(dateTimeUtc, timeZoneId);
285
- const time = applyFormat(dateTimeUtc, 'h:mm\u00a0A', timeZoneId);
286
- const timezoneAbbreviation = zonedMoment.zoneAbbr();
287
- return (timezoneAbbreviation === 'EDT' || timezoneAbbreviation === 'EST') && !showEasternZoneId
288
- ? // Don't show the full zone name if in EDT or EST, unless told to
289
- `${time} ${timezoneAbbreviation}`
290
- : // If not EDT or EST, show the zone name, replacing underscores with spaces
291
- // Ex: "Asia/Taipei"
292
- `${time} ${timezoneAbbreviation} (${timeZoneId.replace('_', ' ')})`;
259
+ export function getFormattedNumberedTimeWithFullZone(dateTimeUtc) {
260
+ let showEasternZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
261
+ let timeZoneId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : guessTimeZoneId();
262
+ const zonedMoment = getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
263
+ const time = applyFormat(dateTimeUtc, 'h:mm\u00a0A', timeZoneId);
264
+ const timezoneAbbreviation = zonedMoment.zoneAbbr();
265
+ return (timezoneAbbreviation === 'EDT' || timezoneAbbreviation === 'EST') && !showEasternZoneId ?
266
+ // Don't show the full zone name if in EDT or EST, unless told to
267
+ `${time} ${timezoneAbbreviation}` :
268
+ // If not EDT or EST, show the zone name, replacing underscores with spaces
269
+ // Ex: "Asia/Taipei"
270
+ `${time} ${timezoneAbbreviation} (${timeZoneId.replace('_', ' ')})`;
293
271
  }
272
+
294
273
  /**
295
274
  * Returns a time string without time zone, e.g. `4:05 PM`
296
275
  * @param dateTimeUtc A UTC date time string
297
276
  */
298
- function getFormattedNumberedTimeWithoutZone(dateTimeUtc) {
299
- return applyFormat(dateTimeUtc, 'h:mm\u00a0A');
277
+ export function getFormattedNumberedTimeWithoutZone(dateTimeUtc) {
278
+ return applyFormat(dateTimeUtc, 'h:mm\u00a0A');
300
279
  }
280
+
301
281
  /**
302
282
  * Returns a time string without time zone, in 24 hr time, e.g. `16:05`
303
283
  * @param dateTimeUtc A UTC date time string
304
284
  */
305
- function getFormattedNumberedTimeWithoutZoneOrMeridian(dateTimeUtc) {
306
- return applyFormat(dateTimeUtc, 'HH:mm');
285
+ export function getFormattedNumberedTimeWithoutZoneOrMeridian(dateTimeUtc) {
286
+ return applyFormat(dateTimeUtc, 'HH:mm');
307
287
  }
288
+
308
289
  /**
309
290
  * Returns a full formatted time zone string for the given `timeZoneId`.
310
291
  *
@@ -316,62 +297,64 @@ function getFormattedNumberedTimeWithoutZoneOrMeridian(dateTimeUtc) {
316
297
  * @param showEasternZoneId (optional) Whether or not to include the timeZoneId in the result for EST/EDT. Defaults to `false`.
317
298
  * @param nowUtc (optional) The current time, "now", as an ISO date string.
318
299
  */
319
- function getFullFormattedTimeZone(timeZoneId = (0, timezone_1.guessTimeZoneId)(), showEasternZoneId = false, nowUtc = (0, exports.getServerNowUtc)().toISOString()) {
320
- const zone = moment_timezone_1.default.tz.zone(timeZoneId);
321
- if (!zone)
322
- return '';
323
- const zonedMoment = (0, exports.getZonedMomentFromUtc)(nowUtc, timeZoneId);
324
- // filter the zone data down to just recent years, instead of the default of 1900 to 2038
325
- const filteredZone = moment_timezone_utils_1.default.tz.filterYears(zone, zonedMoment.year() - 1, zonedMoment.year() + 1);
326
- // find all unique abbreviations for the zone, combined into a string
327
- const abbreviations = filteredZone.abbrs
328
- // filter out non-alpha abbreviations
329
- .filter(abbr => /[a-zA-Z]+/g.test(abbr))
330
- .reduce((uniqueAbbrs, abbr) => {
331
- if (!uniqueAbbrs.includes(abbr)) {
332
- uniqueAbbrs.push(abbr);
333
- }
334
- return uniqueAbbrs;
335
- }, []);
336
- const abbreviationsString = abbreviations.length > 0 ? abbreviations.join('/') : null;
337
- const readableZoneId = timeZoneId.replace('_', ' ');
338
- return !abbreviationsString
339
- ? readableZoneId
340
- : abbreviationsString === 'EST/EDT' && !showEasternZoneId
341
- ? // Don't show the zoneId if in Eastern, unless told to
342
- abbreviationsString
343
- : // Show the combined abbreviations plus the friendly zoneId
344
- `${abbreviationsString} (${readableZoneId})`;
300
+ export function getFullFormattedTimeZone() {
301
+ let timeZoneId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : guessTimeZoneId();
302
+ let showEasternZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
303
+ let nowUtc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getServerNowUtc().toISOString();
304
+ const zone = moment.tz.zone(timeZoneId);
305
+ if (!zone) return '';
306
+ const zonedMoment = getZonedMomentFromUtc(nowUtc, timeZoneId);
307
+ // filter the zone data down to just recent years, instead of the default of 1900 to 2038
308
+ const filteredZone = momentUtils.tz.filterYears(zone, zonedMoment.year() - 1, zonedMoment.year() + 1);
309
+ // find all unique abbreviations for the zone, combined into a string
310
+ const abbreviations = filteredZone.abbrs
311
+ // filter out non-alpha abbreviations
312
+ .filter(abbr => /[a-zA-Z]+/g.test(abbr)).reduce((uniqueAbbrs, abbr) => {
313
+ if (!uniqueAbbrs.includes(abbr)) {
314
+ uniqueAbbrs.push(abbr);
315
+ }
316
+ return uniqueAbbrs;
317
+ }, []);
318
+ const abbreviationsString = abbreviations.length > 0 ? abbreviations.join('/') : null;
319
+ const readableZoneId = timeZoneId.replace('_', ' ');
320
+ return !abbreviationsString ? readableZoneId : abbreviationsString === 'EST/EDT' && !showEasternZoneId ?
321
+ // Don't show the zoneId if in Eastern, unless told to
322
+ abbreviationsString :
323
+ // Show the combined abbreviations plus the friendly zoneId
324
+ `${abbreviationsString} (${readableZoneId})`;
345
325
  }
326
+
346
327
  /**
347
328
  * Returns the basic time zone abbreviation for the given date, e.g. `EDT`.
348
329
  *
349
330
  * @param dateTimeUtc The date to format.
350
331
  */
351
- function getFormattedTimeZone(dateTimeUtc) {
352
- return applyFormat(dateTimeUtc, 'z');
332
+ export function getFormattedTimeZone(dateTimeUtc) {
333
+ return applyFormat(dateTimeUtc, 'z');
353
334
  }
335
+
354
336
  /**
355
337
  * Formats a date using the given format. Parses the date as UTC, then converts to the current time zone, then formats.
356
338
  * @param {*} dateTimeUtc The date to format. Any valid input for `moment.utc(...)`
357
339
  * @param {*} format The format to use
358
340
  */
359
- function applyFormat(dateTimeUtc, format, timeZoneId = (0, timezone_1.guessTimeZoneId)()) {
360
- return (0, exports.getZonedMomentFromUtc)(dateTimeUtc, timeZoneId).format(format);
341
+ function applyFormat(dateTimeUtc, format) {
342
+ let timeZoneId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : guessTimeZoneId();
343
+ return getZonedMomentFromUtc(dateTimeUtc, timeZoneId).format(format);
361
344
  }
362
- const isInputTypeSupported = (type) => {
363
- try {
364
- const test = document.createElement('input');
365
- test.type = type;
366
- const isSupported = test.type === type;
367
- return isSupported;
368
- }
369
- catch (_a) {
370
- return false;
371
- }
345
+ const isInputTypeSupported = type => {
346
+ try {
347
+ const test = document.createElement('input');
348
+ test.type = type;
349
+ const isSupported = test.type === type;
350
+ return isSupported;
351
+ } catch {
352
+ return false;
353
+ }
372
354
  };
373
- exports.isDateInputSupported = isInputTypeSupported('date');
374
- exports.isTimeInputSupported = isInputTypeSupported('time');
375
- function isDateTimeValid(dateTime) {
376
- return !!dateTime && (0, moment_timezone_1.default)(dateTime).isValid();
355
+ export const isDateInputSupported = isInputTypeSupported('date');
356
+ export const isTimeInputSupported = isInputTypeSupported('time');
357
+ export function isDateTimeValid(dateTime) {
358
+ return !!dateTime && moment(dateTime).isValid();
377
359
  }
360
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJtb21lbnQiLCJtb21lbnRVdGlscyIsImdldERlZmF1bHRUaW1lWm9uZUlkIiwiZ3Vlc3NUaW1lWm9uZUlkIiwiY2xvY2tPZmZzZXQiLCJzZXRDbG9ja09mZnNldCIsIm9mZnNldCIsImdldFNlcnZlck5vd1V0YyIsIkRhdGUiLCJub3ciLCJnZXRPZmZzZXREYXRlIiwiZGF0ZSIsImdldFRpbWUiLCJnZXRab25lZE1vbWVudEZyb21VdGMiLCJkYXRlVGltZVV0YyIsImFyZ3VtZW50cyIsImxlbmd0aCIsInVuZGVmaW5lZCIsInRvSVNPU3RyaW5nIiwidGltZVpvbmVJZCIsInV0YyIsInR6IiwiZ2V0Wm9uZWRNb21lbnRGcm9tVXRjSW5EZWZhdWx0Wm9uZSIsImdldFpvbmVkTW9tZW50RnJvbUxvY2FsRGF0ZVRpbWUiLCJsb2NhbERhdGVUaW1lIiwibG9jYWxNb21lbnQiLCJ6b25lZE1vbWVudCIsInllYXIiLCJtb250aCIsImhvdXIiLCJtaW51dGUiLCJzZWNvbmQiLCJtaWxsaXNlY29uZCIsImdldExvY2FsTW9tZW50RnJvbVV0YyIsImdldExvY2FsRGF0ZVRpbWVGcm9tVXRjIiwidG9EYXRlIiwiZ2V0RGF0ZU1pbnVzVGltZSIsImRhdGVUaW1lIiwiZ2V0RnVsbFllYXIiLCJnZXRNb250aCIsImdldERhdGUiLCJnZXRFbmRPZkRheSIsInN0YXJ0T2YiLCJhZGQiLCJzdWJ0cmFjdCIsImdldEVuZE9mTWludXRlIiwiaXNOb3dFcXVhbE9yQWZ0ZXJEYXRlIiwibm93VXRjIiwiYWRqdXN0ZWREYXRlVGltZU1vbWVudCIsImN1cnJlbnRNb21lbnQiLCJpc1NhbWVPckFmdGVyIiwiaXNOb3dFcXVhbE9yQmVmb3JlRGF0ZSIsImlzU2FtZU9yQmVmb3JlIiwiaXNOb3dBZnRlckRhdGUiLCJpc05vd0JlZm9yZURhdGUiLCJnZXRGb3JtYXR0ZWRGdWxsRGF0ZUFuZFRpbWUiLCJ3aXRoVGltZVpvbmUiLCJhcHBseUZvcm1hdCIsImdldEZvcm1hdHRlZEZ1bGxEYXRlV2l0aFdlZWsiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZERhdGVBbmRUaW1lIiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlQW5kVGltZVdpdGhvdXRZZWFyIiwiZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGUiLCJnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZVdpdGhvdXRZZWFyIiwiZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGVXaXRoWWVhcklmTm90Q3VycmVudCIsIm5vd1V0Y01vbWVudCIsImRhdGVUaW1lTW9tZW50IiwiTWF0aCIsImFicyIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZSIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZVdpdGhGdWxsWWVhciIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZUZvcklucHV0IiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlV2l0aG91dFllYXIiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZFRpbWUiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZFRpbWVXaXRoRnVsbFpvbmUiLCJzaG93RWFzdGVyblpvbmVJZCIsInRpbWUiLCJ0aW1lem9uZUFiYnJldmlhdGlvbiIsInpvbmVBYmJyIiwicmVwbGFjZSIsImdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhvdXRab25lIiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWRUaW1lV2l0aG91dFpvbmVPck1lcmlkaWFuIiwiZ2V0RnVsbEZvcm1hdHRlZFRpbWVab25lIiwiem9uZSIsImZpbHRlcmVkWm9uZSIsImZpbHRlclllYXJzIiwiYWJicmV2aWF0aW9ucyIsImFiYnJzIiwiZmlsdGVyIiwiYWJiciIsInRlc3QiLCJyZWR1Y2UiLCJ1bmlxdWVBYmJycyIsImluY2x1ZGVzIiwicHVzaCIsImFiYnJldmlhdGlvbnNTdHJpbmciLCJqb2luIiwicmVhZGFibGVab25lSWQiLCJnZXRGb3JtYXR0ZWRUaW1lWm9uZSIsImZvcm1hdCIsImlzSW5wdXRUeXBlU3VwcG9ydGVkIiwidHlwZSIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsImlzU3VwcG9ydGVkIiwiaXNEYXRlSW5wdXRTdXBwb3J0ZWQiLCJpc1RpbWVJbnB1dFN1cHBvcnRlZCIsImlzRGF0ZVRpbWVWYWxpZCIsImlzVmFsaWQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvZGF0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSdcbmltcG9ydCBtb21lbnRVdGlscyBmcm9tICdtb21lbnQtdGltZXpvbmUvbW9tZW50LXRpbWV6b25lLXV0aWxzJ1xuaW1wb3J0IHsgZ2V0RGVmYXVsdFRpbWVab25lSWQsIGd1ZXNzVGltZVpvbmVJZCB9IGZyb20gJy4vdGltZXpvbmUnXG5cbi8qKlxuICogVGhpcyB2YWx1ZSBpcyB1c2VkIGJ5IHRpbWUtc2Vuc2l0aXZlIGZ1bmN0aW9ucyBpbiB0aGlzIG1vZHVsZSBhbmQgb3RoZXIgZGF0ZS90aW1lIHV0aWxzLiBBbnkgdGltZVxuICogYSBuZXcgRGF0ZSBvYmplY3QgaXMgY29uc3RydWN0ZWQsIGl0IHdpbGwgdXNlIHRoaXMgdmFsdWUgdG8gYWRqdXN0IHRoZSB0aW1lIGJ5IHRoaXMgb2Zmc2V0ICh0b1xuICogbWFrZSBpdCBjb25zaXN0ZW50IHdpdGggYSBrbm93biB0aW1lKVxuICovXG5sZXQgY2xvY2tPZmZzZXQgPSAwXG5cbi8qKlxuICogV2hlbiBhIEdyb3VwQXNzZXNzbWVudCBjb21lcyBpbiB0aGUgZG9vciwgaXQgaW5jbHVkZXMgdGhlIGN1cnJlbnQgVVRDIGRhdGV0aW1lLiBUaGlzIG1ldGhvZCBpc1xuICogdXNlZCB0byB1cGRhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgKGFjY3VyYXRlKSBzZXJ2ZXIgdGltZSBhbmQgdGhlIGJyb3dzZXIgdGltZVxuICovXG5leHBvcnQgY29uc3Qgc2V0Q2xvY2tPZmZzZXQgPSBmdW5jdGlvbiAob2Zmc2V0OiBudW1iZXIpIHtcblx0Y2xvY2tPZmZzZXQgPSBvZmZzZXRcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgVVRDIHRpbWUsIGNhbGlicmF0ZWQgdG8gdGhlIEFQSSBzZXJ2ZXIncyBjbG9ja1xuICovXG5leHBvcnQgY29uc3QgZ2V0U2VydmVyTm93VXRjID0gZnVuY3Rpb24gKCkge1xuXHRyZXR1cm4gbmV3IERhdGUoRGF0ZS5ub3coKSArIGNsb2NrT2Zmc2V0KVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgcHJvdmlkZWQgZGF0ZSwgb2Zmc2V0IGJ5IHRoZSBjbG9ja09mZnNldFxuICovXG5leHBvcnQgY29uc3QgZ2V0T2Zmc2V0RGF0ZSA9IChkYXRlOiBEYXRlKSA9PiB7XG5cdHJldHVybiBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSArIGNsb2NrT2Zmc2V0KVxufVxuXG5leHBvcnQgY29uc3QgZ2V0Wm9uZWRNb21lbnRGcm9tVXRjID0gKFxuXHRkYXRlVGltZVV0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCksXG5cdHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKVxuKSA9PiB7XG5cdHJldHVybiBtb21lbnQudXRjKGRhdGVUaW1lVXRjKS50eih0aW1lWm9uZUlkKVxufVxuXG5leHBvcnQgY29uc3QgZ2V0Wm9uZWRNb21lbnRGcm9tVXRjSW5EZWZhdWx0Wm9uZSA9IChkYXRlVGltZVV0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCkpID0+IHtcblx0Y29uc3QgdGltZVpvbmVJZCA9IGdldERlZmF1bHRUaW1lWm9uZUlkKClcblx0cmV0dXJuIGdldFpvbmVkTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YywgdGltZVpvbmVJZClcbn1cblxuZXhwb3J0IGNvbnN0IGdldFpvbmVkTW9tZW50RnJvbUxvY2FsRGF0ZVRpbWUgPSAobG9jYWxEYXRlVGltZTogRGF0ZSB8IHN0cmluZywgdGltZVpvbmVJZCA9IGd1ZXNzVGltZVpvbmVJZCgpKSA9PiB7XG5cdGNvbnN0IGxvY2FsTW9tZW50ID0gbW9tZW50KGxvY2FsRGF0ZVRpbWUpXG5cdGNvbnN0IHpvbmVkTW9tZW50ID0gbW9tZW50LnR6KFxuXHRcdFtcblx0XHRcdGxvY2FsTW9tZW50LnllYXIoKSxcblx0XHRcdGxvY2FsTW9tZW50Lm1vbnRoKCksXG5cdFx0XHRsb2NhbE1vbWVudC5kYXRlKCksXG5cdFx0XHRsb2NhbE1vbWVudC5ob3VyKCksXG5cdFx0XHRsb2NhbE1vbWVudC5taW51dGUoKSxcblx0XHRcdGxvY2FsTW9tZW50LnNlY29uZCgpLFxuXHRcdFx0bG9jYWxNb21lbnQubWlsbGlzZWNvbmQoKVxuXHRcdF0sXG5cdFx0dGltZVpvbmVJZFxuXHQpXG5cdHJldHVybiB6b25lZE1vbWVudFxufVxuXG5leHBvcnQgY29uc3QgZ2V0TG9jYWxNb21lbnRGcm9tVXRjID0gKFxuXHRkYXRlVGltZVV0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCksXG5cdHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKVxuKSA9PiB7XG5cdGNvbnN0IHpvbmVkTW9tZW50ID0gZ2V0Wm9uZWRNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjLCB0aW1lWm9uZUlkKVxuXHRjb25zdCBsb2NhbE1vbWVudCA9IG1vbWVudChbXG5cdFx0em9uZWRNb21lbnQueWVhcigpLFxuXHRcdHpvbmVkTW9tZW50Lm1vbnRoKCksXG5cdFx0em9uZWRNb21lbnQuZGF0ZSgpLFxuXHRcdHpvbmVkTW9tZW50LmhvdXIoKSxcblx0XHR6b25lZE1vbWVudC5taW51dGUoKSxcblx0XHR6b25lZE1vbWVudC5zZWNvbmQoKSxcblx0XHR6b25lZE1vbWVudC5taWxsaXNlY29uZCgpXG5cdF0pXG5cdHJldHVybiBsb2NhbE1vbWVudFxufVxuXG5leHBvcnQgY29uc3QgZ2V0TG9jYWxEYXRlVGltZUZyb21VdGMgPSAoZGF0ZVRpbWVVdGM6IHN0cmluZykgPT4ge1xuXHRyZXR1cm4gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjKS50b0RhdGUoKVxufVxuXG5leHBvcnQgY29uc3QgZ2V0RGF0ZU1pbnVzVGltZSA9IChkYXRlVGltZTogRGF0ZSkgPT4ge1xuXHRyZXR1cm4gbmV3IERhdGUoZGF0ZVRpbWUuZ2V0RnVsbFllYXIoKSwgZGF0ZVRpbWUuZ2V0TW9udGgoKSwgZGF0ZVRpbWUuZ2V0RGF0ZSgpKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW5kT2ZEYXkoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gbW9tZW50KGRhdGVUaW1lVXRjKVxuXHRcdC5zdGFydE9mKCdkYXknKVxuXHRcdC5hZGQoMSwgJ2RheXMnKVxuXHRcdC5zdWJ0cmFjdCgzLCAnbWlsbGlzZWNvbmRzJykgLy8gbXVzdCBiZSBtaW51cyAzIGZvciBTUUwgZGF0ZVxuXHRcdC50b0RhdGUoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW5kT2ZNaW51dGUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gbW9tZW50KGRhdGVUaW1lVXRjKVxuXHRcdC5zdGFydE9mKCdtaW51dGUnKVxuXHRcdC5hZGQoMSwgJ21pbnV0ZScpXG5cdFx0LnN1YnRyYWN0KDMsICdtaWxsaXNlY29uZHMnKSAvLyBtdXN0IGJlIG1pbnVzIDMgZm9yIFNRTCBkYXRlXG5cdFx0LnRvRGF0ZSgpXG59XG5cbi8qKlxuICogSXMgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgKiphZnRlciBvciBlcXVhbCB0byoqIHRoZSBnaXZlbiBkYXRlLlxuICpcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBUaGUgZGF0ZSB0byBjb21wYXJlIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsIGFzIGFuIElTTyBkYXRlIHN0cmluZy5cbiAqIEBwYXJhbSBub3dVdGMgT3B0aW9uYWwuIFRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsIGFzIGFuIElTTyBkYXRlIHN0cmluZy5cbiAqXG4gKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCBcIm5vd1wiIGlzICoqYWZ0ZXIgb3IgZXF1YWwgdG8qKiBgZGF0ZVRpbWVVdGNgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vd0VxdWFsT3JBZnRlckRhdGUoZGF0ZVRpbWVVdGM/OiBzdHJpbmcsIG5vd1V0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCkpIHtcblx0aWYgKCFkYXRlVGltZVV0Yykge1xuXHRcdHJldHVybiBmYWxzZVxuXHR9XG5cdGNvbnN0IGFkanVzdGVkRGF0ZVRpbWVNb21lbnQgPSBnZXRMb2NhbE1vbWVudEZyb21VdGMoZGF0ZVRpbWVVdGMpXG5cdGNvbnN0IGN1cnJlbnRNb21lbnQgPSBnZXRMb2NhbE1vbWVudEZyb21VdGMobm93VXRjKVxuXHRyZXR1cm4gY3VycmVudE1vbWVudC5pc1NhbWVPckFmdGVyKGFkanVzdGVkRGF0ZVRpbWVNb21lbnQpXG59XG5cbi8qKlxuICogSXMgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgKipiZWZvcmUgb3IgZXF1YWwgdG8qKiB0aGUgZ2l2ZW4gZGF0ZS5cbiAqXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgVGhlIGRhdGUgdG8gY29tcGFyZSB0aGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCBhcyBhbiBJU08gZGF0ZSBzdHJpbmcuXG4gKiBAcGFyYW0gbm93VXRjIE9wdGlvbmFsLiBUaGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCBhcyBhbiBJU08gZGF0ZSBzdHJpbmcuXG4gKlxuICogQHJldHVybnMgV2hldGhlciBvciBub3QgXCJub3dcIiBpcyAqKmJlZm9yZSBvciBlcXVhbCB0byoqIGBkYXRlVGltZVV0Y2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vd0VxdWFsT3JCZWZvcmVEYXRlKGRhdGVUaW1lVXRjPzogc3RyaW5nLCBub3dVdGMgPSBnZXRTZXJ2ZXJOb3dVdGMoKS50b0lTT1N0cmluZygpKSB7XG5cdGlmICghZGF0ZVRpbWVVdGMpIHtcblx0XHRyZXR1cm4gZmFsc2Vcblx0fVxuXHRjb25zdCBhZGp1c3RlZERhdGVUaW1lTW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjKVxuXHRjb25zdCBjdXJyZW50TW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKG5vd1V0Yylcblx0cmV0dXJuIGN1cnJlbnRNb21lbnQuaXNTYW1lT3JCZWZvcmUoYWRqdXN0ZWREYXRlVGltZU1vbWVudClcbn1cblxuLyoqXG4gKiBJcyB0aGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCAqKmFmdGVyKiogdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIGRhdGVUaW1lVXRjIFRoZSBkYXRlIHRvIGNvbXBhcmUgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxuICogQHBhcmFtIG5vd1V0YyBPcHRpb25hbC4gVGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxuICpcbiAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IFwibm93XCIgaXMgKiphZnRlcioqIGBkYXRlVGltZVV0Y2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vd0FmdGVyRGF0ZShkYXRlVGltZVV0Yz86IHN0cmluZywgbm93VXRjID0gZ2V0U2VydmVyTm93VXRjKCkudG9JU09TdHJpbmcoKSkge1xuXHRpZiAoIWRhdGVUaW1lVXRjKSB7XG5cdFx0cmV0dXJuIGZhbHNlXG5cdH1cblx0Y29uc3QgYWRqdXN0ZWREYXRlVGltZU1vbWVudCA9IGdldExvY2FsTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0Yylcblx0Y29uc3QgY3VycmVudE1vbWVudCA9IGdldExvY2FsTW9tZW50RnJvbVV0Yyhub3dVdGMpXG5cdHJldHVybiBjdXJyZW50TW9tZW50ID4gYWRqdXN0ZWREYXRlVGltZU1vbWVudFxufVxuXG4vKipcbiAqIElzIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsICoqYmVmb3JlKiogdGhlIGdpdmVuIGRhdGUuXG4gKlxuICogQHBhcmFtIGRhdGVUaW1lVXRjIFRoZSBkYXRlIHRvIGNvbXBhcmUgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxuICogQHBhcmFtIG5vd1V0YyBPcHRpb25hbC4gVGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxuICpcbiAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IFwibm93XCIgaXMgKipiZWZvcmUqKiBgZGF0ZVRpbWVVdGNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb3dCZWZvcmVEYXRlKGRhdGVUaW1lVXRjPzogc3RyaW5nLCBub3dVdGMgPSBnZXRTZXJ2ZXJOb3dVdGMoKS50b0lTT1N0cmluZygpKSB7XG5cdGlmICghZGF0ZVRpbWVVdGMpIHtcblx0XHRyZXR1cm4gZmFsc2Vcblx0fVxuXHRjb25zdCBhZGp1c3RlZERhdGVUaW1lTW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjKVxuXHRjb25zdCBjdXJyZW50TW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKG5vd1V0Yylcblx0cmV0dXJuIGN1cnJlbnRNb21lbnQgPCBhZGp1c3RlZERhdGVUaW1lTW9tZW50XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgYW5kIHRpbWUgc3RyaW5nIHdpdGggZnVsbCBkYXRlLCBlLmcuIGBNYXJjaCA1LCAyMDE4IEAgNDowNSBQTSBFRFRgXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xuICogQHBhcmFtIHdpdGhUaW1lWm9uZSAob3B0aW9uYWwpIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgdGltZSB6b25lIGFiYnJldmlhdGlvbi4gRGVmYXVsdHMgdG8gYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkRnVsbERhdGVBbmRUaW1lKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCBgTU1NTSBELCBZWVlZIEAgaDptbVxcdTAwYTBBJHt3aXRoVGltZVpvbmUgPyAnIHonIDogJyd9YClcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBhbmQgdGltZSBzdHJpbmcgd2l0aCBkYXkgb2Ygd2VlayBhbmQgQW1lcmljYW4gc2xhc2ggZGF0ZXMsIGUuZy4gYE1vbiwgMy81LzIwMTggQCA0OjA1IFBNIEVEVGBcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXG4gKiBAcGFyYW0gd2l0aFRpbWVab25lIChvcHRpb25hbCkgV2hldGhlciB0byBpbmNsdWRlIHRoZSB0aW1lIHpvbmUgYWJicmV2aWF0aW9uLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWRGdWxsRGF0ZVdpdGhXZWVrKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCBgZGRkLCBNL0QvWVlZWSBAIGg6bW1cXHUwMGEwQSR7d2l0aFRpbWVab25lID8gJyB6JyA6ICcnfWApXG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgYW5kIHRpbWUgc3RyaW5nIHdpdGggQW1lcmljYW4gc2xhc2ggZGF0ZXMsIGFuZCBubyBsZWFkaW5nIHplcm9lcywgZS5nLiBgMy81LzE4IDQ6MDUgUE0gRURUYFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqIEBwYXJhbSB3aXRoVGltZVpvbmUgKG9wdGlvbmFsKSBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIHRpbWUgem9uZSBhYmJyZXZpYXRpb24uIERlZmF1bHRzIHRvIGB0cnVlYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZUFuZFRpbWUoZGF0ZVRpbWVVdGM6IHN0cmluZywgd2l0aFRpbWVab25lID0gdHJ1ZSkge1xuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsIGBNL0QvWVkgaDptbVxcdTAwYTBBJHt3aXRoVGltZVpvbmUgPyAnIHonIDogJyd9YClcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBhbmQgdGltZSBzdHJpbmcgd2l0aCBBbWVyaWNhbiBzbGFzaCBkYXRlcywgbm8gbGVhZGluZyB6ZXJvZXMsIGFuZCBubyB5ZWFyLCBlLmcuIGAzLzUgNDowNSBQTSBFRFRgXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xuICogQHBhcmFtIHdpdGhUaW1lWm9uZSAob3B0aW9uYWwpIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgdGltZSB6b25lIGFiYnJldmlhdGlvbi4gRGVmYXVsdHMgdG8gYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlQW5kVGltZVdpdGhvdXRZZWFyKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCBgTS9EIGg6bW1cXHUwMGEwQSR7d2l0aFRpbWVab25lID8gJyB6JyA6ICcnfWApXG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIHdpdGggc2hvcnQgbW9udGggYW5kIGZ1bGwgeWVhciwgZS5nLiBgTWFyIDUsIDIwMThgXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICdNTU0gRCwgWVlZWScpXG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIHdpdGggc2hvcnQgbW9udGggYW5kIG5vIHllYXIsIGUuZy4gYE1hciA1YFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZFNpbXBsaWZpZWREYXRlV2l0aG91dFllYXIoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICdNTU0gRCcpXG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIGFzIGVpdGhlciAnTU1NIEQsIFlZWVknIG9yICdNTU0gRCcgaWYgdGhlIGRhdGUncyB5ZWFyIGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IHllYXJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXG4gKiBAcGFyYW0gbm93VXRjIChvcHRpb25hbCkgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZyBvZiBcIm5vd1wiLiBVc2VkIGZvciB0ZXN0aW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGVXaXRoWWVhcklmTm90Q3VycmVudChcblx0ZGF0ZVRpbWVVdGM6IHN0cmluZyxcblx0bm93VXRjID0gZ2V0U2VydmVyTm93VXRjKCkudG9JU09TdHJpbmcoKVxuKSB7XG5cdGNvbnN0IG5vd1V0Y01vbWVudCA9IG1vbWVudChub3dVdGMpXG5cdGNvbnN0IGRhdGVUaW1lTW9tZW50ID0gbW9tZW50KGRhdGVUaW1lVXRjKVxuXHRyZXR1cm4gTWF0aC5hYnMobm93VXRjTW9tZW50LnllYXIoKSAtIGRhdGVUaW1lTW9tZW50LnllYXIoKSkgPT09IDBcblx0XHQ/IGdldEZvcm1hdHRlZFNpbXBsaWZpZWREYXRlV2l0aG91dFllYXIoZGF0ZVRpbWVVdGMpXG5cdFx0OiBnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZShkYXRlVGltZVV0Yylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBzdHJpbmcgd2l0aCBBbWVyaWNhbiBzbGFzaCBkYXRlcywgbm8gbGVhZGluZyB6ZXJvZXMsIGFuZCBzaG9ydCB5ZWFyLCBlLmcuIGAzLzUvMThgXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlKGRhdGVUaW1lVXRjOiBzdHJpbmcpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnTS9EL1lZJylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBzdHJpbmcgd2l0aCBBbWVyaWNhbiBzbGFzaCBkYXRlcywgbm8gbGVhZGluZyB6ZXJvZXMsIGFuZCBmdWxsIHllYXIsIGUuZy4gYDMvNS8yMDE4YFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZVdpdGhGdWxsWWVhcihkYXRlVGltZVV0Yzogc3RyaW5nKSB7XG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ00vRC9ZWVlZJylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBzdHJpbmcgZm9yIHVzZSBpbiBIVE1MIGlucHV0cywgZS5nLiBgMjAxOC0wMy0wNWBcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWROdW1iZXJlZERhdGVGb3JJbnB1dChkYXRlVGltZVV0Yzogc3RyaW5nKSB7XG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ1lZWVktTU0tREQnKVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBkYXRlIHN0cmluZyB3aXRoIEFtZXJpY2FuIHNsYXNoIGRhdGVzIGFuZCBubyB5ZWFyIGFuZCBubyBsZWFkaW5nIHplcm9lcywgZS5nLiBgMy81YFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZVdpdGhvdXRZZWFyKGRhdGVUaW1lVXRjOiBzdHJpbmcpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnTS9EJylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgdGltZSBzdHJpbmcsIGUuZy4gYDQ6MDUgUE0gRURUYFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqIEBwYXJhbSB3aXRoVGltZVpvbmUgKG9wdGlvbmFsKSBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIHRpbWUgem9uZSBhYmJyZXZpYXRpb24uIERlZmF1bHRzIHRvIGB0cnVlYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkVGltZShkYXRlVGltZVV0Yzogc3RyaW5nLCB3aXRoVGltZVpvbmUgPSB0cnVlKSB7XG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgYGg6bW1cXHUwMGEwQSR7d2l0aFRpbWVab25lID8gJyB6JyA6ICcnfWApXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHRpbWUgc3RyaW5nIHdpdGggcG9zc2libHkgZnVsbCB0aW1lIHpvbmUgbmFtZSwgZS5nLiBgNDowNSBQTSBFRFRgIG9yIGA0OjA1IFBNIENTVCAoQXNpYS9UYWlwZWkpYFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqIEBwYXJhbSBzaG93RWFzdGVyblpvbmVJZCAob3B0aW9uYWwpIFdoZXRoZXIgb3Igbm90IHRvIGluY2x1ZGUgdGhlIHRpbWVab25lSWQgaW4gdGhlIHJlc3VsdCBmb3IgRVNUL0VEVC4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAqIEBwYXJhbSB0aW1lWm9uZUlkIChvcHRpb25hbCkgQSB0aW1lIHpvbmUgSWQuIERlZmF1bHRzIHRvIHRoZSBjdXJyZW50IHRpbWUgem9uZSBpZCwgdXNpbmcgYGd1ZXNzVGltZVpvbmVJZCgpYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhGdWxsWm9uZShcblx0ZGF0ZVRpbWVVdGM6IHN0cmluZyxcblx0c2hvd0Vhc3Rlcm5ab25lSWQgPSBmYWxzZSxcblx0dGltZVpvbmVJZCA9IGd1ZXNzVGltZVpvbmVJZCgpXG4pIHtcblx0Y29uc3Qgem9uZWRNb21lbnQgPSBnZXRab25lZE1vbWVudEZyb21VdGMoZGF0ZVRpbWVVdGMsIHRpbWVab25lSWQpXG5cdGNvbnN0IHRpbWUgPSBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ2g6bW1cXHUwMGEwQScsIHRpbWVab25lSWQpXG5cdGNvbnN0IHRpbWV6b25lQWJicmV2aWF0aW9uID0gem9uZWRNb21lbnQuem9uZUFiYnIoKVxuXHRyZXR1cm4gKHRpbWV6b25lQWJicmV2aWF0aW9uID09PSAnRURUJyB8fCB0aW1lem9uZUFiYnJldmlhdGlvbiA9PT0gJ0VTVCcpICYmICFzaG93RWFzdGVyblpvbmVJZFxuXHRcdD8gLy8gRG9uJ3Qgc2hvdyB0aGUgZnVsbCB6b25lIG5hbWUgaWYgaW4gRURUIG9yIEVTVCwgdW5sZXNzIHRvbGQgdG9cblx0XHRcdGAke3RpbWV9ICR7dGltZXpvbmVBYmJyZXZpYXRpb259YFxuXHRcdDogLy8gSWYgbm90IEVEVCBvciBFU1QsIHNob3cgdGhlIHpvbmUgbmFtZSwgcmVwbGFjaW5nIHVuZGVyc2NvcmVzIHdpdGggc3BhY2VzXG5cdFx0XHQvLyBFeDogXCJBc2lhL1RhaXBlaVwiXG5cdFx0XHRgJHt0aW1lfSAke3RpbWV6b25lQWJicmV2aWF0aW9ufSAoJHt0aW1lWm9uZUlkLnJlcGxhY2UoJ18nLCAnICcpfSlgXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHRpbWUgc3RyaW5nIHdpdGhvdXQgdGltZSB6b25lLCBlLmcuIGA0OjA1IFBNYFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhvdXRab25lKGRhdGVUaW1lVXRjOiBzdHJpbmcpIHtcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnaDptbVxcdTAwYTBBJylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgdGltZSBzdHJpbmcgd2l0aG91dCB0aW1lIHpvbmUsIGluIDI0IGhyIHRpbWUsIGUuZy4gYDE2OjA1YFxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhvdXRab25lT3JNZXJpZGlhbihkYXRlVGltZVV0Yzogc3RyaW5nKSB7XG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ0hIOm1tJylcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVsbCBmb3JtYXR0ZWQgdGltZSB6b25lIHN0cmluZyBmb3IgdGhlIGdpdmVuIGB0aW1lWm9uZUlkYC5cbiAqXG4gKiBDb21iaW5lcyBhbGwgcG9zc2libGUgYWJicmV2aWF0aW9ucyBmb3IgdGhlIHpvbmUgYW5kIHRoZSB0aW1lWm9uZUlkLCBlLmcuIGBFU1QvRURUYCwgYFBTVC9QRFQgKEFtZXJpY2EvTG9zIEFuZ2VsZXMpYCBvciBgQ1NUIChBc2lhL1RhaXBlaSlgXG4gKlxuICogSWYgYWJicmV2aWF0aW9ucyBhcmUgbm90IGFscGhhIGNoYXJhY3RlcnMsIGUuZy4gYC0wNGAsIHRoZW4gb25seSB0aGUgdGltZVpvbmVJZCBpcyByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0gdGltZVpvbmVJZCAob3B0aW9uYWwpIEEgdGltZSB6b25lIElkLiBEZWZhdWx0cyB0byB0aGUgY3VycmVudCB0aW1lIHpvbmUgaWQsIHVzaW5nIGBndWVzc1RpbWVab25lSWQoKWAuXG4gKiBAcGFyYW0gc2hvd0Vhc3Rlcm5ab25lSWQgKG9wdGlvbmFsKSBXaGV0aGVyIG9yIG5vdCB0byBpbmNsdWRlIHRoZSB0aW1lWm9uZUlkIGluIHRoZSByZXN1bHQgZm9yIEVTVC9FRFQuIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gKiBAcGFyYW0gbm93VXRjIChvcHRpb25hbCkgVGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVsbEZvcm1hdHRlZFRpbWVab25lKFxuXHR0aW1lWm9uZUlkID0gZ3Vlc3NUaW1lWm9uZUlkKCksXG5cdHNob3dFYXN0ZXJuWm9uZUlkID0gZmFsc2UsXG5cdG5vd1V0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKClcbikge1xuXHRjb25zdCB6b25lID0gbW9tZW50LnR6LnpvbmUodGltZVpvbmVJZClcblx0aWYgKCF6b25lKSByZXR1cm4gJydcblxuXHRjb25zdCB6b25lZE1vbWVudCA9IGdldFpvbmVkTW9tZW50RnJvbVV0Yyhub3dVdGMsIHRpbWVab25lSWQpXG5cdC8vIGZpbHRlciB0aGUgem9uZSBkYXRhIGRvd24gdG8ganVzdCByZWNlbnQgeWVhcnMsIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb2YgMTkwMCB0byAyMDM4XG5cdGNvbnN0IGZpbHRlcmVkWm9uZSA9IG1vbWVudFV0aWxzLnR6LmZpbHRlclllYXJzKHpvbmUsIHpvbmVkTW9tZW50LnllYXIoKSAtIDEsIHpvbmVkTW9tZW50LnllYXIoKSArIDEpXG5cdC8vIGZpbmQgYWxsIHVuaXF1ZSBhYmJyZXZpYXRpb25zIGZvciB0aGUgem9uZSwgY29tYmluZWQgaW50byBhIHN0cmluZ1xuXHRjb25zdCBhYmJyZXZpYXRpb25zID0gZmlsdGVyZWRab25lLmFiYnJzXG5cdFx0Ly8gZmlsdGVyIG91dCBub24tYWxwaGEgYWJicmV2aWF0aW9uc1xuXHRcdC5maWx0ZXIoYWJiciA9PiAvW2EtekEtWl0rL2cudGVzdChhYmJyKSlcblx0XHQucmVkdWNlKCh1bmlxdWVBYmJyczogc3RyaW5nW10sIGFiYnIpID0+IHtcblx0XHRcdGlmICghdW5pcXVlQWJicnMuaW5jbHVkZXMoYWJicikpIHtcblx0XHRcdFx0dW5pcXVlQWJicnMucHVzaChhYmJyKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHVuaXF1ZUFiYnJzXG5cdFx0fSwgW10pXG5cdGNvbnN0IGFiYnJldmlhdGlvbnNTdHJpbmcgPSBhYmJyZXZpYXRpb25zLmxlbmd0aCA+IDAgPyBhYmJyZXZpYXRpb25zLmpvaW4oJy8nKSA6IG51bGxcblx0Y29uc3QgcmVhZGFibGVab25lSWQgPSB0aW1lWm9uZUlkLnJlcGxhY2UoJ18nLCAnICcpXG5cdHJldHVybiAhYWJicmV2aWF0aW9uc1N0cmluZ1xuXHRcdD8gcmVhZGFibGVab25lSWRcblx0XHQ6IGFiYnJldmlhdGlvbnNTdHJpbmcgPT09ICdFU1QvRURUJyAmJiAhc2hvd0Vhc3Rlcm5ab25lSWRcblx0XHRcdD8gLy8gRG9uJ3Qgc2hvdyB0aGUgem9uZUlkIGlmIGluIEVhc3Rlcm4sIHVubGVzcyB0b2xkIHRvXG5cdFx0XHRcdGFiYnJldmlhdGlvbnNTdHJpbmdcblx0XHRcdDogLy8gU2hvdyB0aGUgY29tYmluZWQgYWJicmV2aWF0aW9ucyBwbHVzIHRoZSBmcmllbmRseSB6b25lSWRcblx0XHRcdFx0YCR7YWJicmV2aWF0aW9uc1N0cmluZ30gKCR7cmVhZGFibGVab25lSWR9KWBcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiYXNpYyB0aW1lIHpvbmUgYWJicmV2aWF0aW9uIGZvciB0aGUgZ2l2ZW4gZGF0ZSwgZS5nLiBgRURUYC5cbiAqXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgVGhlIGRhdGUgdG8gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkVGltZVpvbmUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICd6Jylcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEgZGF0ZSB1c2luZyB0aGUgZ2l2ZW4gZm9ybWF0LiBQYXJzZXMgdGhlIGRhdGUgYXMgVVRDLCB0aGVuIGNvbnZlcnRzIHRvIHRoZSBjdXJyZW50IHRpbWUgem9uZSwgdGhlbiBmb3JtYXRzLlxuICogQHBhcmFtIHsqfSBkYXRlVGltZVV0YyBUaGUgZGF0ZSB0byBmb3JtYXQuIEFueSB2YWxpZCBpbnB1dCBmb3IgYG1vbWVudC51dGMoLi4uKWBcbiAqIEBwYXJhbSB7Kn0gZm9ybWF0IFRoZSBmb3JtYXQgdG8gdXNlXG4gKi9cbmZ1bmN0aW9uIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nLCB0aW1lWm9uZUlkID0gZ3Vlc3NUaW1lWm9uZUlkKCkpIHtcblx0cmV0dXJuIGdldFpvbmVkTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YywgdGltZVpvbmVJZCkuZm9ybWF0KGZvcm1hdClcbn1cblxuY29uc3QgaXNJbnB1dFR5cGVTdXBwb3J0ZWQgPSAodHlwZTogc3RyaW5nKSA9PiB7XG5cdHRyeSB7XG5cdFx0Y29uc3QgdGVzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jylcblx0XHR0ZXN0LnR5cGUgPSB0eXBlXG5cdFx0Y29uc3QgaXNTdXBwb3J0ZWQgPSB0ZXN0LnR5cGUgPT09IHR5cGVcblx0XHRyZXR1cm4gaXNTdXBwb3J0ZWRcblx0fSBjYXRjaCB7XG5cdFx0cmV0dXJuIGZhbHNlXG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IGlzRGF0ZUlucHV0U3VwcG9ydGVkID0gaXNJbnB1dFR5cGVTdXBwb3J0ZWQoJ2RhdGUnKVxuXG5leHBvcnQgY29uc3QgaXNUaW1lSW5wdXRTdXBwb3J0ZWQgPSBpc0lucHV0VHlwZVN1cHBvcnRlZCgndGltZScpXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGVUaW1lVmFsaWQoZGF0ZVRpbWU6IHN0cmluZyB8IERhdGUpIHtcblx0cmV0dXJuICEhZGF0ZVRpbWUgJiYgbW9tZW50KGRhdGVUaW1lKS5pc1ZhbGlkKClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsTUFBTSxNQUFNLGlCQUFpQjtBQUNwQyxPQUFPQyxXQUFXLE1BQU0sdUNBQXVDO0FBQy9ELFNBQVNDLG9CQUFvQixFQUFFQyxlQUFlLFFBQVEsWUFBWTs7QUFFbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUlDLFdBQVcsR0FBRyxDQUFDOztBQUVuQjtBQUNBO0FB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