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.
- package/lib/components/ActionList.js +164 -37
- package/lib/components/AlertDialog.js +128 -12
- package/lib/components/AlertWithIcon.js +88 -29
- package/lib/components/ConnectedModal.js +35 -12
- package/lib/components/Dropdowns/GroupsDropdown.js +63 -45
- package/lib/components/Dropdowns/ManagedNavDropdown.js +92 -67
- package/lib/components/Dropdowns/UserDropdown.js +105 -24
- package/lib/components/Dropdowns/index.js +4 -10
- package/lib/components/EntityOwnerList.js +47 -21
- package/lib/components/Error.js +101 -12
- package/lib/components/ErrorBoundary.js +127 -38
- package/lib/components/ErrorMessage.js +39 -12
- package/lib/components/Forms/DateField.js +56 -45
- package/lib/components/Forms/TimeField.js +76 -45
- package/lib/components/Forms/index.js +3 -5
- package/lib/components/Groups/CreateEditCopySaveButtons.js +109 -14
- package/lib/components/Groups/ExternalGroups/Attach.js +206 -151
- package/lib/components/Groups/ExternalGroups/Table.js +176 -48
- package/lib/components/Groups/GroupCreateOrEditCommonProps.js +2 -2
- package/lib/components/Groups/RosterSyncInfo.js +142 -23
- package/lib/components/HOC/AccessibleAppComponent.js +88 -72
- package/lib/components/HOC/ActivityRequiredComponent.js +68 -33
- package/lib/components/HOC/AsyncComponent.js +49 -41
- package/lib/components/HOC/AuthenticatedComponent.js +55 -44
- package/lib/components/HOC/CollectionComponent.js +154 -104
- package/lib/components/HOC/CollectionFirstItemComponent.js +45 -40
- package/lib/components/HOC/CollectionItemComponent.js +152 -100
- package/lib/components/HOC/ConnectedModalComponent.js +87 -69
- package/lib/components/HOC/DataDependentComponent.js +26 -27
- package/lib/components/HOC/EntityComponent.js +57 -53
- package/lib/components/HOC/FullscreenModalComponent.js +139 -108
- package/lib/components/HOC/GroupActivityRequiredComponent.js +27 -20
- package/lib/components/HOC/GuidComponent.js +20 -20
- package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +32 -29
- package/lib/components/HOC/ModelErrorRedirectComponent.js +37 -39
- package/lib/components/HOC/SearchPersistorComponent.js +237 -173
- package/lib/components/HOC/UnauthenticatedComponent.js +32 -30
- package/lib/components/HOC/UserComponent.js +6 -8
- package/lib/components/Icons/IconAlphaList.js +28 -8
- package/lib/components/Icons/IconExternalUser.js +28 -8
- package/lib/components/Icons/IconImpersonation.js +28 -8
- package/lib/components/Icons/IconStopImpersonating.js +28 -8
- package/lib/components/Icons/IconTable.js +29 -9
- package/lib/components/Icons/IconTableDeleteCol.js +28 -8
- package/lib/components/Icons/IconTableDeleteRow.js +28 -8
- package/lib/components/Icons/IconTableInsertCol.js +28 -8
- package/lib/components/Icons/IconTableInsertRow.js +28 -8
- package/lib/components/Impersonation/Button.js +71 -16
- package/lib/components/Impersonation/Link.js +72 -16
- package/lib/components/Impersonation/UserDetail.js +60 -11
- package/lib/components/Loading.js +23 -8
- package/lib/components/LockDownBrowser/Check.js +188 -51
- package/lib/components/LockDownBrowser/ExitButton.js +22 -13
- package/lib/components/LockDownBrowser/Launch.js +64 -64
- package/lib/components/Lti/Confirm.js +147 -14
- package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +165 -36
- package/lib/components/Lti/Launch.js +99 -25
- package/lib/components/Lti/LaunchGroup.js +81 -16
- package/lib/components/ManageTable.js +304 -90
- package/lib/components/ManageTableNoDataComponent.js +38 -7
- package/lib/components/NewVersionAlert.js +76 -49
- package/lib/components/NotFound.js +81 -11
- package/lib/components/Notifications.js +179 -129
- package/lib/components/PaginationNextButton.js +28 -9
- package/lib/components/PaginationPreviousButton.js +28 -9
- package/lib/components/Quill/CustomToolbar.js +427 -222
- package/lib/components/Quill/Formats/Image.js +67 -67
- package/lib/components/Quill/Formats/List.js +38 -47
- package/lib/components/Quill/Formats/Video.js +23 -26
- package/lib/components/Quill/ImageDropModule.js +136 -114
- package/lib/components/Quill/ImageWarning.js +41 -12
- package/lib/components/Quill/ImageWithAltTextModal.js +420 -89
- package/lib/components/Quill/Specs/CustomImageSpec.js +32 -31
- package/lib/components/Quill/Specs/CustomVideoSpec.js +22 -23
- package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +89 -97
- package/lib/components/Quill/TableModule/Blots/TableBlot.js +47 -50
- package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +48 -51
- package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +219 -224
- package/lib/components/Quill/TableModule/Blots/TableContainer.js +75 -86
- package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +70 -73
- package/lib/components/Quill/TableModule/constants.js +40 -42
- package/lib/components/Quill/TableModule/index.js +357 -305
- package/lib/components/Quill/TableModule/utils.js +39 -48
- package/lib/components/Quill/accessibilityFix.js +219 -223
- package/lib/components/Quill/index.js +30 -33
- package/lib/components/RefreshIndicator/Bordered.js +44 -10
- package/lib/components/RefreshIndicator/Inline.js +43 -12
- package/lib/components/RefreshIndicator/index.js +257 -62
- package/lib/components/SearchControls.js +211 -14
- package/lib/components/SentryRoute.js +5 -7
- package/lib/components/Tables/RoleFilter.js +66 -38
- package/lib/components/Tables/TextFilter.js +58 -18
- package/lib/components/UserRoles/Add.js +193 -99
- package/lib/components/UserRoles/Context.js +3 -6
- package/lib/components/UserRoles/RoleCell.js +176 -75
- package/lib/components/UserRoles/Select.js +151 -20
- package/lib/components/UserRoles/Table.js +215 -82
- package/lib/components/UserRoles/index.js +526 -386
- package/lib/config/eslint/index.js +26 -29
- package/lib/config/eslint/lib/order.js +21 -28
- package/lib/config/eslint/lib/prettier.js +15 -19
- package/lib/config/eslint/lib/typescript.js +87 -113
- package/lib/config/eslint/react.js +18 -15
- package/lib/constants/baseActivity.js +26 -28
- package/lib/constants/baseRole.js +10 -12
- package/lib/constants/configuration.js +43 -55
- package/lib/constants/externalProviderType.js +6 -8
- package/lib/constants/fetchErrorData.js +10 -12
- package/lib/constants/index.js +13 -15
- package/lib/constants/lockDownBrowser.js +23 -25
- package/lib/constants/mockData.js +370 -300
- package/lib/constants/modelStatus.js +11 -13
- package/lib/constants/notificationType.js +8 -10
- package/lib/constants/operatingSystem.js +8 -10
- package/lib/constants/shard.js +7 -9
- package/lib/constants/table.js +18 -22
- package/lib/constants/tier.js +8 -10
- package/lib/constants/userRole.js +11 -8
- package/lib/endpointMappings.js +191 -182
- package/lib/hooks/useCollection.js +79 -65
- package/lib/hooks/useCollectionConfiguration.js +220 -80
- package/lib/hooks/useCollectionItem.js +151 -57
- package/lib/hooks/useGuid.js +16 -9
- package/lib/hooks/usePrevious.js +14 -13
- package/lib/index.js +11 -26
- package/lib/redux/actionCreator.js +44 -35
- package/lib/redux/actions/AuthAction.js +45 -32
- package/lib/redux/actions/ModalAction.js +6 -8
- package/lib/redux/actions/ModelAction.js +95 -43
- package/lib/redux/actions/NotificationAction.js +6 -8
- package/lib/redux/actions/SearchAction.js +5 -7
- package/lib/redux/actions/index.js +6 -8
- package/lib/redux/configureReducers.js +48 -46
- package/lib/redux/configureStore.js +77 -91
- package/lib/redux/helpers.js +2 -5
- package/lib/redux/reducers/authReducer.js +44 -43
- package/lib/redux/reducers/index.js +7 -14
- package/lib/redux/reducers/modalsReducer.js +43 -31
- package/lib/redux/reducers/modelsReducer.js +131 -137
- package/lib/redux/reducers/notificationsReducer.js +20 -20
- package/lib/redux/reducers/searchReducer.js +13 -13
- package/lib/redux/sagas/appInsightsSaga.js +19 -21
- package/lib/redux/sagas/authSaga.js +248 -234
- package/lib/redux/sagas/caliperSaga.js +142 -131
- package/lib/redux/sagas/clockOffsetSaga.js +29 -32
- package/lib/redux/sagas/configurationSaga.js +8 -10
- package/lib/redux/sagas/downtimeApiErrorSaga.js +16 -19
- package/lib/redux/sagas/errorSaga.js +23 -24
- package/lib/redux/sagas/googleAnalyticsSaga.js +24 -27
- package/lib/redux/sagas/identityProviderSaga.js +19 -21
- package/lib/redux/sagas/initialDataLoadSaga.js +34 -31
- package/lib/redux/sagas/lockDownBrowserErrorSaga.js +25 -22
- package/lib/redux/sagas/modelFetchSaga.js +302 -286
- package/lib/redux/sagas/noStoreSaga.js +60 -61
- package/lib/redux/sagas/postLoginDataSaga.js +37 -32
- package/lib/redux/sagas/postLoginRedirectSaga.js +22 -27
- package/lib/redux/sagas/rootSaga.js +77 -60
- package/lib/redux/sagas/sentrySaga.js +25 -28
- package/lib/redux/sagas/userIdSaga.js +13 -15
- package/lib/services/codeProviderService.js +21 -21
- package/lib/services/dateService.js +6 -8
- package/lib/services/documentService.js +10 -11
- package/lib/services/fetchService.js +103 -95
- package/lib/services/persistenceService.js +27 -30
- package/lib/services/ticketProviderService.js +25 -25
- package/lib/services/tokenPersistenceService.js +8 -10
- package/lib/services/windowService.js +14 -16
- package/lib/startup.js +110 -101
- package/lib/types/AppConfiguration.js +2 -2
- package/lib/types/Artifact.js +7 -9
- package/lib/types/BaseReduxState.js +2 -2
- package/lib/types/Client.js +2 -2
- package/lib/types/Collection.js +2 -2
- package/lib/types/Configuration.js +2 -2
- package/lib/types/DeepLinkingResponseRequest.js +2 -2
- package/lib/types/DeletableModel.js +2 -2
- package/lib/types/Event.js +2 -2
- package/lib/types/ExternalGroup.js +2 -2
- package/lib/types/ExternalProvider.js +2 -2
- package/lib/types/ExternalTerm.js +2 -2
- package/lib/types/Group.js +2 -2
- package/lib/types/IdentityProvider.js +2 -2
- package/lib/types/LtiLaunch.js +2 -2
- package/lib/types/NameOnlyEntity.js +2 -2
- package/lib/types/Notification.js +2 -2
- package/lib/types/OptionalRecord.js +2 -2
- package/lib/types/OwnerSchedule.js +2 -2
- package/lib/types/PropertyOfType.js +2 -2
- package/lib/types/Quill.js +2 -2
- package/lib/types/RoleDescription.js +2 -2
- package/lib/types/Search.js +2 -2
- package/lib/types/SimpleLocation.js +2 -2
- package/lib/types/UniTime.js +2 -2
- package/lib/types/User.js +2 -2
- package/lib/types/UserRole.js +2 -2
- package/lib/types/auth/AuthState.js +2 -2
- package/lib/types/auth/CasV1LoginRequestBody.js +2 -2
- package/lib/types/auth/ClientCredentials.js +2 -2
- package/lib/types/auth/CodeProviderService.js +2 -2
- package/lib/types/auth/LocalLoginRequestBody.js +2 -2
- package/lib/types/auth/TicketProviderService.js +2 -2
- package/lib/types/auth/TokenPersistenceService.js +2 -2
- package/lib/types/auth/index.js +8 -10
- package/lib/types/externals.d.js +2 -0
- package/lib/types/index.js +29 -31
- package/lib/types/net/EndpointConfig.js +2 -2
- package/lib/types/net/EndpointMapping.js +2 -2
- package/lib/types/net/EndpointMappings.js +2 -2
- package/lib/types/net/ErrorHandler.js +2 -2
- package/lib/types/net/FetchConfig.js +2 -2
- package/lib/types/net/FetchErrorData.js +6 -8
- package/lib/types/net/FetchResult.js +2 -2
- package/lib/types/net/HTTPMethod.js +2 -2
- package/lib/types/net/HTTPStatusCode.js +12 -14
- package/lib/types/net/Metadata.js +2 -2
- package/lib/types/net/Model.js +2 -2
- package/lib/types/net/ModelCollection.js +2 -2
- package/lib/types/net/ModelsState.js +2 -2
- package/lib/types/net/OAuthToken.js +2 -2
- package/lib/types/net/OAuthTokenOrNull.js +2 -2
- package/lib/types/net/TokenAccessFunction.js +2 -2
- package/lib/types/net/index.js +17 -19
- package/lib/utils/baseActivity.js +83 -85
- package/lib/utils/baseRole.js +32 -36
- package/lib/utils/collection.js +403 -297
- package/lib/utils/cookies.js +19 -23
- package/lib/utils/date.js +188 -205
- package/lib/utils/dom.js +130 -131
- package/lib/utils/domainIdentifier.js +4 -8
- package/lib/utils/entityUserRole.js +2 -5
- package/lib/utils/error.js +14 -19
- package/lib/utils/events.js +32 -31
- package/lib/utils/externalGroup.js +20 -25
- package/lib/utils/externalProviders.js +4 -7
- package/lib/utils/externalTerms.js +6 -6
- package/lib/utils/fetch.js +168 -176
- package/lib/utils/group.js +14 -11
- package/lib/utils/groupDates.js +38 -46
- package/lib/utils/groupRoles.js +23 -32
- package/lib/utils/lockDownBrowser.js +12 -15
- package/lib/utils/logger.js +23 -28
- package/lib/utils/lti.js +4 -7
- package/lib/utils/model.js +28 -43
- package/lib/utils/number.js +9 -13
- package/lib/utils/promise.js +23 -26
- package/lib/utils/quill.js +55 -60
- package/lib/utils/route.js +52 -60
- package/lib/utils/search.js +72 -87
- package/lib/utils/shard.js +33 -42
- package/lib/utils/sort.js +47 -50
- package/lib/utils/string.js +10 -12
- package/lib/utils/table.js +29 -33
- package/lib/utils/timezone.js +7 -12
- package/lib/utils/url.js +130 -144
- package/lib/utils/user.js +54 -64
- package/lib/utils/userAgent.js +7 -14
- package/lib/utils/userRole.js +36 -39
- package/package.json +17 -3
package/lib/utils/date.js
CHANGED
|
@@ -1,121 +1,73 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
16
|
+
export const setClockOffset = function (offset) {
|
|
17
|
+
clockOffset = offset;
|
|
44
18
|
};
|
|
45
|
-
|
|
19
|
+
|
|
46
20
|
/**
|
|
47
21
|
* Get the current UTC time, calibrated to the API server's clock
|
|
48
22
|
*/
|
|
49
|
-
const getServerNowUtc = function () {
|
|
50
|
-
|
|
23
|
+
export const getServerNowUtc = function () {
|
|
24
|
+
return new Date(Date.now() + clockOffset);
|
|
51
25
|
};
|
|
52
|
-
|
|
26
|
+
|
|
53
27
|
/**
|
|
54
28
|
* Return the provided date, offset by the clockOffset
|
|
55
29
|
*/
|
|
56
|
-
const getOffsetDate =
|
|
57
|
-
|
|
30
|
+
export const getOffsetDate = date => {
|
|
31
|
+
return new Date(date.getTime() + clockOffset);
|
|
58
32
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
return (0, exports.getLocalMomentFromUtc)(dateTimeUtc).toDate();
|
|
56
|
+
export const getLocalDateTimeFromUtc = dateTimeUtc => {
|
|
57
|
+
return getLocalMomentFromUtc(dateTimeUtc).toDate();
|
|
99
58
|
};
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
114
|
-
|
|
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
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
|
189
|
-
|
|
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
|
|
197
|
-
|
|
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
|
|
205
|
-
|
|
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
|
|
213
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
275
|
-
|
|
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
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
|
|
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
|
|
360
|
-
|
|
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 =
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
|
|
374
|
-
|
|
375
|
-
function isDateTimeValid(dateTime) {
|
|
376
|
-
|
|
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+IDAgPyBhYmJyZXZpYXRpb25zLmpvaW4oJy8nKSA6IG51bGxcblx0Y29uc3QgcmVhZGFibGVab25lSWQgPSB0aW1lWm9uZUlkLnJlcGxhY2UoJ18nLCAnICcpXG5cdHJldHVybiAhYWJicmV2aWF0aW9uc1N0cmluZ1xuXHRcdD8gcmVhZGFibGVab25lSWRcblx0XHQ6IGFiYnJldmlhdGlvbnNTdHJpbmcgPT09ICdFU1QvRURUJyAmJiAhc2hvd0Vhc3Rlcm5ab25lSWRcblx0XHRcdD8gLy8gRG9uJ3Qgc2hvdyB0aGUgem9uZUlkIGlmIGluIEVhc3Rlcm4sIHVubGVzcyB0b2xkIHRvXG5cdFx0XHRcdGFiYnJldmlhdGlvbnNTdHJpbmdcblx0XHRcdDogLy8gU2hvdyB0aGUgY29tYmluZWQgYWJicmV2aWF0aW9ucyBwbHVzIHRoZSBmcmllbmRseSB6b25lSWRcblx0XHRcdFx0YCR7YWJicmV2aWF0aW9uc1N0cmluZ30gKCR7cmVhZGFibGVab25lSWR9KWBcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiYXNpYyB0aW1lIHpvbmUgYWJicmV2aWF0aW9uIGZvciB0aGUgZ2l2ZW4gZGF0ZSwgZS5nLiBgRURUYC5cbiAqXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgVGhlIGRhdGUgdG8gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkVGltZVpvbmUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICd6Jylcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEgZGF0ZSB1c2luZyB0aGUgZ2l2ZW4gZm9ybWF0LiBQYXJzZXMgdGhlIGRhdGUgYXMgVVRDLCB0aGVuIGNvbnZlcnRzIHRvIHRoZSBjdXJyZW50IHRpbWUgem9uZSwgdGhlbiBmb3JtYXRzLlxuICogQHBhcmFtIHsqfSBkYXRlVGltZVV0YyBUaGUgZGF0ZSB0byBmb3JtYXQuIEFueSB2YWxpZCBpbnB1dCBmb3IgYG1vbWVudC51dGMoLi4uKWBcbiAqIEBwYXJhbSB7Kn0gZm9ybWF0IFRoZSBmb3JtYXQgdG8gdXNlXG4gKi9cbmZ1bmN0aW9uIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nLCB0aW1lWm9uZUlkID0gZ3Vlc3NUaW1lWm9uZUlkKCkpIHtcblx0cmV0dXJuIGdldFpvbmVkTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YywgdGltZVpvbmVJZCkuZm9ybWF0KGZvcm1hdClcbn1cblxuY29uc3QgaXNJbnB1dFR5cGVTdXBwb3J0ZWQgPSAodHlwZTogc3RyaW5nKSA9PiB7XG5cdHRyeSB7XG5cdFx0Y29uc3QgdGVzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jylcblx0XHR0ZXN0LnR5cGUgPSB0eXBlXG5cdFx0Y29uc3QgaXNTdXBwb3J0ZWQgPSB0ZXN0LnR5cGUgPT09IHR5cGVcblx0XHRyZXR1cm4gaXNTdXBwb3J0ZWRcblx0fSBjYXRjaCB7XG5cdFx0cmV0dXJuIGZhbHNlXG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IGlzRGF0ZUlucHV0U3VwcG9ydGVkID0gaXNJbnB1dFR5cGVTdXBwb3J0ZWQoJ2RhdGUnKVxuXG5leHBvcnQgY29uc3QgaXNUaW1lSW5wdXRTdXBwb3J0ZWQgPSBpc0lucHV0VHlwZVN1cHBvcnRlZCgndGltZScpXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGVUaW1lVmFsaWQoZGF0ZVRpbWU6IHN0cmluZyB8IERhdGUpIHtcblx0cmV0dXJuICEhZGF0ZVRpbWUgJiYgbW9tZW50KGRhdGVUaW1lKS5pc1ZhbGlkKClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsTUFBTSxNQUFNLGlCQUFpQjtBQUNwQyxPQUFPQyxXQUFXLE1BQU0sdUNBQXVDO0FBQy9ELFNBQVNDLG9CQUFvQixFQUFFQyxlQUFlLFFBQVEsWUFBWTs7QUFFbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUlDLFdBQVcsR0FBRyxDQUFDOztBQUVuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sTUFBTUMsY0FBYyxHQUFHLFNBQUFBLENBQVVDLE1BQWMsRUFBRTtFQUN2REYsV0FBVyxHQUFHRSxNQUFNO0FBQ3JCLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsT0FBTyxNQUFNQyxlQUFlLEdBQUcsU0FBQUEsQ0FBQSxFQUFZO0VBQzFDLE9BQU8sSUFBSUMsSUFBSSxDQUFDQSxJQUFJLENBQUNDLEdBQUcsQ0FBQyxDQUFDLEdBQUdMLFdBQVcsQ0FBQztBQUMxQyxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLE9BQU8sTUFBTU0sYUFBYSxHQUFJQyxJQUFVLElBQUs7RUFDNUMsT0FBTyxJQUFJSCxJQUFJLENBQUNHLElBQUksQ0FBQ0MsT0FBTyxDQUFDLENBQUMsR0FBR1IsV0FBVyxDQUFDO0FBQzlDLENBQUM7QUFFRCxPQUFPLE1BQU1TLHFCQUFxQixHQUFHLFNBQUFBLENBQUEsRUFHaEM7RUFBQSxJQUZKQyxXQUFXLEdBQUFDLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHUixlQUFlLENBQUMsQ0FBQyxDQUFDVyxXQUFXLENBQUMsQ0FBQztFQUFBLElBQzdDQyxVQUFVLEdBQUFKLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHWixlQUFlLENBQUMsQ0FBQztFQUU5QixPQUFPSCxNQUFNLENBQUNvQixHQUFHLENBQUNOLFdBQVcsQ0FBQyxDQUFDTyxFQUFFLENBQUNGLFVBQVUsQ0FBQztBQUM5QyxDQUFDO0FBRUQsT0FBTyxNQUFNRyxrQ0FBa0MsR0FBRyxTQUFBQSxDQUFBLEVBQW1EO0VBQUEsSUFBbERSLFdBQVcsR0FBQUMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdSLGVBQWUsQ0FBQyxDQUFDLENBQUNXLFdBQVcsQ0FBQyxDQUFDO0VBQy9GLE1BQU1DLFVBQVUsR0FBR2pCLG9CQUFvQixDQUFDLENBQUM7RUFDekMsT0FBT1cscUJBQXFCLENBQUNDLFdBQVcsRUFBRUssVUFBVSxDQUFDO0FBQ3RELENBQUM7QUFFRCxPQUFPLE1BQU1JLCtCQUErQixHQUFHLFNBQUFBLENBQUNDLGFBQTRCLEVBQXFDO0VBQUEsSUFBbkNMLFVBQVUsR0FBQUosU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdaLGVBQWUsQ0FBQyxDQUFDO0VBQzNHLE1BQU1zQixXQUFXLEdBQUd6QixNQUFNLENBQUN3QixhQUFhLENBQUM7RUFDekMsTUFBTUUsV0FBVyxHQUFHMUIsTUFBTSxDQUFDcUIsRUFBRSxDQUM1QixDQUNDSSxXQUFXLENBQUNFLElBQUksQ0FBQyxDQUFDLEVBQ2xCRixXQUFXLENBQUNHLEtBQUssQ0FBQyxDQUFDLEVBQ25CSCxXQUFXLENBQUNkLElBQUksQ0FBQyxDQUFDLEVBQ2xCYyxXQUFXLENBQUNJLElBQUksQ0FBQyxDQUFDLEVBQ2xCSixXQUFXLENBQUNLLE1BQU0sQ0FBQyxDQUFDLEVBQ3BCTCxXQUFXLENBQUNNLE1BQU0sQ0FBQyxDQUFDLEVBQ3BCTixXQUFXLENBQUNPLFdBQVcsQ0FBQyxDQUFDLENBQ3pCLEVBQ0RiLFVBQ0QsQ0FBQztFQUNELE9BQU9PLFdBQVc7QUFDbkIsQ0FBQztBQUVELE9BQU8sTUFBTU8scUJBQXFCLEdBQUcsU0FBQUEsQ0FBQSxFQUdoQztFQUFBLElBRkpuQixXQUFXLEdBQUFDLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHUixlQUFlLENBQUMsQ0FBQyxDQUFDVyxXQUFXLENBQUMsQ0FBQztFQUFBLElBQzdDQyxVQUFVLEdBQUFKLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHWixlQUFlLENBQUMsQ0FBQztFQUU5QixNQUFNdUIsV0FBVyxHQUFHYixxQkFBcUIsQ0FBQ0MsV0FBVyxFQUFFSyxVQUFVLENBQUM7RUFDbEUsTUFBTU0sV0FBVyxHQUFHekIsTUFBTSxDQUFDLENBQzFCMEIsV0FBVyxDQUFDQyxJQUFJLENBQUMsQ0FBQyxFQUNsQkQsV0FBVyxDQUFDRSxLQUFLLENBQUMsQ0FBQyxFQUNuQkYsV0FBVyxDQUFDZixJQUFJLENBQUMsQ0FBQyxFQUNsQmUsV0FBVyxDQUFDRyxJQUFJLENBQUMsQ0FBQyxFQUNsQkgsV0FBVyxDQUFDSSxNQUFNLENBQUMsQ0FBQyxFQUNwQkosV0FBVyxDQUFDSyxNQUFNLENBQUMsQ0FBQyxFQUNwQkwsV0FBVyxDQUFDTSxXQUFXLENBQUMsQ0FBQyxDQUN6QixDQUFDO0VBQ0YsT0FBT1AsV0FBVztBQUNuQixDQUFDO0FBRUQsT0FBTyxNQUFNUyx1QkFBdUIsR0FBSXBCLFdBQW1CLElBQUs7RUFDL0QsT0FBT21CLHFCQUFxQixDQUFDbkIsV0FBVyxDQUFDLENBQUNxQixNQUFNLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsT0FBTyxNQUFNQyxnQkFBZ0IsR0FBSUMsUUFBYyxJQUFLO0VBQ25ELE9BQU8sSUFBSTdCLElBQUksQ0FBQzZCLFFBQVEsQ0FBQ0MsV0FBVyxDQUFDLENBQUMsRUFBRUQsUUFBUSxDQUFDRSxRQUFRLENBQUMsQ0FBQyxFQUFFRixRQUFRLENBQUNHLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDakYsQ0FBQztBQUVELE9BQU8sU0FBU0MsV0FBV0EsQ0FBQzNCLFdBQW1CLEVBQUU7RUFDaEQsT0FBT2QsTUFBTSxDQUFDYyxXQUFXLENBQUMsQ0FDeEI0QixPQUFPLENBQUMsS0FBSyxDQUFDLENBQ2RDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQ2RDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7RUFBQSxDQUM1QlQsTUFBTSxDQUFDLENBQUM7QUFDWDtBQUVBLE9BQU8sU0FBU1UsY0FBY0EsQ0FBQy9CLFdBQW1CLEVBQUU7RUFDbkQsT0FBT2QsTUFBTSxDQUFDYyxXQUFXLENBQUMsQ0FDeEI0QixPQUFPLENBQUMsUUFBUSxDQUFDLENBQ2pCQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUNoQkMsUUFBUSxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztFQUFBLENBQzVCVCxNQUFNLENBQUMsQ0FBQztBQUNYOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNXLHFCQUFxQkEsQ0FBQ2hDLFdBQW9CLEVBQTRDO0VBQUEsSUFBMUNpQyxNQUFNLEdBQUFoQyxTQUFBLENBQUFDLE1BQUEsUUFBQUQsU0FBQSxRQUFBRSxTQUFBLEdBQUFGLFNBQUEsTUFBR1IsZUFBZSxDQUFDLENBQUMsQ0FBQ1csV0FBVyxDQUFDLENBQUM7RUFDbkcsSUFBSSxDQUFDSixXQUFXLEVBQUU7SUFDakIsT0FBTyxLQUFLO0VBQ2I7RUFDQSxNQUFNa0Msc0JBQXNCLEdBQUdmLHFCQUFxQixDQUFDbkIsV0FBVyxDQUFDO0VBQ2pFLE1BQU1tQyxhQUFhLEdBQUdoQixxQkFBcUIsQ0FBQ2MsTUFBTSxDQUFDO0VBQ25ELE9BQU9FLGFBQWEsQ0FBQ0MsYUFBYSxDQUFDRixzQkFBc0IsQ0FBQztBQUMzRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTRyxzQkFBc0JBLENBQUNyQyxXQUFvQixFQUE0QztFQUFBLElBQTFDaUMsTUFBTSxHQUFBaEMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdSLGVBQWUsQ0FBQyxDQUFDLENBQUNXLFdBQVcsQ0FBQyxDQUFDO0VBQ3BHLElBQUksQ0FBQ0osV0FBVyxFQUFFO0lBQ2pCLE9BQU8sS0FBSztFQUNiO0VBQ0EsTUFBTWtDLHNCQUFzQixHQUFHZixxQkFBcUIsQ0FBQ25CLFdBQVcsQ0FBQztFQUNqRSxNQUFNbUMsYUFBYSxHQUFHaEIscUJBQXFCLENBQUNjLE1BQU0sQ0FBQztFQUNuRCxPQUFPRSxhQUFhLENBQUNHLGNBQWMsQ0FBQ0osc0JBQXNCLENBQUM7QUFDNUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0ssY0FBY0EsQ0FBQ3ZDLFdBQW9CLEVBQTRDO0VBQUEsSUFBMUNpQyxNQUFNLEdBQUFoQyxTQUFBLENBQUFDLE1BQUEsUUFBQUQsU0FBQSxRQUFBRSxTQUFBLEdBQUFGLFNBQUEsTUFBR1IsZUFBZSxDQUFDLENBQUMsQ0FBQ1csV0FBVyxDQUFDLENBQUM7RUFDNUYsSUFBSSxDQUFDSixXQUFXLEVBQUU7SUFDakIsT0FBTyxLQUFLO0VBQ2I7RUFDQSxNQUFNa0Msc0JBQXNCLEdBQUdmLHFCQUFxQixDQUFDbkIsV0FBVyxDQUFDO0VBQ2pFLE1BQU1tQyxhQUFhLEdBQUdoQixxQkFBcUIsQ0FBQ2MsTUFBTSxDQUFDO0VBQ25ELE9BQU9FLGFBQWEsR0FBR0Qsc0JBQXNCO0FBQzlDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNNLGVBQWVBLENBQUN4QyxXQUFvQixFQUE0QztFQUFBLElBQTFDaUMsTUFBTSxHQUFBaEMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdSLGVBQWUsQ0FBQyxDQUFDLENBQUNXLFdBQVcsQ0FBQyxDQUFDO0VBQzdGLElBQUksQ0FBQ0osV0FBVyxFQUFFO0lBQ2pCLE9BQU8sS0FBSztFQUNiO0VBQ0EsTUFBTWtDLHNCQUFzQixHQUFHZixxQkFBcUIsQ0FBQ25CLFdBQVcsQ0FBQztFQUNqRSxNQUFNbUMsYUFBYSxHQUFHaEIscUJBQXFCLENBQUNjLE1BQU0sQ0FBQztFQUNuRCxPQUFPRSxhQUFhLEdBQUdELHNCQUFzQjtBQUM5Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTTywyQkFBMkJBLENBQUN6QyxXQUFtQixFQUF1QjtFQUFBLElBQXJCMEMsWUFBWSxHQUFBekMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUcsSUFBSTtFQUNuRixPQUFPMEMsV0FBVyxDQUFDM0MsV0FBVyxFQUFFLDZCQUE2QjBDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7QUFDekY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0UsNEJBQTRCQSxDQUFDNUMsV0FBbUIsRUFBdUI7RUFBQSxJQUFyQjBDLFlBQVksR0FBQXpDLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHLElBQUk7RUFDcEYsT0FBTzBDLFdBQVcsQ0FBQzNDLFdBQVcsRUFBRSw4QkFBOEIwQyxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO0FBQzFGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNHLCtCQUErQkEsQ0FBQzdDLFdBQW1CLEVBQXVCO0VBQUEsSUFBckIwQyxZQUFZLEdBQUF6QyxTQUFBLENBQUFDLE1BQUEsUUFBQUQsU0FBQSxRQUFBRSxTQUFBLEdBQUFGLFNBQUEsTUFBRyxJQUFJO0VBQ3ZGLE9BQU8wQyxXQUFXLENBQUMzQyxXQUFXLEVBQUUscUJBQXFCMEMsWUFBWSxHQUFHLElBQUksR0FBRyxFQUFFLEVBQUUsQ0FBQztBQUNqRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTSSwwQ0FBMENBLENBQUM5QyxXQUFtQixFQUF1QjtFQUFBLElBQXJCMEMsWUFBWSxHQUFBekMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUcsSUFBSTtFQUNsRyxPQUFPMEMsV0FBVyxDQUFDM0MsV0FBVyxFQUFFLGtCQUFrQjBDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7QUFDOUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNLLDBCQUEwQkEsQ0FBQy9DLFdBQW1CLEVBQUU7RUFDL0QsT0FBTzJDLFdBQVcsQ0FBQzNDLFdBQVcsRUFBRSxhQUFhLENBQUM7QUFDL0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNnRCxxQ0FBcUNBLENBQUNoRCxXQUFtQixFQUFFO0VBQzFFLE9BQU8yQyxXQUFXLENBQUMzQyxXQUFXLEVBQUUsT0FBTyxDQUFDO0FBQ3pDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNpRCw4Q0FBOENBLENBQzdEakQsV0FBbUIsRUFFbEI7RUFBQSxJQUREaUMsTUFBTSxHQUFBaEMsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdSLGVBQWUsQ0FBQyxDQUFDLENBQUNXLFdBQVcsQ0FBQyxDQUFDO0VBRXhDLE1BQU04QyxZQUFZLEdBQUdoRSxNQUFNLENBQUMrQyxNQUFNLENBQUM7RUFDbkMsTUFBTWtCLGNBQWMsR0FBR2pFLE1BQU0sQ0FBQ2MsV0FBVyxDQUFDO0VBQzFDLE9BQU9vRCxJQUFJLENBQUNDLEdBQUcsQ0FBQ0gsWUFBWSxDQUFDckMsSUFBSSxDQUFDLENBQUMsR0FBR3NDLGNBQWMsQ0FBQ3RDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQy9EbUMscUNBQXFDLENBQUNoRCxXQUFXLENBQUMsR0FDbEQrQywwQkFBMEIsQ0FBQy9DLFdBQVcsQ0FBQztBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU3NELHdCQUF3QkEsQ0FBQ3RELFdBQW1CLEVBQUU7RUFDN0QsT0FBTzJDLFdBQVcsQ0FBQzNDLFdBQVcsRUFBRSxRQUFRLENBQUM7QUFDMUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVN1RCxvQ0FBb0NBLENBQUN2RCxXQUFtQixFQUFFO0VBQ3pFLE9BQU8yQyxXQUFXLENBQUMzQyxXQUFXLEVBQUUsVUFBVSxDQUFDO0FBQzVDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTd0QsZ0NBQWdDQSxDQUFDeEQsV0FBbUIsRUFBRTtFQUNyRSxPQUFPMkMsV0FBVyxDQUFDM0MsV0FBVyxFQUFFLFlBQVksQ0FBQztBQUM5Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU3lELG1DQUFtQ0EsQ0FBQ3pELFdBQW1CLEVBQUU7RUFDeEUsT0FBTzJDLFdBQVcsQ0FBQzNDLFdBQVcsRUFBRSxLQUFLLENBQUM7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBUzBELHdCQUF3QkEsQ0FBQzFELFdBQW1CLEVBQXVCO0VBQUEsSUFBckIwQyxZQUFZLEdBQUF6QyxTQUFBLENBQUFDLE1BQUEsUUFBQUQsU0FBQSxRQUFBRSxTQUFBLEdBQUFGLFNBQUEsTUFBRyxJQUFJO0VBQ2hGLE9BQU8wQyxXQUFXLENBQUMzQyxXQUFXLEVBQUUsY0FBYzBDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7QUFDMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTaUIsb0NBQW9DQSxDQUNuRDNELFdBQW1CLEVBR2xCO0VBQUEsSUFGRDRELGlCQUFpQixHQUFBM0QsU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUcsS0FBSztFQUFBLElBQ3pCSSxVQUFVLEdBQUFKLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHWixlQUFlLENBQUMsQ0FBQztFQUU5QixNQUFNdUIsV0FBVyxHQUFHYixxQkFBcUIsQ0FBQ0MsV0FBVyxFQUFFSyxVQUFVLENBQUM7RUFDbEUsTUFBTXdELElBQUksR0FBR2xCLFdBQVcsQ0FBQzNDLFdBQVcsRUFBRSxhQUFhLEVBQUVLLFVBQVUsQ0FBQztFQUNoRSxNQUFNeUQsb0JBQW9CLEdBQUdsRCxXQUFXLENBQUNtRCxRQUFRLENBQUMsQ0FBQztFQUNuRCxPQUFPLENBQUNELG9CQUFvQixLQUFLLEtBQUssSUFBSUEsb0JBQW9CLEtBQUssS0FBSyxLQUFLLENBQUNGLGlCQUFpQjtFQUM1RjtFQUNELEdBQUdDLElBQUksSUFBSUMsb0JBQW9CLEVBQUU7RUFDaEM7RUFDRDtFQUNBLEdBQUdELElBQUksSUFBSUMsb0JBQW9CLEtBQUt6RCxVQUFVLENBQUMyRCxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHO0FBQ3RFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTQyxtQ0FBbUNBLENBQUNqRSxXQUFtQixFQUFFO0VBQ3hFLE9BQU8yQyxXQUFXLENBQUMzQyxXQUFXLEVBQUUsYUFBYSxDQUFDO0FBQy9DOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTa0UsNkNBQTZDQSxDQUFDbEUsV0FBbUIsRUFBRTtFQUNsRixPQUFPMkMsV0FBVyxDQUFDM0MsV0FBVyxFQUFFLE9BQU8sQ0FBQztBQUN6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTbUUsd0JBQXdCQSxDQUFBLEVBSXRDO0VBQUEsSUFIRDlELFVBQVUsR0FBQUosU0FBQSxDQUFBQyxNQUFBLFFBQUFELFNBQUEsUUFBQUUsU0FBQSxHQUFBRixTQUFBLE1BQUdaLGVBQWUsQ0FBQyxDQUFDO0VBQUEsSUFDOUJ1RSxpQkFBaUIsR0FBQTNELFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHLEtBQUs7RUFBQSxJQUN6QmdDLE1BQU0sR0FBQWhDLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHUixlQUFlLENBQUMsQ0FBQyxDQUFDVyxXQUFXLENBQUMsQ0FBQztFQUV4QyxNQUFNZ0UsSUFBSSxHQUFHbEYsTUFBTSxDQUFDcUIsRUFBRSxDQUFDNkQsSUFBSSxDQUFDL0QsVUFBVSxDQUFDO0VBQ3ZDLElBQUksQ0FBQytELElBQUksRUFBRSxPQUFPLEVBQUU7RUFFcEIsTUFBTXhELFdBQVcsR0FBR2IscUJBQXFCLENBQUNrQyxNQUFNLEVBQUU1QixVQUFVLENBQUM7RUFDN0Q7RUFDQSxNQUFNZ0UsWUFBWSxHQUFHbEYsV0FBVyxDQUFDb0IsRUFBRSxDQUFDK0QsV0FBVyxDQUFDRixJQUFJLEVBQUV4RCxXQUFXLENBQUNDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFRCxXQUFXLENBQUNDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0VBQ3JHO0VBQ0EsTUFBTTBELGFBQWEsR0FBR0YsWUFBWSxDQUFDRztFQUNsQztFQUFBLENBQ0NDLE1BQU0sQ0FBQ0MsSUFBSSxJQUFJLFlBQVksQ0FBQ0MsSUFBSSxDQUFDRCxJQUFJLENBQUMsQ0FBQyxDQUN2Q0UsTUFBTSxDQUFDLENBQUNDLFdBQXFCLEVBQUVILElBQUksS0FBSztJQUN4QyxJQUFJLENBQUNHLFdBQVcsQ0FBQ0MsUUFBUSxDQUFDSixJQUFJLENBQUMsRUFBRTtNQUNoQ0csV0FBVyxDQUFDRSxJQUFJLENBQUNMLElBQUksQ0FBQztJQUN2QjtJQUNBLE9BQU9HLFdBQVc7RUFDbkIsQ0FBQyxFQUFFLEVBQUUsQ0FBQztFQUNQLE1BQU1HLG1CQUFtQixHQUFHVCxhQUFhLENBQUNyRSxNQUFNLEdBQUcsQ0FBQyxHQUFHcUUsYUFBYSxDQUFDVSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSTtFQUNyRixNQUFNQyxjQUFjLEdBQUc3RSxVQUFVLENBQUMyRCxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztFQUNuRCxPQUFPLENBQUNnQixtQkFBbUIsR0FDeEJFLGNBQWMsR0FDZEYsbUJBQW1CLEtBQUssU0FBUyxJQUFJLENBQUNwQixpQkFBaUI7RUFDdEQ7RUFDRG9CLG1CQUFtQjtFQUNsQjtFQUNELEdBQUdBLG1CQUFtQixLQUFLRSxjQUFjLEdBQUc7QUFDaEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0Msb0JBQW9CQSxDQUFDbkYsV0FBbUIsRUFBRTtFQUN6RCxPQUFPMkMsV0FBVyxDQUFDM0MsV0FBVyxFQUFFLEdBQUcsQ0FBQztBQUNyQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzJDLFdBQVdBLENBQUMzQyxXQUFtQixFQUFFb0YsTUFBYyxFQUFrQztFQUFBLElBQWhDL0UsVUFBVSxHQUFBSixTQUFBLENBQUFDLE1BQUEsUUFBQUQsU0FBQSxRQUFBRSxTQUFBLEdBQUFGLFNBQUEsTUFBR1osZUFBZSxDQUFDLENBQUM7RUFDdkYsT0FBT1UscUJBQXFCLENBQUNDLFdBQVcsRUFBRUssVUFBVSxDQUFDLENBQUMrRSxNQUFNLENBQUNBLE1BQU0sQ0FBQztBQUNyRTtBQUVBLE1BQU1DLG9CQUFvQixHQUFJQyxJQUFZLElBQUs7RUFDOUMsSUFBSTtJQUNILE1BQU1YLElBQUksR0FBR1ksUUFBUSxDQUFDQyxhQUFhLENBQUMsT0FBTyxDQUFDO0lBQzVDYixJQUFJLENBQUNXLElBQUksR0FBR0EsSUFBSTtJQUNoQixNQUFNRyxXQUFXLEdBQUdkLElBQUksQ0FBQ1csSUFBSSxLQUFLQSxJQUFJO0lBQ3RDLE9BQU9HLFdBQVc7RUFDbkIsQ0FBQyxDQUFDLE1BQU07SUFDUCxPQUFPLEtBQUs7RUFDYjtBQUNELENBQUM7QUFFRCxPQUFPLE1BQU1DLG9CQUFvQixHQUFHTCxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7QUFFaEUsT0FBTyxNQUFNTSxvQkFBb0IsR0FBR04sb0JBQW9CLENBQUMsTUFBTSxDQUFDO0FBRWhFLE9BQU8sU0FBU08sZUFBZUEsQ0FBQ3JFLFFBQXVCLEVBQUU7RUFDeEQsT0FBTyxDQUFDLENBQUNBLFFBQVEsSUFBSXJDLE1BQU0sQ0FBQ3FDLFFBQVEsQ0FBQyxDQUFDc0UsT0FBTyxDQUFDLENBQUM7QUFDaEQiLCJpZ25vcmVMaXN0IjpbXX0=
|