@cedx/base 0.26.0 → 0.28.0
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/ReadMe.md +1 -1
- package/lib/Date.d.ts +5 -0
- package/lib/Date.d.ts.map +1 -1
- package/lib/Date.js +14 -5
- package/lib/TimeSpan.d.ts +46 -0
- package/lib/TimeSpan.d.ts.map +1 -0
- package/lib/TimeSpan.js +45 -0
- package/lib/UI/Components/FullScreenToggler.d.ts +1 -1
- package/lib/UI/Components/FullScreenToggler.js +3 -3
- package/lib/UI/Components/Toaster.js +1 -1
- package/lib/UI/Components/TypeAhead.d.ts +53 -0
- package/lib/UI/Components/TypeAhead.d.ts.map +1 -0
- package/lib/UI/Components/TypeAhead.js +138 -0
- package/lib/UI/DialogResult.d.ts +0 -4
- package/lib/UI/DialogResult.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Client/Date.ts +15 -5
- package/src/Client/TimeSpan.ts +55 -0
- package/src/Client/UI/Components/FullScreenToggler.ts +3 -3
- package/src/Client/UI/Components/Toaster.ts +1 -1
- package/src/Client/UI/Components/TypeAhead.ts +153 -0
- package/src/Client/UI/DialogResult.ts +0 -5
- package/lib/Duration.d.ts +0 -26
- package/lib/Duration.d.ts.map +0 -1
- package/lib/Duration.js +0 -21
- package/src/Client/Duration.ts +0 -30
package/ReadMe.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Cédric Belin's Base
|
|
2
|
-
   
|
|
3
3
|
|
|
4
4
|
Base library by [Cédric Belin](https://cedric-belin.fr), full stack developer,
|
|
5
5
|
implemented in [C#](https://learn.microsoft.com/en-us/dotnet/csharp) and [TypeScript](https://www.typescriptlang.org).
|
package/lib/Date.d.ts
CHANGED
|
@@ -52,6 +52,11 @@ export declare function isHoliday(date: Date): boolean;
|
|
|
52
52
|
* @returns `true` if the specified date is a working day, otherwise `false`.
|
|
53
53
|
*/
|
|
54
54
|
export declare function isWorkingDay(date: Date): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Gets the current date.
|
|
57
|
+
* @returns The current date.
|
|
58
|
+
*/
|
|
59
|
+
export declare function today(): Date;
|
|
55
60
|
/**
|
|
56
61
|
* Converts the specified date to an ISO 8601 week.
|
|
57
62
|
* @param date The date to convert.
|
package/lib/Date.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Date.d.ts","sourceRoot":"","sources":["../src/Client/Date.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAc1C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,CAqB9C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG7C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAGhD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,MAAM,CAM7H"}
|
|
1
|
+
{"version":3,"file":"Date.d.ts","sourceRoot":"","sources":["../src/Client/Date.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAc1C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,CAqB9C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG7C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAGhD;AAED;;;GAGG;AACH,wBAAgB,KAAK,IAAI,IAAI,CAI5B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,MAAM,CAM7H"}
|
package/lib/Date.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TimeSpan } from "./TimeSpan.js";
|
|
2
2
|
/**
|
|
3
3
|
* Returns the date at midnight corresponding to the specified date.
|
|
4
4
|
* @param date The source date.
|
|
@@ -52,9 +52,9 @@ export function getHolidays(date) {
|
|
|
52
52
|
holidays.push(new Date(year, 11, 25)); // Christmas.
|
|
53
53
|
// Holidays depending on Easter.
|
|
54
54
|
const easter = getEaster(date);
|
|
55
|
-
holidays.push(new Date(easter.getTime() +
|
|
56
|
-
holidays.push(new Date(easter.getTime() + (39 *
|
|
57
|
-
holidays.push(new Date(easter.getTime() + (50 *
|
|
55
|
+
holidays.push(new Date(easter.getTime() + TimeSpan.MillisecondsPerDay)); // Easter monday.
|
|
56
|
+
holidays.push(new Date(easter.getTime() + (39 * TimeSpan.MillisecondsPerDay))); // Ascension thursday.
|
|
57
|
+
holidays.push(new Date(easter.getTime() + (50 * TimeSpan.MillisecondsPerDay))); // Pentecost monday.
|
|
58
58
|
return holidays;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
@@ -73,7 +73,7 @@ export function getQuarter(date) {
|
|
|
73
73
|
export function getWeekOfYear(date) {
|
|
74
74
|
const thursday = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 3 - ((date.getDay() + 6) % 7));
|
|
75
75
|
const firstWeek = new Date(thursday.getFullYear(), 0, 4);
|
|
76
|
-
return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) /
|
|
76
|
+
return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) / TimeSpan.MillisecondsPerDay) - 3 + ((firstWeek.getDay() + 6) % 7)) / 7);
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
79
|
* Returns a value indicating whether the specified date is in a leap year.
|
|
@@ -102,6 +102,15 @@ export function isWorkingDay(date) {
|
|
|
102
102
|
const dayOfWeek = date.getDay();
|
|
103
103
|
return dayOfWeek >= 1 && dayOfWeek <= 5;
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets the current date.
|
|
107
|
+
* @returns The current date.
|
|
108
|
+
*/
|
|
109
|
+
export function today() {
|
|
110
|
+
const date = new Date;
|
|
111
|
+
date.setHours(0, 0, 0, 0);
|
|
112
|
+
return date;
|
|
113
|
+
}
|
|
105
114
|
/**
|
|
106
115
|
* Converts the specified date to an ISO 8601 week.
|
|
107
116
|
* @param date The date to convert.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides some common time intervals in milliseconds.
|
|
3
|
+
*/
|
|
4
|
+
export declare const TimeSpan: Readonly<{
|
|
5
|
+
/**
|
|
6
|
+
* The number of hours in 1 day.
|
|
7
|
+
*/
|
|
8
|
+
HoursPerDay: 24;
|
|
9
|
+
/**
|
|
10
|
+
* The number of minutes in 1 day.
|
|
11
|
+
*/
|
|
12
|
+
MinutesPerDay: 1440;
|
|
13
|
+
/**
|
|
14
|
+
* The number of minutes in 1 hour.
|
|
15
|
+
*/
|
|
16
|
+
MinutesPerHour: 60;
|
|
17
|
+
/**
|
|
18
|
+
* The number of seconds in 1 day.
|
|
19
|
+
*/
|
|
20
|
+
SecondsPerDay: 86400;
|
|
21
|
+
/**
|
|
22
|
+
* The number of seconds in 1 hour.
|
|
23
|
+
*/
|
|
24
|
+
SecondsPerHour: 3600;
|
|
25
|
+
/**
|
|
26
|
+
* The number of seconds in 1 minute.
|
|
27
|
+
*/
|
|
28
|
+
SecondsPerMinute: 60;
|
|
29
|
+
/**
|
|
30
|
+
* The number of milliseconds in 1 day.
|
|
31
|
+
*/
|
|
32
|
+
MillisecondsPerDay: 86400000;
|
|
33
|
+
/**
|
|
34
|
+
* The number of milliseconds in 1 hour.
|
|
35
|
+
*/
|
|
36
|
+
MillisecondsPerHour: 3600000;
|
|
37
|
+
/**
|
|
38
|
+
* The number of milliseconds in 1 minute.
|
|
39
|
+
*/
|
|
40
|
+
MillisecondsPerMinute: 60000;
|
|
41
|
+
/**
|
|
42
|
+
* The number of milliseconds in 1 second.
|
|
43
|
+
*/
|
|
44
|
+
MillisecondsPerSecond: 1000;
|
|
45
|
+
}>;
|
|
46
|
+
//# sourceMappingURL=TimeSpan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeSpan.d.ts","sourceRoot":"","sources":["../src/Client/TimeSpan.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;IAEpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC"}
|
package/lib/TimeSpan.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides some common time intervals in milliseconds.
|
|
3
|
+
*/
|
|
4
|
+
export const TimeSpan = Object.freeze({
|
|
5
|
+
/**
|
|
6
|
+
* The number of hours in 1 day.
|
|
7
|
+
*/
|
|
8
|
+
HoursPerDay: 24,
|
|
9
|
+
/**
|
|
10
|
+
* The number of minutes in 1 day.
|
|
11
|
+
*/
|
|
12
|
+
MinutesPerDay: 1_440,
|
|
13
|
+
/**
|
|
14
|
+
* The number of minutes in 1 hour.
|
|
15
|
+
*/
|
|
16
|
+
MinutesPerHour: 60,
|
|
17
|
+
/**
|
|
18
|
+
* The number of seconds in 1 day.
|
|
19
|
+
*/
|
|
20
|
+
SecondsPerDay: 86_400,
|
|
21
|
+
/**
|
|
22
|
+
* The number of seconds in 1 hour.
|
|
23
|
+
*/
|
|
24
|
+
SecondsPerHour: 3_600,
|
|
25
|
+
/**
|
|
26
|
+
* The number of seconds in 1 minute.
|
|
27
|
+
*/
|
|
28
|
+
SecondsPerMinute: 60,
|
|
29
|
+
/**
|
|
30
|
+
* The number of milliseconds in 1 day.
|
|
31
|
+
*/
|
|
32
|
+
MillisecondsPerDay: 86_400_000,
|
|
33
|
+
/**
|
|
34
|
+
* The number of milliseconds in 1 hour.
|
|
35
|
+
*/
|
|
36
|
+
MillisecondsPerHour: 3_600_000,
|
|
37
|
+
/**
|
|
38
|
+
* The number of milliseconds in 1 minute.
|
|
39
|
+
*/
|
|
40
|
+
MillisecondsPerMinute: 60_000,
|
|
41
|
+
/**
|
|
42
|
+
* The number of milliseconds in 1 second.
|
|
43
|
+
*/
|
|
44
|
+
MillisecondsPerSecond: 1_000
|
|
45
|
+
});
|
|
@@ -28,7 +28,7 @@ export declare class FullScreenToggler extends HTMLElement {
|
|
|
28
28
|
/**
|
|
29
29
|
* Toggles the full-screen mode of the associated element.
|
|
30
30
|
* @param event The dispatched event.
|
|
31
|
-
* @returns
|
|
31
|
+
* @returns Completes when the full-screen mode has been toggled.
|
|
32
32
|
*/
|
|
33
33
|
toggleFullScreen(event?: Event): Promise<void>;
|
|
34
34
|
}
|
|
@@ -60,7 +60,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
60
60
|
/**
|
|
61
61
|
* Toggles the full-screen mode of the associated element.
|
|
62
62
|
* @param event The dispatched event.
|
|
63
|
-
* @returns
|
|
63
|
+
* @returns Completes when the full-screen mode has been toggled.
|
|
64
64
|
*/
|
|
65
65
|
async toggleFullScreen(event) {
|
|
66
66
|
event?.stopPropagation();
|
|
@@ -71,7 +71,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
73
|
* Acquires a new wake lock.
|
|
74
|
-
* @returns
|
|
74
|
+
* @returns Completes when the wake lock has been acquired.
|
|
75
75
|
*/
|
|
76
76
|
async #acquireWakeLock() {
|
|
77
77
|
if (this.#sentinel && !this.#sentinel.released)
|
|
@@ -99,7 +99,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
99
99
|
};
|
|
100
100
|
/**
|
|
101
101
|
* Releases the acquired wake lock.
|
|
102
|
-
* @returns
|
|
102
|
+
* @returns Completes when the wake lock has been released.
|
|
103
103
|
*/
|
|
104
104
|
async #releaseWakeLock() {
|
|
105
105
|
if (!this.#sentinel || this.#sentinel.released)
|
|
@@ -60,7 +60,7 @@ export class Toaster extends HTMLElement {
|
|
|
60
60
|
*/
|
|
61
61
|
get delay() {
|
|
62
62
|
const value = Number(this.getAttribute("delay"));
|
|
63
|
-
return Math.max(
|
|
63
|
+
return Math.max(0, Number.isNaN(value) ? 5_000 : value);
|
|
64
64
|
}
|
|
65
65
|
set delay(value) {
|
|
66
66
|
this.setAttribute("delay", value.toString());
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A component that moves back in the session history when clicked.
|
|
3
|
+
*/
|
|
4
|
+
export declare class TypeAhead extends HTMLElement {
|
|
5
|
+
#private;
|
|
6
|
+
/**
|
|
7
|
+
* The list of observed attributes.
|
|
8
|
+
*/
|
|
9
|
+
static readonly observedAttributes: string[];
|
|
10
|
+
/**
|
|
11
|
+
* The delay in milliseconds to wait before triggering autocomplete suggestions.
|
|
12
|
+
*/
|
|
13
|
+
get delay(): number;
|
|
14
|
+
set delay(value: number);
|
|
15
|
+
/**
|
|
16
|
+
* The function invoked when the query has been changed.
|
|
17
|
+
*/
|
|
18
|
+
set handler(callback: (query: string) => Promise<string[]>);
|
|
19
|
+
/**
|
|
20
|
+
* The data list identifier.
|
|
21
|
+
*/
|
|
22
|
+
get list(): string;
|
|
23
|
+
set list(value: string);
|
|
24
|
+
/**
|
|
25
|
+
* The minimum character length needed before triggering autocomplete suggestions.
|
|
26
|
+
*/
|
|
27
|
+
get minLength(): number;
|
|
28
|
+
set minLength(value: number);
|
|
29
|
+
/**
|
|
30
|
+
* The query to look up.
|
|
31
|
+
*/
|
|
32
|
+
get query(): string;
|
|
33
|
+
set query(value: string);
|
|
34
|
+
/**
|
|
35
|
+
* Method invoked when an attribute has been changed.
|
|
36
|
+
* @param attribute The attribute name.
|
|
37
|
+
* @param oldValue The previous attribute value.
|
|
38
|
+
* @param newValue The new attribute value.
|
|
39
|
+
*/
|
|
40
|
+
attributeChangedCallback(attribute: string, oldValue: string | null, newValue: string | null): void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Declaration merging.
|
|
44
|
+
*/
|
|
45
|
+
declare global {
|
|
46
|
+
/**
|
|
47
|
+
* The map of HTML tag names.
|
|
48
|
+
*/
|
|
49
|
+
interface HTMLElementTagNameMap {
|
|
50
|
+
"type-ahead": TypeAhead;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=TypeAhead.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeAhead.d.ts","sourceRoot":"","sources":["../../../src/Client/UI/Components/TypeAhead.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,SAAU,SAAQ,WAAW;;IAEzC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,WAAqB;IAmBvD;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAGlB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;OAEG;IACH,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,EAKzD;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAErB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAGtB;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAE1B;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAC,IAAI,GAAG,IAAI;CAsD/F;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,YAAY,EAAE,SAAS,CAAC;KACxB;CACD"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A component that moves back in the session history when clicked.
|
|
3
|
+
*/
|
|
4
|
+
export class TypeAhead extends HTMLElement {
|
|
5
|
+
/**
|
|
6
|
+
* The list of observed attributes.
|
|
7
|
+
*/
|
|
8
|
+
static observedAttributes = ["list", "query"];
|
|
9
|
+
/**
|
|
10
|
+
* The debounced handler used to look up the query.
|
|
11
|
+
*/
|
|
12
|
+
#debounced = () => { };
|
|
13
|
+
/**
|
|
14
|
+
* The previous query.
|
|
15
|
+
*/
|
|
16
|
+
#previousQuery = "";
|
|
17
|
+
/**
|
|
18
|
+
* Registers the component.
|
|
19
|
+
*/
|
|
20
|
+
static {
|
|
21
|
+
customElements.define("type-ahead", this);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The delay in milliseconds to wait before triggering autocomplete suggestions.
|
|
25
|
+
*/
|
|
26
|
+
get delay() {
|
|
27
|
+
const value = Number(this.getAttribute("delay"));
|
|
28
|
+
return Math.max(0, Number.isNaN(value) ? 300 : value);
|
|
29
|
+
}
|
|
30
|
+
set delay(value) {
|
|
31
|
+
this.setAttribute("delay", value.toString());
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The function invoked when the query has been changed.
|
|
35
|
+
*/
|
|
36
|
+
set handler(callback) {
|
|
37
|
+
this.#debounced = this.#debounce(async (query) => {
|
|
38
|
+
try {
|
|
39
|
+
this.#updateItems(await callback(query));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
this.#updateItems([]);
|
|
43
|
+
}
|
|
44
|
+
}, this.delay);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The data list identifier.
|
|
48
|
+
*/
|
|
49
|
+
get list() {
|
|
50
|
+
return (this.getAttribute("list") ?? "").trim();
|
|
51
|
+
}
|
|
52
|
+
set list(value) {
|
|
53
|
+
this.setAttribute("list", value);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The minimum character length needed before triggering autocomplete suggestions.
|
|
57
|
+
*/
|
|
58
|
+
get minLength() {
|
|
59
|
+
const value = Number(this.getAttribute("minlength"));
|
|
60
|
+
return Math.max(1, Number.isNaN(value) ? 1 : value);
|
|
61
|
+
}
|
|
62
|
+
set minLength(value) {
|
|
63
|
+
this.setAttribute("minlength", value.toString());
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The query to look up.
|
|
67
|
+
*/
|
|
68
|
+
get query() {
|
|
69
|
+
return (this.getAttribute("query") ?? "").trim();
|
|
70
|
+
}
|
|
71
|
+
set query(value) {
|
|
72
|
+
this.setAttribute("query", value);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Method invoked when an attribute has been changed.
|
|
76
|
+
* @param attribute The attribute name.
|
|
77
|
+
* @param oldValue The previous attribute value.
|
|
78
|
+
* @param newValue The new attribute value.
|
|
79
|
+
*/
|
|
80
|
+
attributeChangedCallback(attribute, oldValue, newValue) {
|
|
81
|
+
if (newValue != oldValue)
|
|
82
|
+
switch (attribute) {
|
|
83
|
+
case "list":
|
|
84
|
+
this.#updateList(newValue ?? "");
|
|
85
|
+
break;
|
|
86
|
+
case "query":
|
|
87
|
+
this.#updateQuery(newValue ?? "");
|
|
88
|
+
break;
|
|
89
|
+
// No default
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Postpones the invocation of the specified callback until after a given delay has elapsed since the last time it was invoked.
|
|
94
|
+
* @param callback The function to debounce.
|
|
95
|
+
* @param delay The delay to wait, in milliseconds.
|
|
96
|
+
* @returns The debounced function.
|
|
97
|
+
*/
|
|
98
|
+
#debounce(callback, delay) {
|
|
99
|
+
let timer = 0;
|
|
100
|
+
return value => {
|
|
101
|
+
if (timer)
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
timer = window.setTimeout(callback, delay, value);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Updates the identifier of the underlying data list.
|
|
108
|
+
* @param value The new value.
|
|
109
|
+
*/
|
|
110
|
+
#updateList(value) {
|
|
111
|
+
this.firstElementChild.id = value.trim();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Updates the query to look up.
|
|
115
|
+
* @param value The new value.
|
|
116
|
+
*/
|
|
117
|
+
#updateQuery(value) {
|
|
118
|
+
const query = value.trim();
|
|
119
|
+
if (query != this.#previousQuery) {
|
|
120
|
+
this.#previousQuery = query;
|
|
121
|
+
if (query.length < this.minLength)
|
|
122
|
+
this.#updateItems([]);
|
|
123
|
+
else
|
|
124
|
+
this.#debounced(query);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Updates the items of the underlying data list.
|
|
129
|
+
* @param values The new values.
|
|
130
|
+
*/
|
|
131
|
+
#updateItems(values) {
|
|
132
|
+
this.firstElementChild.replaceChildren(...values.map(value => {
|
|
133
|
+
const option = document.createElement("option");
|
|
134
|
+
option.value = value;
|
|
135
|
+
return option;
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
package/lib/UI/DialogResult.d.ts
CHANGED
|
@@ -27,8 +27,4 @@ export declare const DialogResult: Readonly<{
|
|
|
27
27
|
*/
|
|
28
28
|
Ignore: "Ignore";
|
|
29
29
|
}>;
|
|
30
|
-
/**
|
|
31
|
-
* Specifies the return value of a dialog box.
|
|
32
|
-
*/
|
|
33
|
-
export type DialogResult = typeof DialogResult[keyof typeof DialogResult];
|
|
34
30
|
//# sourceMappingURL=DialogResult.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogResult.d.ts","sourceRoot":"","sources":["../../src/Client/UI/DialogResult.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY;IAExB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC
|
|
1
|
+
{"version":3,"file":"DialogResult.d.ts","sourceRoot":"","sources":["../../src/Client/UI/DialogResult.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY;IAExB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC"}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"name": "@cedx/base",
|
|
8
8
|
"repository": "cedx/base",
|
|
9
9
|
"type": "module",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.28.0",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@playwright/browser-chromium": "^1.55.0",
|
|
13
13
|
"@types/bootstrap": "^5.2.10",
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"chai": "^6.0.1",
|
|
19
19
|
"esbuild": "^0.25.9",
|
|
20
20
|
"globals": "^16.3.0",
|
|
21
|
-
"mocha": "^11.7.
|
|
21
|
+
"mocha": "^11.7.2",
|
|
22
22
|
"playwright": "^1.55.0",
|
|
23
23
|
"serve-handler": "^6.1.6",
|
|
24
24
|
"typedoc": "^0.28.12",
|
|
25
25
|
"typescript": "^5.9.2",
|
|
26
|
-
"typescript-eslint": "^8.
|
|
26
|
+
"typescript-eslint": "^8.42.0"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=24.0.0"
|
package/src/Client/Date.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {TimeSpan} from "./TimeSpan.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns the date at midnight corresponding to the specified date.
|
|
@@ -60,9 +60,9 @@ export function getHolidays(date: Date): Date[] {
|
|
|
60
60
|
|
|
61
61
|
// Holidays depending on Easter.
|
|
62
62
|
const easter = getEaster(date);
|
|
63
|
-
holidays.push(new Date(easter.getTime() +
|
|
64
|
-
holidays.push(new Date(easter.getTime() + (39 *
|
|
65
|
-
holidays.push(new Date(easter.getTime() + (50 *
|
|
63
|
+
holidays.push(new Date(easter.getTime() + TimeSpan.MillisecondsPerDay)); // Easter monday.
|
|
64
|
+
holidays.push(new Date(easter.getTime() + (39 * TimeSpan.MillisecondsPerDay))); // Ascension thursday.
|
|
65
|
+
holidays.push(new Date(easter.getTime() + (50 * TimeSpan.MillisecondsPerDay))); // Pentecost monday.
|
|
66
66
|
|
|
67
67
|
return holidays;
|
|
68
68
|
}
|
|
@@ -84,7 +84,7 @@ export function getQuarter(date: Date): number {
|
|
|
84
84
|
export function getWeekOfYear(date: Date): number {
|
|
85
85
|
const thursday = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 3 - ((date.getDay() + 6) % 7));
|
|
86
86
|
const firstWeek = new Date(thursday.getFullYear(), 0, 4);
|
|
87
|
-
return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) /
|
|
87
|
+
return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) / TimeSpan.MillisecondsPerDay) - 3 + ((firstWeek.getDay() + 6) % 7)) / 7);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
@@ -117,6 +117,16 @@ export function isWorkingDay(date: Date): boolean {
|
|
|
117
117
|
return dayOfWeek >= 1 && dayOfWeek <= 5;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Gets the current date.
|
|
122
|
+
* @returns The current date.
|
|
123
|
+
*/
|
|
124
|
+
export function today(): Date {
|
|
125
|
+
const date = new Date;
|
|
126
|
+
date.setHours(0, 0, 0, 0);
|
|
127
|
+
return date;
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
/**
|
|
121
131
|
* Converts the specified date to an ISO 8601 week.
|
|
122
132
|
* @param date The date to convert.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides some common time intervals in milliseconds.
|
|
3
|
+
*/
|
|
4
|
+
export const TimeSpan = Object.freeze({
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The number of hours in 1 day.
|
|
8
|
+
*/
|
|
9
|
+
HoursPerDay: 24,
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The number of minutes in 1 day.
|
|
13
|
+
*/
|
|
14
|
+
MinutesPerDay: 1_440,
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The number of minutes in 1 hour.
|
|
18
|
+
*/
|
|
19
|
+
MinutesPerHour: 60,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The number of seconds in 1 day.
|
|
23
|
+
*/
|
|
24
|
+
SecondsPerDay: 86_400,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The number of seconds in 1 hour.
|
|
28
|
+
*/
|
|
29
|
+
SecondsPerHour: 3_600,
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The number of seconds in 1 minute.
|
|
33
|
+
*/
|
|
34
|
+
SecondsPerMinute: 60,
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The number of milliseconds in 1 day.
|
|
38
|
+
*/
|
|
39
|
+
MillisecondsPerDay: 86_400_000,
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The number of milliseconds in 1 hour.
|
|
43
|
+
*/
|
|
44
|
+
MillisecondsPerHour: 3_600_000,
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The number of milliseconds in 1 minute.
|
|
48
|
+
*/
|
|
49
|
+
MillisecondsPerMinute: 60_000,
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The number of milliseconds in 1 second.
|
|
53
|
+
*/
|
|
54
|
+
MillisecondsPerSecond: 1_000
|
|
55
|
+
});
|
|
@@ -69,7 +69,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
69
69
|
/**
|
|
70
70
|
* Toggles the full-screen mode of the associated element.
|
|
71
71
|
* @param event The dispatched event.
|
|
72
|
-
* @returns
|
|
72
|
+
* @returns Completes when the full-screen mode has been toggled.
|
|
73
73
|
*/
|
|
74
74
|
async toggleFullScreen(event?: Event): Promise<void> {
|
|
75
75
|
event?.stopPropagation();
|
|
@@ -79,7 +79,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* Acquires a new wake lock.
|
|
82
|
-
* @returns
|
|
82
|
+
* @returns Completes when the wake lock has been acquired.
|
|
83
83
|
*/
|
|
84
84
|
async #acquireWakeLock(): Promise<void> {
|
|
85
85
|
if (this.#sentinel && !this.#sentinel.released) return;
|
|
@@ -105,7 +105,7 @@ export class FullScreenToggler extends HTMLElement {
|
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Releases the acquired wake lock.
|
|
108
|
-
* @returns
|
|
108
|
+
* @returns Completes when the wake lock has been released.
|
|
109
109
|
*/
|
|
110
110
|
async #releaseWakeLock(): Promise<void> {
|
|
111
111
|
if (!this.#sentinel || this.#sentinel.released) return;
|
|
@@ -115,7 +115,7 @@ export class Toaster extends HTMLElement {
|
|
|
115
115
|
*/
|
|
116
116
|
get delay(): number {
|
|
117
117
|
const value = Number(this.getAttribute("delay"));
|
|
118
|
-
return Math.max(
|
|
118
|
+
return Math.max(0, Number.isNaN(value) ? 5_000 : value);
|
|
119
119
|
}
|
|
120
120
|
set delay(value: number) {
|
|
121
121
|
this.setAttribute("delay", value.toString());
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A component that moves back in the session history when clicked.
|
|
3
|
+
*/
|
|
4
|
+
export class TypeAhead extends HTMLElement {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The list of observed attributes.
|
|
8
|
+
*/
|
|
9
|
+
static readonly observedAttributes = ["list", "query"];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The debounced handler used to look up the query.
|
|
13
|
+
*/
|
|
14
|
+
#debounced: (value: string) => void = () => { /* Noop */ };
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The previous query.
|
|
18
|
+
*/
|
|
19
|
+
#previousQuery = "";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Registers the component.
|
|
23
|
+
*/
|
|
24
|
+
static {
|
|
25
|
+
customElements.define("type-ahead", this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The delay in milliseconds to wait before triggering autocomplete suggestions.
|
|
30
|
+
*/
|
|
31
|
+
get delay(): number {
|
|
32
|
+
const value = Number(this.getAttribute("delay"));
|
|
33
|
+
return Math.max(0, Number.isNaN(value) ? 300 : value);
|
|
34
|
+
}
|
|
35
|
+
set delay(value: number) {
|
|
36
|
+
this.setAttribute("delay", value.toString());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The function invoked when the query has been changed.
|
|
41
|
+
*/
|
|
42
|
+
set handler(callback: (query: string) => Promise<string[]>) { // eslint-disable-line accessor-pairs
|
|
43
|
+
this.#debounced = this.#debounce(async query => { // eslint-disable-line @typescript-eslint/no-misused-promises
|
|
44
|
+
try { this.#updateItems(await callback(query)); }
|
|
45
|
+
catch { this.#updateItems([]); }
|
|
46
|
+
}, this.delay);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The data list identifier.
|
|
51
|
+
*/
|
|
52
|
+
get list(): string {
|
|
53
|
+
return (this.getAttribute("list") ?? "").trim();
|
|
54
|
+
}
|
|
55
|
+
set list(value: string) {
|
|
56
|
+
this.setAttribute("list", value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The minimum character length needed before triggering autocomplete suggestions.
|
|
61
|
+
*/
|
|
62
|
+
get minLength(): number {
|
|
63
|
+
const value = Number(this.getAttribute("minlength"));
|
|
64
|
+
return Math.max(1, Number.isNaN(value) ? 1 : value);
|
|
65
|
+
}
|
|
66
|
+
set minLength(value: number) {
|
|
67
|
+
this.setAttribute("minlength", value.toString());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The query to look up.
|
|
72
|
+
*/
|
|
73
|
+
get query(): string {
|
|
74
|
+
return (this.getAttribute("query") ?? "").trim();
|
|
75
|
+
}
|
|
76
|
+
set query(value: string) {
|
|
77
|
+
this.setAttribute("query", value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Method invoked when an attribute has been changed.
|
|
82
|
+
* @param attribute The attribute name.
|
|
83
|
+
* @param oldValue The previous attribute value.
|
|
84
|
+
* @param newValue The new attribute value.
|
|
85
|
+
*/
|
|
86
|
+
attributeChangedCallback(attribute: string, oldValue: string|null, newValue: string|null): void {
|
|
87
|
+
if (newValue != oldValue) switch (attribute) {
|
|
88
|
+
case "list": this.#updateList(newValue ?? ""); break;
|
|
89
|
+
case "query": this.#updateQuery(newValue ?? ""); break;
|
|
90
|
+
// No default
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Postpones the invocation of the specified callback until after a given delay has elapsed since the last time it was invoked.
|
|
96
|
+
* @param callback The function to debounce.
|
|
97
|
+
* @param delay The delay to wait, in milliseconds.
|
|
98
|
+
* @returns The debounced function.
|
|
99
|
+
*/
|
|
100
|
+
#debounce(callback: (value: string) => void, delay: number): (value: string) => void {
|
|
101
|
+
let timer = 0;
|
|
102
|
+
return value => {
|
|
103
|
+
if (timer) clearTimeout(timer);
|
|
104
|
+
timer = window.setTimeout(callback, delay, value);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Updates the identifier of the underlying data list.
|
|
110
|
+
* @param value The new value.
|
|
111
|
+
*/
|
|
112
|
+
#updateList(value: string): void {
|
|
113
|
+
this.firstElementChild!.id = value.trim();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Updates the query to look up.
|
|
118
|
+
* @param value The new value.
|
|
119
|
+
*/
|
|
120
|
+
#updateQuery(value: string): void {
|
|
121
|
+
const query = value.trim();
|
|
122
|
+
if (query != this.#previousQuery) {
|
|
123
|
+
this.#previousQuery = query;
|
|
124
|
+
if (query.length < this.minLength) this.#updateItems([]);
|
|
125
|
+
else this.#debounced(query);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Updates the items of the underlying data list.
|
|
131
|
+
* @param values The new values.
|
|
132
|
+
*/
|
|
133
|
+
#updateItems(values: string[]): void {
|
|
134
|
+
this.firstElementChild!.replaceChildren(...values.map(value => {
|
|
135
|
+
const option = document.createElement("option");
|
|
136
|
+
option.value = value;
|
|
137
|
+
return option;
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Declaration merging.
|
|
144
|
+
*/
|
|
145
|
+
declare global {
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The map of HTML tag names.
|
|
149
|
+
*/
|
|
150
|
+
interface HTMLElementTagNameMap {
|
|
151
|
+
"type-ahead": TypeAhead;
|
|
152
|
+
}
|
|
153
|
+
}
|
package/lib/Duration.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provides some common durations in milliseconds.
|
|
3
|
-
*/
|
|
4
|
-
export declare const Duration: Readonly<{
|
|
5
|
-
/**
|
|
6
|
-
* One second.
|
|
7
|
-
*/
|
|
8
|
-
Second: 1000;
|
|
9
|
-
/**
|
|
10
|
-
* One minute.
|
|
11
|
-
*/
|
|
12
|
-
Minute: 60000;
|
|
13
|
-
/**
|
|
14
|
-
* One hour.
|
|
15
|
-
*/
|
|
16
|
-
Hour: 3600000;
|
|
17
|
-
/**
|
|
18
|
-
* One day.
|
|
19
|
-
*/
|
|
20
|
-
Day: 86400000;
|
|
21
|
-
}>;
|
|
22
|
-
/**
|
|
23
|
-
* Provides some common durations in milliseconds.
|
|
24
|
-
*/
|
|
25
|
-
export type Duration = typeof Duration[keyof typeof Duration];
|
|
26
|
-
//# sourceMappingURL=Duration.d.ts.map
|
package/lib/Duration.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Duration.d.ts","sourceRoot":"","sources":["../src/Client/Duration.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;IAEpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC"}
|
package/lib/Duration.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provides some common durations in milliseconds.
|
|
3
|
-
*/
|
|
4
|
-
export const Duration = Object.freeze({
|
|
5
|
-
/**
|
|
6
|
-
* One second.
|
|
7
|
-
*/
|
|
8
|
-
Second: 1_000,
|
|
9
|
-
/**
|
|
10
|
-
* One minute.
|
|
11
|
-
*/
|
|
12
|
-
Minute: 60_000,
|
|
13
|
-
/**
|
|
14
|
-
* One hour.
|
|
15
|
-
*/
|
|
16
|
-
Hour: 3_600_000,
|
|
17
|
-
/**
|
|
18
|
-
* One day.
|
|
19
|
-
*/
|
|
20
|
-
Day: 86_400_000
|
|
21
|
-
});
|
package/src/Client/Duration.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provides some common durations in milliseconds.
|
|
3
|
-
*/
|
|
4
|
-
export const Duration = Object.freeze({
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* One second.
|
|
8
|
-
*/
|
|
9
|
-
Second: 1_000,
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* One minute.
|
|
13
|
-
*/
|
|
14
|
-
Minute: 60_000,
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* One hour.
|
|
18
|
-
*/
|
|
19
|
-
Hour: 3_600_000,
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* One day.
|
|
23
|
-
*/
|
|
24
|
-
Day: 86_400_000
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Provides some common durations in milliseconds.
|
|
29
|
-
*/
|
|
30
|
-
export type Duration = typeof Duration[keyof typeof Duration];
|