dce-reactkit 4.0.0-beta-date-and-time.1 → 4.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.vscode/settings.json +1 -3
  2. package/README.md +20 -0
  3. package/dist/cjs/index.js +167 -392
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/types/components/ItemPicker/index.d.ts +0 -1
  6. package/dist/cjs/types/components/Modal/ModalProps.d.ts +0 -2
  7. package/dist/cjs/types/components/SimpleDateChooser.d.ts +1 -3
  8. package/dist/cjs/types/components/TabBox.d.ts +0 -1
  9. package/dist/cjs/types/index.d.ts +1 -3
  10. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +1 -3
  11. package/dist/esm/index.js +169 -392
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/types/components/ItemPicker/index.d.ts +0 -1
  14. package/dist/esm/types/components/Modal/ModalProps.d.ts +0 -2
  15. package/dist/esm/types/components/SimpleDateChooser.d.ts +1 -3
  16. package/dist/esm/types/components/TabBox.d.ts +0 -1
  17. package/dist/esm/types/index.d.ts +1 -3
  18. package/dist/esm/types/types/ReactKitErrorCode.d.ts +1 -3
  19. package/dist/index.d.ts +17 -55
  20. package/package.json +2 -2
  21. package/src/components/IntelliTable.tsx +1 -1
  22. package/src/components/ItemPicker/NestableItemList.tsx +0 -1
  23. package/src/components/ItemPicker/index.tsx +0 -96
  24. package/src/components/LogReviewer.tsx +2 -2
  25. package/src/components/Modal/ModalProps.ts +0 -4
  26. package/src/components/Modal/index.tsx +20 -59
  27. package/src/components/SimpleDateChooser.tsx +26 -62
  28. package/src/components/TabBox.tsx +9 -27
  29. package/src/index.ts +0 -4
  30. package/src/types/ReactKitErrorCode.tsx +1 -3
  31. package/dist/cjs/types/components/SimpleTimeChooser.d.ts +0 -20
  32. package/dist/cjs/types/helpers/getWordCount.d.ts +0 -10
  33. package/dist/esm/types/components/SimpleTimeChooser.d.ts +0 -20
  34. package/dist/esm/types/helpers/getWordCount.d.ts +0 -10
  35. package/src/components/SimpleTimeChooser.tsx +0 -195
  36. package/src/helpers/getWordCount.ts +0 -26
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useState, useRef, useEffect, useReducer, forwardRef, useContext, useLayoutEffect, createContext, useMemo, useCallback, Component, Fragment } from 'react';
3
- import { faExclamationTriangle, faCircle, faHourglassEnd, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faCalendar, faTag, faHammer, faList, faTimes, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
3
+ import { faExclamationTriangle, faHourglassEnd, faCircle, faDotCircle, faCheckSquare, faHourglass, faClipboard, faChevronDown, faChevronRight, faCloudDownloadAlt, faMinus, faCheckCircle, faXmarkCircle, faSort, faSortDown, faSortUp, faCalendar, faTag, faHammer, faList, faTimes, faSave, faTrash, faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
4
4
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
5
  import { faCircle as faCircle$1, faSquareMinus, faSquare } from '@fortawesome/free-regular-svg-icons';
6
6
 
@@ -29,7 +29,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
29
29
  });
30
30
  }
31
31
 
32
- // Highest error code = DRK36
32
+ // Highest error code = DRK34
33
33
  /**
34
34
  * List of error codes built into the react kit
35
35
  * @author Gabe Abrams
@@ -40,8 +40,6 @@ var ReactKitErrorCode;
40
40
  ReactKitErrorCode["NoCode"] = "DRK2";
41
41
  ReactKitErrorCode["SessionExpired"] = "DRK3";
42
42
  ReactKitErrorCode["NoCACCLSendRequestFunction"] = "DRK7";
43
- ReactKitErrorCode["SimpleDateChooserInvalidDateRange"] = "DRK35";
44
- ReactKitErrorCode["SimpleDateChooserInvalidNumMonths"] = "DRK36";
45
43
  })(ReactKitErrorCode || (ReactKitErrorCode = {}));
46
44
  var ReactKitErrorCode$1 = ReactKitErrorCode;
47
45
 
@@ -873,98 +871,6 @@ function requireReactDom_development () {
873
871
 
874
872
  var ReactDOM = /*@__PURE__*/getDefaultExportFromCjs(reactDom.exports);
875
873
 
876
- /**
877
- * Loading spinner/indicator
878
- * @author Gabe Abrams
879
- */
880
- /*------------------------------------------------------------------------*/
881
- /* -------------------------------- Style ------------------------------- */
882
- /*------------------------------------------------------------------------*/
883
- const style$a = `
884
- /* Container fades in */
885
- .LoadingSpinner-container {
886
- animation-name: LoadingSpinner-container-fade-in;
887
- animation-duration: 0.3s;
888
- animation-delay: 0.4s;
889
- animation-fill-mode: both;
890
- animation-timing-function: ease-out;
891
- }
892
- @keyframes LoadingSpinner-container-fade-in {
893
- 0% {
894
- opacity: 0;
895
- }
896
- 100% {
897
- opacity: 1;
898
- }
899
- }
900
-
901
- /* Blips */
902
- .LoadingSpinner-blip-1,
903
- .LoadingSpinner-blip-2,
904
- .LoadingSpinner-blip-3,
905
- .LoadingSpinner-blip-4 {
906
- font-size: 1.8rem;
907
- opacity: 0.6;
908
- margin-top: 1rem;
909
- margin-bottom: 1rem;
910
- }
911
-
912
- /* First Blip */
913
- .LoadingSpinner-blip-1 {
914
- animation: LoadingSpinner-pop-animation 2s infinite;
915
- }
916
-
917
- /* Second Blip */
918
- .LoadingSpinner-blip-2 {
919
- animation: LoadingSpinner-pop-animation 2s infinite;
920
- -webkit-animation-delay: 0.1s;
921
- animation-delay: 0.1s;
922
- }
923
-
924
- /* Third Blip */
925
- .LoadingSpinner-blip-3 {
926
- animation: LoadingSpinner-pop-animation 2s infinite;
927
- animation-delay: 0.2s;
928
- }
929
-
930
- /* Fourth Blip */
931
- .LoadingSpinner-blip-4 {
932
- animation: LoadingSpinner-pop-animation 2s infinite;
933
- animation-delay: 0.3s;
934
- }
935
-
936
- /* Pop Animation for Each Blip */
937
- @keyframes LoadingSpinner-pop-animation {
938
- 0% {
939
- transform: scale(1.0);
940
- }
941
- 10% {
942
- transform: scale(1.5);
943
- }
944
- 30% {
945
- transform: scale(1.0);
946
- }
947
- 100% {
948
- transform: scale(1.0);
949
- }
950
- }
951
- `;
952
- /*------------------------------------------------------------------------*/
953
- /* ------------------------------ Component ----------------------------- */
954
- /*------------------------------------------------------------------------*/
955
- const LoadingSpinner = () => {
956
- /*------------------------------------------------------------------------*/
957
- /* ------------------------------- Render ------------------------------- */
958
- /*------------------------------------------------------------------------*/
959
- // Add all four blips to a container
960
- return (React__default.createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
961
- React__default.createElement("style", null, style$a),
962
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-1 me-1" }),
963
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-2 me-1" }),
964
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-3 me-1" }),
965
- React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-4" })));
966
- };
967
-
968
874
  /**
969
875
  * Wait for a certain number of ms
970
876
  * @author Gabe Abrams
@@ -1108,7 +1014,6 @@ const BASE_Z_INDEX = 1000000000;
1108
1014
  const BASE_Z_INDEX_ON_TOP = 2000000000;
1109
1015
  // Constants
1110
1016
  const MS_TO_ANIMATE = 200; // Animation duration
1111
- const MS_TO_WAIT_BEFORE_SHOWING_LOADING_INDICATOR = 1000;
1112
1017
  // Modal type to list of buttons
1113
1018
  const modalTypeToModalButtonTypes = {
1114
1019
  [ModalType$1.Okay]: [
@@ -1222,7 +1127,7 @@ const getNextUniqueId = () => {
1222
1127
  /*------------------------------------------------------------------------*/
1223
1128
  /* -------------------------------- Style ------------------------------- */
1224
1129
  /*------------------------------------------------------------------------*/
1225
- const style$9 = `
1130
+ const style$a = `
1226
1131
  .Modal-backdrop {
1227
1132
  position: fixed;
1228
1133
  top: 0;
@@ -1294,14 +1199,13 @@ const Modal = (props) => {
1294
1199
  /*------------------------------------------------------------------------*/
1295
1200
  var _a;
1296
1201
  /* -------------- Props ------------- */
1297
- const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, isLoading, isLoadingCancelable, } = props;
1202
+ const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, } = props;
1298
1203
  // Determine if no header either
1299
1204
  const noHeader = (!title && type === ModalType$1.NoButtons);
1300
1205
  /* -------------- State ------------- */
1301
1206
  // True if animation is in use
1302
1207
  const [animatingIn, setAnimatingIn] = useState(true);
1303
1208
  const [animatingPop, setAnimatingPop] = useState(false);
1304
- const [showModal, setShowModal] = useState(false);
1305
1209
  /* -------------- Refs -------------- */
1306
1210
  // Keep track of whether modal is still mounted
1307
1211
  const mounted = useRef(false);
@@ -1328,16 +1232,6 @@ const Modal = (props) => {
1328
1232
  if (mounted.current) {
1329
1233
  setAnimatingIn(false);
1330
1234
  }
1331
- if (isLoading) {
1332
- // wait before showing modal
1333
- yield waitMs(MS_TO_WAIT_BEFORE_SHOWING_LOADING_INDICATOR);
1334
- if (mounted.current) {
1335
- setShowModal(true);
1336
- }
1337
- }
1338
- else {
1339
- setShowModal(true);
1340
- }
1341
1235
  }))();
1342
1236
  return () => {
1343
1237
  mounted.current = false;
@@ -1404,15 +1298,6 @@ const Modal = (props) => {
1404
1298
  else if (animatingPop) {
1405
1299
  animationClass = 'Modal-animating-pop';
1406
1300
  }
1407
- // default to show close button when not loading and not show close button when loading
1408
- // unless downShowXButton or isLoadingCancelable
1409
- const showCloseButton = (
1410
- // The modal must have an onClose function
1411
- onClose
1412
- // ...and the close button is allowed to be visible
1413
- && !dontShowXButton
1414
- // ...and should not be shown if the modal is loading and not cancelable
1415
- && !(isLoading && !isLoadingCancelable));
1416
1301
  // Render the modal
1417
1302
  const contentToRender = (React__default.createElement("div", { className: "modal show", tabIndex: -1, style: {
1418
1303
  zIndex: baseZIndex,
@@ -1421,7 +1306,7 @@ const Modal = (props) => {
1421
1306
  left: 0,
1422
1307
  right: 0,
1423
1308
  } },
1424
- React__default.createElement("style", null, style$9),
1309
+ React__default.createElement("style", null, style$a),
1425
1310
  React__default.createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: {
1426
1311
  zIndex: baseZIndex + 1,
1427
1312
  }, onClick: () => __awaiter(void 0, void 0, void 0, function* () {
@@ -1439,7 +1324,7 @@ const Modal = (props) => {
1439
1324
  // Handle close
1440
1325
  handleClose(ModalButtonType$1.Cancel);
1441
1326
  }) }),
1442
- showModal && (React__default.createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
1327
+ React__default.createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
1443
1328
  zIndex: baseZIndex + 2,
1444
1329
  // Override sizes for even larger for XL
1445
1330
  width: (size === ModalSize$1.ExtraLarge
@@ -1471,7 +1356,7 @@ const Modal = (props) => {
1471
1356
  ? '1.6rem'
1472
1357
  : undefined),
1473
1358
  } }, title),
1474
- showCloseButton && (React__default.createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
1359
+ (onClose && !dontShowXButton) && (React__default.createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
1475
1360
  backgroundColor: (isDarkModeOn()
1476
1361
  ? 'white'
1477
1362
  : undefined),
@@ -1479,18 +1364,14 @@ const Modal = (props) => {
1479
1364
  // Handle close
1480
1365
  handleClose(ModalButtonType$1.Cancel);
1481
1366
  } })))),
1482
- React__default.createElement("div", { className: "modal-body", style: {
1367
+ children && (React__default.createElement("div", { className: "modal-body", style: {
1483
1368
  color: (isDarkModeOn()
1484
1369
  ? 'white'
1485
1370
  : undefined),
1486
1371
  backgroundColor: (isDarkModeOn()
1487
1372
  ? '#444'
1488
1373
  : undefined),
1489
- } }, isLoading
1490
- ? (React__default.createElement(React__default.Fragment, null,
1491
- React__default.createElement(LoadingSpinner, null),
1492
- React__default.createElement("span", { className: "sr-only" }, "Content loading")))
1493
- : children),
1374
+ } }, children)),
1494
1375
  footer && (React__default.createElement("div", { className: "modal-footer pt-1 pb-1", style: {
1495
1376
  color: (isDarkModeOn()
1496
1377
  ? 'white'
@@ -1501,7 +1382,7 @@ const Modal = (props) => {
1501
1382
  borderTop: (isDarkModeOn()
1502
1383
  ? '0.1rem solid gray'
1503
1384
  : undefined),
1504
- } }, footer)))))));
1385
+ } }, footer))))));
1505
1386
  // Determine which portal to use
1506
1387
  const portalNumber = id.current % NUM_MODAL_PORTALS;
1507
1388
  // Render in a portal
@@ -2072,7 +1953,7 @@ const showSessionExpiredMessage = () => __awaiter(void 0, void 0, void 0, functi
2072
1953
  /*------------------------------------------------------------------------*/
2073
1954
  /* -------------------------------- Style ------------------------------- */
2074
1955
  /*------------------------------------------------------------------------*/
2075
- const style$8 = `
1956
+ const style$9 = `
2076
1957
  .AppWrapper-leave-to-url-notice {
2077
1958
  opacity: 0;
2078
1959
 
@@ -2286,13 +2167,105 @@ const AppWrapper = (props) => {
2286
2167
  /* --------------- Main UI -------------- */
2287
2168
  /*----------------------------------------*/
2288
2169
  return (React__default.createElement(React__default.Fragment, null,
2289
- React__default.createElement("style", null, style$8),
2170
+ React__default.createElement("style", null, style$9),
2290
2171
  React__default.createElement("style", null, tooltipStyle),
2291
2172
  modal,
2292
2173
  customModalPortals,
2293
2174
  body));
2294
2175
  };
2295
2176
 
2177
+ /**
2178
+ * Loading spinner/indicator
2179
+ * @author Gabe Abrams
2180
+ */
2181
+ /*------------------------------------------------------------------------*/
2182
+ /* -------------------------------- Style ------------------------------- */
2183
+ /*------------------------------------------------------------------------*/
2184
+ const style$8 = `
2185
+ /* Container fades in */
2186
+ .LoadingSpinner-container {
2187
+ animation-name: LoadingSpinner-container-fade-in;
2188
+ animation-duration: 0.3s;
2189
+ animation-delay: 0.4s;
2190
+ animation-fill-mode: both;
2191
+ animation-timing-function: ease-out;
2192
+ }
2193
+ @keyframes LoadingSpinner-container-fade-in {
2194
+ 0% {
2195
+ opacity: 0;
2196
+ }
2197
+ 100% {
2198
+ opacity: 1;
2199
+ }
2200
+ }
2201
+
2202
+ /* Blips */
2203
+ .LoadingSpinner-blip-1,
2204
+ .LoadingSpinner-blip-2,
2205
+ .LoadingSpinner-blip-3,
2206
+ .LoadingSpinner-blip-4 {
2207
+ font-size: 1.8rem;
2208
+ opacity: 0.6;
2209
+ margin-top: 1rem;
2210
+ margin-bottom: 1rem;
2211
+ }
2212
+
2213
+ /* First Blip */
2214
+ .LoadingSpinner-blip-1 {
2215
+ animation: LoadingSpinner-pop-animation 2s infinite;
2216
+ }
2217
+
2218
+ /* Second Blip */
2219
+ .LoadingSpinner-blip-2 {
2220
+ animation: LoadingSpinner-pop-animation 2s infinite;
2221
+ -webkit-animation-delay: 0.1s;
2222
+ animation-delay: 0.1s;
2223
+ }
2224
+
2225
+ /* Third Blip */
2226
+ .LoadingSpinner-blip-3 {
2227
+ animation: LoadingSpinner-pop-animation 2s infinite;
2228
+ animation-delay: 0.2s;
2229
+ }
2230
+
2231
+ /* Fourth Blip */
2232
+ .LoadingSpinner-blip-4 {
2233
+ animation: LoadingSpinner-pop-animation 2s infinite;
2234
+ animation-delay: 0.3s;
2235
+ }
2236
+
2237
+ /* Pop Animation for Each Blip */
2238
+ @keyframes LoadingSpinner-pop-animation {
2239
+ 0% {
2240
+ transform: scale(1.0);
2241
+ }
2242
+ 10% {
2243
+ transform: scale(1.5);
2244
+ }
2245
+ 30% {
2246
+ transform: scale(1.0);
2247
+ }
2248
+ 100% {
2249
+ transform: scale(1.0);
2250
+ }
2251
+ }
2252
+ `;
2253
+ /*------------------------------------------------------------------------*/
2254
+ /* ------------------------------ Component ----------------------------- */
2255
+ /*------------------------------------------------------------------------*/
2256
+ const LoadingSpinner = () => {
2257
+ /*------------------------------------------------------------------------*/
2258
+ /* ------------------------------- Render ------------------------------- */
2259
+ /*------------------------------------------------------------------------*/
2260
+ // Add all four blips to a container
2261
+ return (React__default.createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
2262
+ React__default.createElement("style", null, style$8),
2263
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-1 me-1" }),
2264
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-2 me-1" }),
2265
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-3 me-1" }),
2266
+ React__default.createElement(FontAwesomeIcon, { icon: faCircle, className: "LoadingSpinner-blip-4" })));
2267
+ };
2268
+
2296
2269
  /**
2297
2270
  * A box with a tab on the top that holds buttons and other content
2298
2271
  * @author Gabe Abrams
@@ -2324,9 +2297,7 @@ const style$7 = `
2324
2297
 
2325
2298
  /* Container for Title */
2326
2299
  .TabBox-title-container {
2327
- display: flex;
2328
- justify-content: space-between;
2329
- align-items: center;
2300
+ /* Place on Left */
2330
2301
  position: relative;
2331
2302
  left: 0;
2332
2303
  text-align: left;
@@ -2359,19 +2330,6 @@ const style$7 = `
2359
2330
  background: #fdfdfd;
2360
2331
  }
2361
2332
 
2362
- .TabBox-title-right-container {
2363
- display: flex;
2364
- flex-direction: row;
2365
- align-items: bottom;
2366
- height: 2.4rem;
2367
- overflow: visible;
2368
- }
2369
-
2370
- .TabBox-title-right-contents {
2371
- margin-right: 0.5rem;
2372
- margin-bottom: 0.2rem;
2373
- }
2374
-
2375
2333
  /* Make the TabBox's Children Appear Above Title if Overlap Occurs */
2376
2334
  .TabBox-children {
2377
2335
  position: relative;
@@ -2385,16 +2343,19 @@ const TabBox = (props) => {
2385
2343
  /*------------------------------------------------------------------------*/
2386
2344
  /* -------------------------------- Setup ------------------------------- */
2387
2345
  /*------------------------------------------------------------------------*/
2388
- const { title, children, topRightChildren, noBottomPadding, noBottomMargin, } = props;
2346
+ /* -------------- Props ------------- */
2347
+ const { title, children, noBottomPadding, noBottomMargin, } = props;
2389
2348
  /*------------------------------------------------------------------------*/
2390
2349
  /* ------------------------------- Render ------------------------------- */
2391
2350
  /*------------------------------------------------------------------------*/
2351
+ /*----------------------------------------*/
2352
+ /* --------------- Main UI -------------- */
2353
+ /*----------------------------------------*/
2354
+ // Full UI
2392
2355
  return (React__default.createElement("div", { className: `TabBox-container ${noBottomMargin ? '' : 'mb-2'}` },
2393
2356
  React__default.createElement("style", null, style$7),
2394
2357
  React__default.createElement("div", { className: "TabBox-title-container" },
2395
- React__default.createElement("div", { className: "TabBox-title" }, title),
2396
- topRightChildren && (React__default.createElement("div", { className: "TabBox-title-right-container" },
2397
- React__default.createElement("div", { className: "TabBox-title-right-contents" }, topRightChildren)))),
2358
+ React__default.createElement("div", { className: "TabBox-title" }, title)),
2398
2359
  React__default.createElement("div", { className: `TabBox-box ps-2 pt-2 pe-2 ${noBottomPadding ? '' : 'pb-2'}` },
2399
2360
  React__default.createElement("div", { className: "TabBox-children" }, children))));
2400
2361
  };
@@ -2523,19 +2484,6 @@ const ButtonInputGroup = (props) => {
2523
2484
  : children))));
2524
2485
  };
2525
2486
 
2526
- // Constants
2527
- const ORDINALS = ['th', 'st', 'nd', 'rd'];
2528
- /**
2529
- * Get a number's ordinal
2530
- * @author Gabe Abrams
2531
- * @param num the number being analyzed
2532
- * @returns ordinal
2533
- */
2534
- const getOrdinal = (num) => {
2535
- var _a, _b;
2536
- return ((_b = (_a = ORDINALS[(num - 20) % 10]) !== null && _a !== void 0 ? _a : ORDINALS[num]) !== null && _b !== void 0 ? _b : ORDINALS[0]);
2537
- };
2538
-
2539
2487
  const monthNames = [
2540
2488
  { short: 'Jan', full: 'January' },
2541
2489
  { short: 'Feb', full: 'February' },
@@ -2564,6 +2512,19 @@ const getMonthName = (month) => {
2564
2512
  return ((_a = monthNames[month - 1]) !== null && _a !== void 0 ? _a : monthNames[0]);
2565
2513
  };
2566
2514
 
2515
+ // Constants
2516
+ const ORDINALS = ['th', 'st', 'nd', 'rd'];
2517
+ /**
2518
+ * Get a number's ordinal
2519
+ * @author Gabe Abrams
2520
+ * @param num the number being analyzed
2521
+ * @returns ordinal
2522
+ */
2523
+ const getOrdinal = (num) => {
2524
+ var _a, _b;
2525
+ return ((_b = (_a = ORDINALS[(num - 20) % 10]) !== null && _a !== void 0 ? _a : ORDINALS[num]) !== null && _b !== void 0 ? _b : ORDINALS[0]);
2526
+ };
2527
+
2567
2528
  /**
2568
2529
  * Get current time info in US Boston Eastern Time, independent of machine
2569
2530
  * timezone
@@ -2627,7 +2588,6 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2627
2588
  /**
2628
2589
  * A very simple, lightweight date chooser
2629
2590
  * @author Gabe Abrams
2630
- * @author Gardeniu Liu
2631
2591
  */
2632
2592
  /*------------------------------------------------------------------------*/
2633
2593
  /* ------------------------------ Component ----------------------------- */
@@ -2637,7 +2597,7 @@ const SimpleDateChooser = (props) => {
2637
2597
  /* -------------------------------- Setup ------------------------------- */
2638
2598
  /*------------------------------------------------------------------------*/
2639
2599
  /* -------------- Props ------------- */
2640
- const { ariaLabel, name, onChange, numMonthsToShow = 6, dontAllowFuture, dontAllowPast, } = props;
2600
+ const { ariaLabel, name, onChange, chooseFromPast, numMonthsToShow = 6, } = props;
2641
2601
  /*------------------------------------------------------------------------*/
2642
2602
  /* ------------------------------- Render ------------------------------- */
2643
2603
  /*------------------------------------------------------------------------*/
@@ -2649,28 +2609,14 @@ const SimpleDateChooser = (props) => {
2649
2609
  const choices = [];
2650
2610
  let startYear = today.year;
2651
2611
  let startMonth = today.month;
2652
- // Don't allow past or future dates
2653
- if (dontAllowPast && dontAllowFuture) {
2654
- throw new ErrorWithCode('No past or future dates allowed', ReactKitErrorCode$1.SimpleDateChooserInvalidDateRange);
2655
- }
2656
- // Require numMonthsToShow to be positive
2657
- if (numMonthsToShow <= 0) {
2658
- throw new ErrorWithCode('numMonthsToShow must be positive', ReactKitErrorCode$1.SimpleDateChooserInvalidNumMonths);
2659
- }
2660
- // Recalculate startMonth and startYear when allowing past dates
2661
- if (!dontAllowPast) {
2612
+ if (chooseFromPast) {
2662
2613
  startMonth -= Math.max(0, numMonthsToShow - 1);
2663
2614
  while (startMonth <= 0) {
2664
2615
  startMonth += 12;
2665
2616
  startYear -= 1;
2666
2617
  }
2667
2618
  }
2668
- // Calculate total number of months to show
2669
- let totalMonthsToShow = numMonthsToShow;
2670
- if (!dontAllowPast && !dontAllowFuture) {
2671
- totalMonthsToShow = totalMonthsToShow * 2 - 1;
2672
- }
2673
- for (let i = 0; i < totalMonthsToShow; i++) {
2619
+ for (let i = 0; i < numMonthsToShow; i++) {
2674
2620
  // Get month and year info
2675
2621
  const unmoddedMonth = (startMonth + i);
2676
2622
  let month = unmoddedMonth;
@@ -2689,25 +2635,23 @@ const SimpleDateChooser = (props) => {
2689
2635
  // Figure out which days are allowed
2690
2636
  const days = [];
2691
2637
  const numDaysInMonth = (new Date(year, month, 0)).getDate();
2692
- // Current month
2693
- if (month === today.month && year === today.year) {
2694
- // Past selection: add all previous days of the month
2695
- if (!dontAllowPast) {
2696
- for (let day = 1; day < today.day; day++) {
2697
- days.push(day);
2698
- }
2699
- }
2700
- days.push(today.day); // Add current day
2701
- // Future selection: add all remaining days of the month
2702
- if (!dontAllowFuture) {
2703
- for (let day = today.day + 1; day <= numDaysInMonth; day++) {
2704
- days.push(day);
2705
- }
2638
+ if (chooseFromPast) {
2639
+ // Past selection
2640
+ const numDaysToAdd = ((month === today.month)
2641
+ ? today.day // Current month, only add up to today
2642
+ : numDaysInMonth // Past month, add all days
2643
+ );
2644
+ for (let day = 1; day <= numDaysToAdd; day++) {
2645
+ days.push(day);
2706
2646
  }
2707
2647
  }
2708
- else { // Past or future month
2709
- // Include all days in the month
2710
- for (let day = 1; day <= numDaysInMonth; day++) {
2648
+ else {
2649
+ // Future selection: add all remaining days of the month
2650
+ const firstDay = (month === today.month
2651
+ ? today.day // Current month: start at current date
2652
+ : 1 // Future month: start at beginning of month
2653
+ );
2654
+ for (let day = firstDay; day <= numDaysInMonth; day++) {
2711
2655
  days.push(day);
2712
2656
  }
2713
2657
  }
@@ -2727,8 +2671,8 @@ const SimpleDateChooser = (props) => {
2727
2671
  monthOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2728
2672
  onChange(choice.month, choice.days[0], choice.year);
2729
2673
  } }, choice.choiceName));
2730
- // This is the currently selected month
2731
2674
  if (month === choice.month) {
2675
+ // This is the currently selected month
2732
2676
  // Create day options
2733
2677
  choice.days.forEach((dayChoice) => {
2734
2678
  const ordinal = getOrdinal(dayChoice);
@@ -2750,125 +2694,6 @@ const SimpleDateChooser = (props) => {
2750
2694
  } }, dayOptions)));
2751
2695
  };
2752
2696
 
2753
- /**
2754
- * Pad a number with zeros on the left (e.g. 5 becomes 05 with 2 digit padding)
2755
- * @author Gabe Abrams
2756
- * @param num the number to pad
2757
- * @param numDigits the minimum number of digits before the decimal
2758
- * @returns padded number
2759
- */
2760
- const padZerosLeft = (num, numDigits) => {
2761
- // Convert to string
2762
- let out = String(num);
2763
- // Add zeros
2764
- while (out.split('.')[0].length < numDigits) {
2765
- out = `0${out}`;
2766
- }
2767
- // Return
2768
- return out;
2769
- };
2770
-
2771
- /**
2772
- * A very simple, lightweight time chooser
2773
- * @author Gardenia Liu
2774
- */
2775
- /*------------------------------------------------------------------------*/
2776
- /* ------------------------------ Constants ----------------------------- */
2777
- /*------------------------------------------------------------------------*/
2778
- // Allowed intervals between options
2779
- const ALLOWED_INTERVALS = [15, 30, 60]; // min
2780
- // Default interval to use if an unsupported interval is passed in
2781
- const DEFAULT_INTERVAL = ALLOWED_INTERVALS[0]; // min
2782
- /*------------------------------------------------------------------------*/
2783
- /* ------------------------------ Component ----------------------------- */
2784
- /*------------------------------------------------------------------------*/
2785
- const SimpleTimeChooser = (props) => {
2786
- /*------------------------------------------------------------------------*/
2787
- /* -------------------------------- Setup ------------------------------- */
2788
- /*------------------------------------------------------------------------*/
2789
- /* -------------- Props ------------- */
2790
- const { ariaLabel, name, hour, minute, onChange, } = props;
2791
- let { intervalMin = DEFAULT_INTERVAL, } = props;
2792
- // Use default interval if not supported
2793
- if (ALLOWED_INTERVALS.includes(intervalMin)) {
2794
- intervalMin = DEFAULT_INTERVAL;
2795
- }
2796
- /*------------------------------------------------------------------------*/
2797
- /* ------------------------- Component Functions ------------------------ */
2798
- /*------------------------------------------------------------------------*/
2799
- /**
2800
- * Convert number of minutes since midnight into 24hour and minute format
2801
- * @author Gabe Abrams
2802
- * @param minSinceMidnight total minutes since midnight
2803
- * @returns hours (24) and minutes
2804
- */
2805
- const convertMinSinceMidnightToHoursAndMin = (minSinceMidnight) => {
2806
- return {
2807
- hours: Math.floor(minSinceMidnight / 60),
2808
- minutes: minSinceMidnight % 60,
2809
- };
2810
- };
2811
- /**
2812
- * Convert time in minutes into HH:MM format
2813
- * @author Gardenia Liu
2814
- * @param totalMinutes total minutes since midnight
2815
- * @returns formatted time string
2816
- */
2817
- const formatTime = (totalMinutes) => {
2818
- // Handle special cases
2819
- if (totalMinutes === 0) {
2820
- return '12:00 Midnight';
2821
- }
2822
- if (totalMinutes === 12 * 60) {
2823
- return '12:00 Noon';
2824
- }
2825
- // All normal cases:
2826
- const timeInfo = convertMinSinceMidnightToHoursAndMin(totalMinutes);
2827
- let { hours } = timeInfo;
2828
- const { minutes } = timeInfo;
2829
- // Process 24hr -> 12hr
2830
- const isAM = (hours < 12);
2831
- if (hours === 0) {
2832
- hours = 12;
2833
- }
2834
- else if (hours > 12) {
2835
- hours %= 12;
2836
- }
2837
- // Pad with zeros
2838
- const paddedMinutes = padZerosLeft(minutes, 2);
2839
- // Assemble time string
2840
- return `${hours}:${paddedMinutes} ${isAM ? 'AM' : 'PM'}`;
2841
- };
2842
- /*------------------------------------------------------------------------*/
2843
- /* ------------------------------- Render ------------------------------- */
2844
- /*------------------------------------------------------------------------*/
2845
- /*----------------------------------------*/
2846
- /* --------------- Main UI -------------- */
2847
- /*----------------------------------------*/
2848
- // Generate list of time options
2849
- const times = [];
2850
- for (let time = 0; time < 24 * 60; time += intervalMin) {
2851
- times.push(formatTime(time));
2852
- }
2853
- // Create choice options
2854
- const selectedTimeMin = hour * 60 + minute; // minutes since midnight
2855
- const timeOptions = times.map((timeString, timeIndex) => {
2856
- // Create time option
2857
- const numMinutesForChoice = timeIndex * intervalMin;
2858
- // Render the option
2859
- return (React__default.createElement("option", { key: numMinutesForChoice, value: numMinutesForChoice, "aria-label": `choose ${timeString}` }, timeString));
2860
- });
2861
- return (React__default.createElement("div", { className: "SimpleTimeChooser-container", "aria-label": `time chooser with selected time: ${formatTime(selectedTimeMin)}` },
2862
- React__default.createElement("select", { "aria-label": `time for ${ariaLabel}`, className: "custom-select d-inline-block", style: { width: 'auto' }, id: `SimpleTimeChooser-${name}-time`, value: selectedTimeMin, onChange: (e) => {
2863
- // Parse selector value (string)
2864
- const newTime = Number.parseInt(e.target.value, 10);
2865
- // Convert minutes since midnight to hour and minute
2866
- const timeInfo = convertMinSinceMidnightToHoursAndMin(newTime);
2867
- // Notify parent of change
2868
- onChange(timeInfo.hours, timeInfo.minutes);
2869
- } }, timeOptions)));
2870
- };
2871
-
2872
2697
  /**
2873
2698
  * Drawer container
2874
2699
  * @author Gabe Abrams
@@ -3517,7 +3342,7 @@ const NestableItemList = (props) => {
3517
3342
  React__default.createElement(FontAwesomeIcon, { icon: childExpanded[item.id] ? faChevronDown : faChevronRight })))),
3518
3343
  React__default.createElement(CheckboxButton, { className: `NestableItemList-CheckboxButton-${item.id}`, text: item.name, checked: item.isGroup ? allChecked(item.children) : item.checked, dashed: item.isGroup ? !noneChecked(item.children) : false, onChanged: (checked) => {
3519
3344
  onChanged(changeChecked(item.id, checked, items));
3520
- }, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
3345
+ }, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light }),
3521
3346
  (item.isGroup && childExpanded[item.id]) && (React__default.createElement("div", { className: "NestableItemList-children-container", style: {
3522
3347
  paddingLeft: '2.2rem',
3523
3348
  } },
@@ -3540,62 +3365,17 @@ const ItemPicker = (props) => {
3540
3365
  /*------------------------------------------------------------------------*/
3541
3366
  /* -------------- Props ------------- */
3542
3367
  // Destructure all props
3543
- const { title, items, onChanged, noBottomMargin, hideSelectAllOrNoneButtons, } = props;
3368
+ const { title, items, onChanged, noBottomMargin, } = props;
3544
3369
  /*------------------------------------------------------------------------*/
3545
3370
  /* ------------------------- Component Functions ------------------------ */
3546
3371
  /*------------------------------------------------------------------------*/
3547
- /**
3548
- * Updates the checked state of an item (including all children)
3549
- * @author Yuen Ler Chow
3550
- * @param item the item to update
3551
- * @param checked the new checked state
3552
- * @returns the updated item
3553
- */
3554
- const updateItemChecked = (item, checked) => {
3555
- if (item.isGroup) {
3556
- return Object.assign(Object.assign({}, item), { children: item.children.map((child) => {
3557
- return updateItemChecked(child, checked);
3558
- }) });
3559
- }
3560
- return Object.assign(Object.assign({}, item), { checked });
3561
- };
3562
- /**
3563
- * Selects all items in the list
3564
- * @author Yuen Ler Chow
3565
- */
3566
- const handleSelectAll = () => {
3567
- const updatedItems = items.map((item) => {
3568
- return updateItemChecked(item, true);
3569
- });
3570
- onChanged(updatedItems);
3571
- };
3572
- /**
3573
- * Deselects all items in the list
3574
- * @author Yuen Ler Chow
3575
- */
3576
- const handleDeselectAll = () => {
3577
- const updatedItems = items.map((item) => {
3578
- return updateItemChecked(item, false);
3579
- });
3580
- onChanged(updatedItems);
3581
- };
3582
3372
  /*------------------------------------------------------------------------*/
3583
3373
  /* ------------------------------- Render ------------------------------- */
3584
3374
  /*------------------------------------------------------------------------*/
3585
3375
  /*----------------------------------------*/
3586
3376
  /* --------------- Main UI -------------- */
3587
3377
  /*----------------------------------------*/
3588
- // Select all/none
3589
- const selectAllOrNone = (!hideSelectAllOrNoneButtons
3590
- ? (React__default.createElement("div", { className: "d-flex h-100 align-items-end flex-row" },
3591
- React__default.createElement("div", { className: "d-flex justify-content-end" },
3592
- React__default.createElement("div", { className: "me-2", style: { fontSize: '1.2rem' } }, "Select"),
3593
- React__default.createElement("div", { className: "btn-group", role: "group" },
3594
- React__default.createElement("button", { type: "button", style: { borderRight: '0.1rem solid white' }, "aria-label": "Select all contexts", className: "btn btn-secondary py-0", onClick: handleSelectAll }, "All"),
3595
- React__default.createElement("button", { type: "button", "aria-label": "Deselect all contexts", className: "btn btn-secondary py-0", onClick: handleDeselectAll }, "None")))))
3596
- : undefined);
3597
- // Main UI
3598
- return (React__default.createElement(TabBox, { title: title, noBottomMargin: noBottomMargin, topRightChildren: selectAllOrNone },
3378
+ return (React__default.createElement(TabBox, { title: title, noBottomMargin: noBottomMargin },
3599
3379
  React__default.createElement("div", { style: { overflowX: 'auto' } },
3600
3380
  React__default.createElement(NestableItemList, { items: items, onChanged: onChanged }))));
3601
3381
  };
@@ -3967,7 +3747,7 @@ const IntelliTable = (props) => {
3967
3747
  param: column.param,
3968
3748
  visible: checked,
3969
3749
  });
3970
- }, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
3750
+ }, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Secondary }));
3971
3751
  }),
3972
3752
  React__default.createElement("div", { className: "mt-3" }, "Or you can:"),
3973
3753
  React__default.createElement("button", { type: "button", id: `IntelliTable-${id}-select-all-columns`, className: "btn btn-secondary me-2", "aria-label": `show all columns in the ${title} table`, onClick: () => {
@@ -4963,14 +4743,14 @@ const LogReviewer = (props) => {
4963
4743
  if (expandedFilterDrawer) {
4964
4744
  if (expandedFilterDrawer === FilterDrawer.Date) {
4965
4745
  filterDrawer = (React__default.createElement(TabBox, { title: "Date" },
4966
- React__default.createElement(SimpleDateChooser, { ariaLabel: "filter start date", name: "filter-start-date", year: dateFilterState.startDate.year, month: dateFilterState.startDate.month, day: dateFilterState.startDate.day, dontAllowFuture: true, numMonthsToShow: 36, onChange: (month, day, year) => {
4746
+ React__default.createElement(SimpleDateChooser, { ariaLabel: "filter start date", name: "filter-start-date", year: dateFilterState.startDate.year, month: dateFilterState.startDate.month, day: dateFilterState.startDate.day, chooseFromPast: true, numMonthsToShow: 36, onChange: (month, day, year) => {
4967
4747
  dateFilterState.startDate = { month, day, year };
4968
4748
  handleDateRangeUpdated(dateFilterState);
4969
4749
  } }),
4970
4750
  ' ',
4971
4751
  "to",
4972
4752
  ' ',
4973
- React__default.createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: dateFilterState.endDate.year, month: dateFilterState.endDate.month, day: dateFilterState.endDate.day, dontAllowFuture: true, numMonthsToShow: 12, onChange: (month, day, year) => {
4753
+ React__default.createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: dateFilterState.endDate.year, month: dateFilterState.endDate.month, day: dateFilterState.endDate.day, chooseFromPast: true, numMonthsToShow: 12, onChange: (month, day, year) => {
4974
4754
  if (year < dateFilterState.startDate.year
4975
4755
  || (year === dateFilterState.startDate.year
4976
4756
  && month < dateFilterState.startDate.month)
@@ -15450,6 +15230,24 @@ const padDecimalZeros = (num, numDigits) => {
15450
15230
  return out;
15451
15231
  };
15452
15232
 
15233
+ /**
15234
+ * Pad a number with zeros on the left (e.g. 5 becomes 05 with 2 digit padding)
15235
+ * @author Gabe Abrams
15236
+ * @param num the number to pad
15237
+ * @param numDigits the minimum number of digits before the decimal
15238
+ * @returns padded number
15239
+ */
15240
+ const padZerosLeft = (num, numDigits) => {
15241
+ // Convert to string
15242
+ let out = String(num);
15243
+ // Add zeros
15244
+ while (out.split('.')[0].length < numDigits) {
15245
+ out = `0${out}`;
15246
+ }
15247
+ // Return
15248
+ return out;
15249
+ };
15250
+
15453
15251
  /**
15454
15252
  * Stub a server endpoint response
15455
15253
  * @author Gabe Abrams
@@ -16283,27 +16081,6 @@ const shuffleArray = (arr) => {
16283
16081
  return newArr;
16284
16082
  };
16285
16083
 
16286
- const punctuationRegex = /[!@#$%^&*(),.?\/;:'"\-\[\]]/g;
16287
- /**
16288
- * Get number of words in string
16289
- * @author Gardenia Liu
16290
- * @author Allison Zhang
16291
- * @author Gabe Abrams
16292
- * @param text the string to check
16293
- * @returns number of words in the string
16294
- */
16295
- const getWordCount = (text) => {
16296
- const trimmedTextWithoutPunctuation = (text
16297
- // Remove leading and trailing whitespace
16298
- .trim()
16299
- // Remove punctuation
16300
- .replace(punctuationRegex, ''));
16301
- if (trimmedTextWithoutPunctuation.length === 0) {
16302
- return 0;
16303
- }
16304
- return trimmedTextWithoutPunctuation.split(/\s+/g).length;
16305
- };
16306
-
16307
16084
  /**
16308
16085
  * Days of the week
16309
16086
  * @author Gabe Abrams
@@ -16320,5 +16097,5 @@ var DayOfWeek;
16320
16097
  })(DayOfWeek || (DayOfWeek = {}));
16321
16098
  var DayOfWeek$1 = DayOfWeek;
16322
16099
 
16323
- export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
16100
+ export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
16324
16101
  //# sourceMappingURL=index.js.map