@nxgt/material-core 0.1.1 → 0.3.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 +178 -5
- package/dist/file-preview/describe-file.d.ts +30 -0
- package/dist/file-preview/describe-file.d.ts.map +1 -0
- package/dist/file-preview/file-kind.d.ts +41 -0
- package/dist/file-preview/file-kind.d.ts.map +1 -0
- package/dist/file-preview/index.d.ts +10 -0
- package/dist/file-preview/index.d.ts.map +1 -0
- package/dist/file-preview/index.js +260 -0
- package/dist/file-preview/index.js.map +13 -0
- package/dist/file-preview/safe-url.d.ts +22 -0
- package/dist/file-preview/safe-url.d.ts.map +1 -0
- package/dist/file-preview/text-preview.d.ts +32 -0
- package/dist/file-preview/text-preview.d.ts.map +1 -0
- package/dist/lib/date-range.d.ts +84 -0
- package/dist/lib/date-range.d.ts.map +1 -0
- package/dist/lib/date-range.js +105 -0
- package/dist/lib/date-range.js.map +10 -0
- package/dist/lib/format-file-size.d.ts +10 -0
- package/dist/lib/format-file-size.d.ts.map +1 -0
- package/dist/lib/format-file-size.js +17 -0
- package/dist/lib/format-file-size.js.map +10 -0
- package/dist/lib/slider-ticks.d.ts +7 -0
- package/dist/lib/slider-ticks.d.ts.map +1 -0
- package/dist/lib/slider-ticks.js +16 -0
- package/dist/lib/slider-ticks.js.map +10 -0
- package/dist/pdf-viewer/index.d.ts +1 -0
- package/dist/pdf-viewer/index.d.ts.map +1 -1
- package/dist/pdf-viewer/index.js +68 -33
- package/dist/pdf-viewer/index.js.map +6 -4
- package/dist/pdf-viewer/pdf-pin-page.d.ts +16 -0
- package/dist/pdf-viewer/pdf-pin-page.d.ts.map +1 -0
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts +2 -8
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts.map +1 -1
- package/dist/pdf-viewer/pdf-user-input.d.ts +7 -0
- package/dist/pdf-viewer/pdf-user-input.d.ts.map +1 -0
- package/dist/pdfkit-fonts/index.d.ts +61 -0
- package/dist/pdfkit-fonts/index.d.ts.map +1 -0
- package/dist/pdfkit-fonts/index.js +80 -0
- package/dist/pdfkit-fonts/index.js.map +10 -0
- package/docs/roadmap.md +12 -1
- package/docs/troubleshooting.md +65 -0
- package/package.json +33 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which URLs `FilePreview` lets reach a link's `href` or a media element's
|
|
3
|
+
* `src`. Pure: nothing runs at import.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `url` when it is safe to put in an `href` or a `src`, else `null`.
|
|
7
|
+
*
|
|
8
|
+
* Allowed: `http:` and `https:`, a relative URL (`/a.pdf`, `files/a.pdf`,
|
|
9
|
+
* `//host/a.pdf`, `?q`, `#x`), `blob:`, and a `data:` URL of an image, a
|
|
10
|
+
* video, an audio file, plain text, CSV, Markdown, JSON or a PDF. Refused:
|
|
11
|
+
* `javascript:`, `vbscript:`, a `data:` URL of anything else (HTML, for
|
|
12
|
+
* one), and every other scheme. What the browser ignores (spaces and
|
|
13
|
+
* control characters at the ends, tabs and newlines anywhere) is removed
|
|
14
|
+
* first, so it cannot hide a scheme.
|
|
15
|
+
*/
|
|
16
|
+
export declare function safePreviewUrl(url: string | null | undefined): string | null;
|
|
17
|
+
/** A file given as a URL that `safePreviewUrl` refused. */
|
|
18
|
+
export declare class FilePreviewUnsafeUrlError extends Error {
|
|
19
|
+
name: string;
|
|
20
|
+
constructor();
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=safe-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-url.d.ts","sourceRoot":"","sources":["../../src/file-preview/safe-url.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmB5E;AAED,2DAA2D;AAC3D,qBAAa,yBAA0B,SAAQ,KAAK;IAC1C,IAAI,SAA+B;;CAK5C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A text file's beginning, read with a size cap, for `FilePreview`. Nothing
|
|
3
|
+
* runs at import: `fetch` and `TextDecoder` are reached only when
|
|
4
|
+
* `readTextPreview` is called.
|
|
5
|
+
*/
|
|
6
|
+
/** How much of a text file `FilePreview` reads by default: 256 KB. */
|
|
7
|
+
export declare const TEXT_PREVIEW_MAX_BYTES: number;
|
|
8
|
+
/** A text file's first bytes, decoded, and whether there was more. */
|
|
9
|
+
export type TextPreview = {
|
|
10
|
+
text: string;
|
|
11
|
+
/** The file is longer than `maxBytes`; `text` is its beginning. */
|
|
12
|
+
truncated: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** A URL that answered with an HTTP error. */
|
|
15
|
+
export declare class FilePreviewHttpError extends Error {
|
|
16
|
+
name: string;
|
|
17
|
+
readonly status: number;
|
|
18
|
+
constructor(url: string, status: number);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The first `maxBytes` of a `Blob` / `File`, or of what a URL answers, as
|
|
22
|
+
* text, decoded with the `charset` of the URL's `Content-Type` (or of the
|
|
23
|
+
* `Blob`'s `type`) when `TextDecoder` supports it, else as UTF-8. A URL is
|
|
24
|
+
* fetched, and stops downloading once past the cap; an HTTP error throws
|
|
25
|
+
* `FilePreviewHttpError`. Pass `signal` to abort: the promise then rejects
|
|
26
|
+
* with the signal's reason, also for a `Blob`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function readTextPreview(source: Blob | string, options?: {
|
|
29
|
+
maxBytes?: number;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}): Promise<TextPreview>;
|
|
32
|
+
//# sourceMappingURL=text-preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-preview.d.ts","sourceRoot":"","sources":["../../src/file-preview/text-preview.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,QAAa,CAAC;AAEjD,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,8CAA8C;AAC9C,qBAAa,oBAAqB,SAAQ,KAAK;IACrC,IAAI,SAA0B;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIvC;AAiFD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,IAAI,GAAG,MAAM,EACrB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACvD,OAAO,CAAC,WAAW,CAAC,CAatB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure half of both libraries' `DateRangeField`: the built-in presets'
|
|
3
|
+
* ranges, a preset's state against the field's rules and value, and the time
|
|
4
|
+
* of day on each end. Plain `Date` maths in the local time zone; nothing reads
|
|
5
|
+
* the clock unless you leave `now` out.
|
|
6
|
+
*/
|
|
7
|
+
/** Both ends of a range, set. */
|
|
8
|
+
export type DayRange = {
|
|
9
|
+
from: Date;
|
|
10
|
+
to: Date;
|
|
11
|
+
};
|
|
12
|
+
/** A range being picked: `to` is unset until the second day is. */
|
|
13
|
+
export type PartialDayRange = {
|
|
14
|
+
from?: Date;
|
|
15
|
+
to?: Date;
|
|
16
|
+
};
|
|
17
|
+
/** The built-in presets, in the order a field lists them. */
|
|
18
|
+
export declare const DATE_RANGE_PRESET_IDS: readonly ["today", "yesterday", "last-7-days", "last-30-days", "this-month", "last-month", "this-year"];
|
|
19
|
+
export type DateRangePresetId = (typeof DATE_RANGE_PRESET_IDS)[number];
|
|
20
|
+
/**
|
|
21
|
+
* A preset of your own: its label, and its range or a function of "now"
|
|
22
|
+
* that returns one (called each time the list renders).
|
|
23
|
+
*/
|
|
24
|
+
export type DateRangePreset = {
|
|
25
|
+
label: string;
|
|
26
|
+
range: DayRange | ((now: Date) => DayRange);
|
|
27
|
+
};
|
|
28
|
+
/** What a field's `presets` takes: a built-in id, or a preset of your own. */
|
|
29
|
+
export type DateRangePresetOption = DateRangePresetId | DateRangePreset;
|
|
30
|
+
/** What a day must not be: a rule of the field's, and its first and last day. */
|
|
31
|
+
export type DateRangeRules = {
|
|
32
|
+
isDayDisabled?: (day: Date) => boolean;
|
|
33
|
+
min?: Date;
|
|
34
|
+
max?: Date;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A built-in preset's range at `now`, both ends at the start of their day.
|
|
38
|
+
* The last N days end today and count it; this month and this year run from
|
|
39
|
+
* their first day to today; last month is the whole previous month.
|
|
40
|
+
*/
|
|
41
|
+
export declare function presetRange(id: DateRangePresetId, now?: Date): DayRange;
|
|
42
|
+
/**
|
|
43
|
+
* A preset's range at `now`: a built-in id's, or yours (called with `now`).
|
|
44
|
+
* With `withTime`, a built-in range ends at 23:59 on its last day, so it
|
|
45
|
+
* covers that day; your own ranges keep the times you gave them.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolvePresetRange(preset: DateRangePresetOption, now?: Date, { withTime }?: {
|
|
48
|
+
withTime?: boolean;
|
|
49
|
+
}): DayRange;
|
|
50
|
+
/** Whether two ranges cover the same days (times are not compared). */
|
|
51
|
+
export declare function isSameDayRange(a: PartialDayRange | undefined, b: PartialDayRange | undefined): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether a field cannot take `range`: its end comes before its start (a
|
|
54
|
+
* preset of your own with its ends reversed), it starts before `min`, ends
|
|
55
|
+
* after `max`, or either end is a day `isDayDisabled` rules out. The days
|
|
56
|
+
* between the ends are not checked, as the calendar lets a range span a
|
|
57
|
+
* disabled day.
|
|
58
|
+
*/
|
|
59
|
+
export declare function isRangeDisabled(range: DayRange, rules?: DateRangeRules): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* `day`'s date with `time`'s hours and minutes; the start of `day` without
|
|
62
|
+
* a `time`. Seconds and milliseconds are dropped.
|
|
63
|
+
*/
|
|
64
|
+
export declare function withTimeOf(day: Date, time?: Date): Date;
|
|
65
|
+
/** `day` at 23:59, the end time a preset gets when the field shows times. */
|
|
66
|
+
export declare function endOfDayTime(day: Date): Date;
|
|
67
|
+
/**
|
|
68
|
+
* The range with its end no earlier than its start: an end before the start
|
|
69
|
+
* becomes the start (the same day and time). The field calls it after a time
|
|
70
|
+
* change, after a day pick (through `keepRangeTimes`) and after a preset
|
|
71
|
+
* pick; the only end that can come first is an earlier time on the start's
|
|
72
|
+
* day. A range missing an end, or already in order, is returned as it is. A
|
|
73
|
+
* preset with its ends reversed never reaches it: `isRangeDisabled` disables
|
|
74
|
+
* it.
|
|
75
|
+
*/
|
|
76
|
+
export declare function clampRangeEnd<R extends PartialDayRange>(range: R): R;
|
|
77
|
+
/**
|
|
78
|
+
* Days picked on a calendar, with times: each end keeps the time `previous`
|
|
79
|
+
* had at the same end. An end that had none starts at 00:00 or ends at 23:59
|
|
80
|
+
* (`endOfDayTime`), as a built-in preset does, so the range covers its last
|
|
81
|
+
* day. The end is then clamped to the start (`clampRangeEnd`).
|
|
82
|
+
*/
|
|
83
|
+
export declare function keepRangeTimes<R extends PartialDayRange>(next: R, previous?: PartialDayRange): R;
|
|
84
|
+
//# sourceMappingURL=date-range.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-range.d.ts","sourceRoot":"","sources":["../../src/lib/date-range.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iCAAiC;AACjC,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC;AAEhD,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,EAAE,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzD,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,yGAQxB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;CAC5C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAExE,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG;IAC5B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC;IACvC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,IAAI,CAAC;CACX,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,WAAW,CAC1B,EAAE,EAAE,iBAAiB,EACrB,GAAG,GAAE,IAAiB,GACpB,QAAQ,CAyBV;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,qBAAqB,EAC7B,GAAG,GAAE,IAAiB,EACtB,EAAE,QAAgB,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,QAAQ,CAQV;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAC7B,CAAC,EAAE,eAAe,GAAG,SAAS,EAC9B,CAAC,EAAE,eAAe,GAAG,SAAS,WAI9B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAE,cAAmB,WAM1E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,QAIhD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,QAIrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAIpE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,eAAe,EACvD,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,eAAe,GACxB,CAAC,CAQH"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// src/lib/date-range.ts
|
|
2
|
+
var DATE_RANGE_PRESET_IDS = [
|
|
3
|
+
"today",
|
|
4
|
+
"yesterday",
|
|
5
|
+
"last-7-days",
|
|
6
|
+
"last-30-days",
|
|
7
|
+
"this-month",
|
|
8
|
+
"last-month",
|
|
9
|
+
"this-year"
|
|
10
|
+
];
|
|
11
|
+
function startOfDay(date) {
|
|
12
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
13
|
+
}
|
|
14
|
+
function addDays(date, days) {
|
|
15
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
|
|
16
|
+
}
|
|
17
|
+
function sameDay(a, b) {
|
|
18
|
+
return startOfDay(a).getTime() === startOfDay(b).getTime();
|
|
19
|
+
}
|
|
20
|
+
function presetRange(id, now = new Date) {
|
|
21
|
+
const today = startOfDay(now);
|
|
22
|
+
const year = today.getFullYear();
|
|
23
|
+
const month = today.getMonth();
|
|
24
|
+
switch (id) {
|
|
25
|
+
case "today":
|
|
26
|
+
return { from: today, to: today };
|
|
27
|
+
case "yesterday": {
|
|
28
|
+
const day = addDays(today, -1);
|
|
29
|
+
return { from: day, to: day };
|
|
30
|
+
}
|
|
31
|
+
case "last-7-days":
|
|
32
|
+
return { from: addDays(today, -6), to: today };
|
|
33
|
+
case "last-30-days":
|
|
34
|
+
return { from: addDays(today, -29), to: today };
|
|
35
|
+
case "this-month":
|
|
36
|
+
return { from: new Date(year, month, 1), to: today };
|
|
37
|
+
case "last-month":
|
|
38
|
+
return {
|
|
39
|
+
from: new Date(year, month - 1, 1),
|
|
40
|
+
to: new Date(year, month, 0)
|
|
41
|
+
};
|
|
42
|
+
case "this-year":
|
|
43
|
+
return { from: new Date(year, 0, 1), to: today };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function resolvePresetRange(preset, now = new Date, { withTime = false } = {}) {
|
|
47
|
+
if (typeof preset !== "string") {
|
|
48
|
+
return typeof preset.range === "function" ? preset.range(now) : preset.range;
|
|
49
|
+
}
|
|
50
|
+
const range = presetRange(preset, now);
|
|
51
|
+
return withTime ? { from: range.from, to: endOfDayTime(range.to) } : range;
|
|
52
|
+
}
|
|
53
|
+
function isSameDayRange(a, b) {
|
|
54
|
+
if (!a?.from || !a.to || !b?.from || !b.to)
|
|
55
|
+
return false;
|
|
56
|
+
return sameDay(a.from, b.from) && sameDay(a.to, b.to);
|
|
57
|
+
}
|
|
58
|
+
function isRangeDisabled(range, rules = {}) {
|
|
59
|
+
const { isDayDisabled, min, max } = rules;
|
|
60
|
+
if (range.to.getTime() < range.from.getTime())
|
|
61
|
+
return true;
|
|
62
|
+
if (min && startOfDay(range.from) < startOfDay(min))
|
|
63
|
+
return true;
|
|
64
|
+
if (max && startOfDay(range.to) > startOfDay(max))
|
|
65
|
+
return true;
|
|
66
|
+
return Boolean(isDayDisabled?.(range.from) || isDayDisabled?.(range.to));
|
|
67
|
+
}
|
|
68
|
+
function withTimeOf(day, time) {
|
|
69
|
+
const next = startOfDay(day);
|
|
70
|
+
if (time)
|
|
71
|
+
next.setHours(time.getHours(), time.getMinutes());
|
|
72
|
+
return next;
|
|
73
|
+
}
|
|
74
|
+
function endOfDayTime(day) {
|
|
75
|
+
const next = startOfDay(day);
|
|
76
|
+
next.setHours(23, 59);
|
|
77
|
+
return next;
|
|
78
|
+
}
|
|
79
|
+
function clampRangeEnd(range) {
|
|
80
|
+
const { from, to } = range;
|
|
81
|
+
if (!from || !to || to.getTime() >= from.getTime())
|
|
82
|
+
return range;
|
|
83
|
+
return { ...range, to: new Date(from) };
|
|
84
|
+
}
|
|
85
|
+
function keepRangeTimes(next, previous) {
|
|
86
|
+
return clampRangeEnd({
|
|
87
|
+
...next,
|
|
88
|
+
from: next.from && withTimeOf(next.from, previous?.from),
|
|
89
|
+
to: next.to && (previous?.to ? withTimeOf(next.to, previous.to) : endOfDayTime(next.to))
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
DATE_RANGE_PRESET_IDS,
|
|
94
|
+
clampRangeEnd,
|
|
95
|
+
endOfDayTime,
|
|
96
|
+
isRangeDisabled,
|
|
97
|
+
isSameDayRange,
|
|
98
|
+
keepRangeTimes,
|
|
99
|
+
presetRange,
|
|
100
|
+
resolvePresetRange,
|
|
101
|
+
withTimeOf
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
//# debugId=DE919010B55B550A64756E2164756E21
|
|
105
|
+
//# sourceMappingURL=date-range.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/date-range.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * The pure half of both libraries' `DateRangeField`: the built-in presets'\n * ranges, a preset's state against the field's rules and value, and the time\n * of day on each end. Plain `Date` maths in the local time zone; nothing reads\n * the clock unless you leave `now` out.\n */\n\n/** Both ends of a range, set. */\nexport type DayRange = { from: Date; to: Date };\n\n/** A range being picked: `to` is unset until the second day is. */\nexport type PartialDayRange = { from?: Date; to?: Date };\n\n/** The built-in presets, in the order a field lists them. */\nexport const DATE_RANGE_PRESET_IDS = [\n\t'today',\n\t'yesterday',\n\t'last-7-days',\n\t'last-30-days',\n\t'this-month',\n\t'last-month',\n\t'this-year',\n] as const;\n\nexport type DateRangePresetId = (typeof DATE_RANGE_PRESET_IDS)[number];\n\n/**\n * A preset of your own: its label, and its range or a function of \"now\"\n * that returns one (called each time the list renders).\n */\nexport type DateRangePreset = {\n\tlabel: string;\n\trange: DayRange | ((now: Date) => DayRange);\n};\n\n/** What a field's `presets` takes: a built-in id, or a preset of your own. */\nexport type DateRangePresetOption = DateRangePresetId | DateRangePreset;\n\n/** What a day must not be: a rule of the field's, and its first and last day. */\nexport type DateRangeRules = {\n\tisDayDisabled?: (day: Date) => boolean;\n\tmin?: Date;\n\tmax?: Date;\n};\n\nfunction startOfDay(date: Date) {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction addDays(date: Date, days: number) {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\nfunction sameDay(a: Date, b: Date) {\n\treturn startOfDay(a).getTime() === startOfDay(b).getTime();\n}\n\n/**\n * A built-in preset's range at `now`, both ends at the start of their day.\n * The last N days end today and count it; this month and this year run from\n * their first day to today; last month is the whole previous month.\n */\nexport function presetRange(\n\tid: DateRangePresetId,\n\tnow: Date = new Date(),\n): DayRange {\n\tconst today = startOfDay(now);\n\tconst year = today.getFullYear();\n\tconst month = today.getMonth();\n\tswitch (id) {\n\t\tcase 'today':\n\t\t\treturn { from: today, to: today };\n\t\tcase 'yesterday': {\n\t\t\tconst day = addDays(today, -1);\n\t\t\treturn { from: day, to: day };\n\t\t}\n\t\tcase 'last-7-days':\n\t\t\treturn { from: addDays(today, -6), to: today };\n\t\tcase 'last-30-days':\n\t\t\treturn { from: addDays(today, -29), to: today };\n\t\tcase 'this-month':\n\t\t\treturn { from: new Date(year, month, 1), to: today };\n\t\tcase 'last-month':\n\t\t\treturn {\n\t\t\t\tfrom: new Date(year, month - 1, 1),\n\t\t\t\tto: new Date(year, month, 0),\n\t\t\t};\n\t\tcase 'this-year':\n\t\t\treturn { from: new Date(year, 0, 1), to: today };\n\t}\n}\n\n/**\n * A preset's range at `now`: a built-in id's, or yours (called with `now`).\n * With `withTime`, a built-in range ends at 23:59 on its last day, so it\n * covers that day; your own ranges keep the times you gave them.\n */\nexport function resolvePresetRange(\n\tpreset: DateRangePresetOption,\n\tnow: Date = new Date(),\n\t{ withTime = false }: { withTime?: boolean } = {},\n): DayRange {\n\tif (typeof preset !== 'string') {\n\t\treturn typeof preset.range === 'function'\n\t\t\t? preset.range(now)\n\t\t\t: preset.range;\n\t}\n\tconst range = presetRange(preset, now);\n\treturn withTime ? { from: range.from, to: endOfDayTime(range.to) } : range;\n}\n\n/** Whether two ranges cover the same days (times are not compared). */\nexport function isSameDayRange(\n\ta: PartialDayRange | undefined,\n\tb: PartialDayRange | undefined,\n) {\n\tif (!a?.from || !a.to || !b?.from || !b.to) return false;\n\treturn sameDay(a.from, b.from) && sameDay(a.to, b.to);\n}\n\n/**\n * Whether a field cannot take `range`: its end comes before its start (a\n * preset of your own with its ends reversed), it starts before `min`, ends\n * after `max`, or either end is a day `isDayDisabled` rules out. The days\n * between the ends are not checked, as the calendar lets a range span a\n * disabled day.\n */\nexport function isRangeDisabled(range: DayRange, rules: DateRangeRules = {}) {\n\tconst { isDayDisabled, min, max } = rules;\n\tif (range.to.getTime() < range.from.getTime()) return true;\n\tif (min && startOfDay(range.from) < startOfDay(min)) return true;\n\tif (max && startOfDay(range.to) > startOfDay(max)) return true;\n\treturn Boolean(isDayDisabled?.(range.from) || isDayDisabled?.(range.to));\n}\n\n/**\n * `day`'s date with `time`'s hours and minutes; the start of `day` without\n * a `time`. Seconds and milliseconds are dropped.\n */\nexport function withTimeOf(day: Date, time?: Date) {\n\tconst next = startOfDay(day);\n\tif (time) next.setHours(time.getHours(), time.getMinutes());\n\treturn next;\n}\n\n/** `day` at 23:59, the end time a preset gets when the field shows times. */\nexport function endOfDayTime(day: Date) {\n\tconst next = startOfDay(day);\n\tnext.setHours(23, 59);\n\treturn next;\n}\n\n/**\n * The range with its end no earlier than its start: an end before the start\n * becomes the start (the same day and time). The field calls it after a time\n * change, after a day pick (through `keepRangeTimes`) and after a preset\n * pick; the only end that can come first is an earlier time on the start's\n * day. A range missing an end, or already in order, is returned as it is. A\n * preset with its ends reversed never reaches it: `isRangeDisabled` disables\n * it.\n */\nexport function clampRangeEnd<R extends PartialDayRange>(range: R): R {\n\tconst { from, to } = range;\n\tif (!from || !to || to.getTime() >= from.getTime()) return range;\n\treturn { ...range, to: new Date(from) };\n}\n\n/**\n * Days picked on a calendar, with times: each end keeps the time `previous`\n * had at the same end. An end that had none starts at 00:00 or ends at 23:59\n * (`endOfDayTime`), as a built-in preset does, so the range covers its last\n * day. The end is then clamped to the start (`clampRangeEnd`).\n */\nexport function keepRangeTimes<R extends PartialDayRange>(\n\tnext: R,\n\tprevious?: PartialDayRange,\n): R {\n\treturn clampRangeEnd({\n\t\t...next,\n\t\tfrom: next.from && withTimeOf(next.from, previous?.from),\n\t\tto:\n\t\t\tnext.to &&\n\t\t\t(previous?.to ? withTimeOf(next.to, previous.to) : endOfDayTime(next.to)),\n\t});\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "DE919010B55B550A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A byte count as people read it: `'512 B'`, `'1.5 KB'`, `'2.0 MB'`,
|
|
3
|
+
* `'1.0 GB'` (1024-based, one decimal above bytes, capped at GB), and `''`
|
|
4
|
+
* for a negative, `NaN` or infinite size. Locale-free, so a server and a
|
|
5
|
+
* browser print the same thing. The file list, the upload field and its
|
|
6
|
+
* constraints, the file card and the chat attachment chip of both libraries
|
|
7
|
+
* use it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatFileSize(bytes: number): string;
|
|
10
|
+
//# sourceMappingURL=format-file-size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-file-size.d.ts","sourceRoot":"","sources":["../../src/lib/format-file-size.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUpD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/lib/format-file-size.ts
|
|
2
|
+
function formatFileSize(bytes) {
|
|
3
|
+
if (bytes < 0 || !Number.isFinite(bytes))
|
|
4
|
+
return "";
|
|
5
|
+
if (bytes === 0)
|
|
6
|
+
return "0 B";
|
|
7
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
8
|
+
const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
|
|
9
|
+
const value = bytes / 1024 ** exponent;
|
|
10
|
+
return `${exponent === 0 ? value : value.toFixed(1)} ${units[exponent]}`;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
formatFileSize
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
//# debugId=5CC787DB991D0F4A64756E2164756E21
|
|
17
|
+
//# sourceMappingURL=format-file-size.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/format-file-size.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * A byte count as people read it: `'512 B'`, `'1.5 KB'`, `'2.0 MB'`,\n * `'1.0 GB'` (1024-based, one decimal above bytes, capped at GB), and `''`\n * for a negative, `NaN` or infinite size. Locale-free, so a server and a\n * browser print the same thing. The file list, the upload field and its\n * constraints, the file card and the chat attachment chip of both libraries\n * use it.\n */\nexport function formatFileSize(bytes: number): string {\n\tif (bytes < 0 || !Number.isFinite(bytes)) return '';\n\tif (bytes === 0) return '0 B';\n\tconst units = ['B', 'KB', 'MB', 'GB'];\n\tconst exponent = Math.min(\n\t\tMath.floor(Math.log(bytes) / Math.log(1024)),\n\t\tunits.length - 1,\n\t);\n\tconst value = bytes / 1024 ** exponent;\n\treturn `${exponent === 0 ? value : value.toFixed(1)} ${units[exponent]}`;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAQO,SAAS,cAAc,CAAC,OAAuB;AAAA,EACrD,IAAI,QAAQ,KAAK,CAAC,OAAO,SAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EACjD,IAAI,UAAU;AAAA,IAAG,OAAO;AAAA,EACxB,MAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AAAA,EACpC,MAAM,WAAW,KAAK,IACrB,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,GAC3C,MAAM,SAAS,CAChB;AAAA,EACA,MAAM,QAAQ,QAAQ,QAAQ;AAAA,EAC9B,OAAO,GAAG,aAAa,IAAI,QAAQ,MAAM,QAAQ,CAAC,KAAK,MAAM;AAAA;",
|
|
8
|
+
"debugId": "5CC787DB991D0F4A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The values a slider's tick marks sit at, from `min` to `max` inclusive:
|
|
3
|
+
* `false` none, a number that many, `true` one per `step` (or 5 without one).
|
|
4
|
+
* Always 2 to 21 marks, evenly spaced; one when `min` and `max` are equal.
|
|
5
|
+
*/
|
|
6
|
+
export declare function tickValues(min: number, max: number, ticks: boolean | number, step?: number): number[];
|
|
7
|
+
//# sourceMappingURL=slider-ticks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider-ticks.d.ts","sourceRoot":"","sources":["../../src/lib/slider-ticks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GAAG,MAAM,EACvB,IAAI,CAAC,EAAE,MAAM,YAeb"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/lib/slider-ticks.ts
|
|
2
|
+
function tickValues(min, max, ticks, step) {
|
|
3
|
+
if (ticks === false)
|
|
4
|
+
return [];
|
|
5
|
+
let count = typeof ticks === "number" ? ticks : step && step > 0 ? Math.round((max - min) / step) + 1 : 5;
|
|
6
|
+
count = Math.min(Math.max(Math.round(count), 2), 21);
|
|
7
|
+
if (max === min)
|
|
8
|
+
return [min];
|
|
9
|
+
return Array.from({ length: count }, (_, index) => min + (max - min) * index / (count - 1));
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
tickValues
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//# debugId=68EBFB8D67762FE364756E2164756E21
|
|
16
|
+
//# sourceMappingURL=slider-ticks.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/slider-ticks.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * The values a slider's tick marks sit at, from `min` to `max` inclusive:\n * `false` none, a number that many, `true` one per `step` (or 5 without one).\n * Always 2 to 21 marks, evenly spaced; one when `min` and `max` are equal.\n */\nexport function tickValues(\n\tmin: number,\n\tmax: number,\n\tticks: boolean | number,\n\tstep?: number,\n) {\n\tif (ticks === false) return [];\n\tlet count =\n\t\ttypeof ticks === 'number'\n\t\t\t? ticks\n\t\t\t: step && step > 0\n\t\t\t\t? Math.round((max - min) / step) + 1\n\t\t\t\t: 5;\n\tcount = Math.min(Math.max(Math.round(count), 2), 21);\n\tif (max === min) return [min];\n\treturn Array.from(\n\t\t{ length: count },\n\t\t(_, index) => min + ((max - min) * index) / (count - 1),\n\t);\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAKO,SAAS,UAAU,CACzB,KACA,KACA,OACA,MACC;AAAA,EACD,IAAI,UAAU;AAAA,IAAO,OAAO,CAAC;AAAA,EAC7B,IAAI,QACH,OAAO,UAAU,WACd,QACA,QAAQ,OAAO,IACd,KAAK,OAAO,MAAM,OAAO,IAAI,IAAI,IACjC;AAAA,EACL,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;AAAA,EACnD,IAAI,QAAQ;AAAA,IAAK,OAAO,CAAC,GAAG;AAAA,EAC5B,OAAO,MAAM,KACZ,EAAE,QAAQ,MAAM,GAChB,CAAC,GAAG,UAAU,OAAQ,MAAM,OAAO,SAAU,QAAQ,EACtD;AAAA;",
|
|
8
|
+
"debugId": "68EBFB8D67762FE364756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -9,6 +9,7 @@ export * from './pdf-document-search';
|
|
|
9
9
|
export * from './pdf-escape';
|
|
10
10
|
export * from './pdf-page-geometry';
|
|
11
11
|
export * from './pdf-page-sizes';
|
|
12
|
+
export * from './pdf-pin-page';
|
|
12
13
|
export * from './pdf-scroll-spy';
|
|
13
14
|
export * from './pdf-text-search';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pdf-viewer/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pdf-viewer/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
package/dist/pdf-viewer/index.js
CHANGED
|
@@ -215,6 +215,24 @@ function createPageSizesLoader(onSizes) {
|
|
|
215
215
|
}
|
|
216
216
|
};
|
|
217
217
|
}
|
|
218
|
+
// src/pdf-viewer/pdf-user-input.ts
|
|
219
|
+
var USER_SCROLL_EVENTS = [
|
|
220
|
+
"wheel",
|
|
221
|
+
"touchstart",
|
|
222
|
+
"pointerdown",
|
|
223
|
+
"keydown"
|
|
224
|
+
];
|
|
225
|
+
function listenForUserInput(target, run) {
|
|
226
|
+
for (const type of USER_SCROLL_EVENTS) {
|
|
227
|
+
target.addEventListener(type, run, { capture: true, passive: true });
|
|
228
|
+
}
|
|
229
|
+
return () => {
|
|
230
|
+
for (const type of USER_SCROLL_EVENTS) {
|
|
231
|
+
target.removeEventListener(type, run, { capture: true });
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
218
236
|
// src/pdf-viewer/pdf-scroll-spy.ts
|
|
219
237
|
function mostVisiblePage(view, pages) {
|
|
220
238
|
let best = null;
|
|
@@ -244,38 +262,6 @@ function scrollIntoArea(node, block, behavior = "smooth") {
|
|
|
244
262
|
top -= (view.height - box.height) / 2;
|
|
245
263
|
area.scrollTo({ top: Math.max(0, top), behavior });
|
|
246
264
|
}
|
|
247
|
-
var USER_SCROLL_EVENTS = [
|
|
248
|
-
"wheel",
|
|
249
|
-
"touchstart",
|
|
250
|
-
"pointerdown",
|
|
251
|
-
"keydown"
|
|
252
|
-
];
|
|
253
|
-
function pinToPage(node, beforeScroll) {
|
|
254
|
-
const area = node()?.closest('[data-slot="scroll-area-viewport"]');
|
|
255
|
-
const content = area?.firstElementChild;
|
|
256
|
-
if (!area || !content || typeof ResizeObserver === "undefined") {
|
|
257
|
-
return () => {};
|
|
258
|
-
}
|
|
259
|
-
const surface = area.closest('[data-slot="scroll-area"]') ?? area;
|
|
260
|
-
const observer = new ResizeObserver(() => {
|
|
261
|
-
const target = node();
|
|
262
|
-
if (!target)
|
|
263
|
-
return;
|
|
264
|
-
beforeScroll();
|
|
265
|
-
scrollIntoArea(target, "start", "auto");
|
|
266
|
-
});
|
|
267
|
-
observer.observe(content);
|
|
268
|
-
const unpin = () => {
|
|
269
|
-
observer.disconnect();
|
|
270
|
-
for (const type of USER_SCROLL_EVENTS) {
|
|
271
|
-
surface.removeEventListener(type, unpin, true);
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
for (const type of USER_SCROLL_EVENTS) {
|
|
275
|
-
surface.addEventListener(type, unpin, { capture: true, passive: true });
|
|
276
|
-
}
|
|
277
|
-
return unpin;
|
|
278
|
-
}
|
|
279
265
|
function createScrollSpy(root, pages, onPage, idleMs = 150) {
|
|
280
266
|
let frame = 0;
|
|
281
267
|
let held = false;
|
|
@@ -313,10 +299,18 @@ function createScrollSpy(root, pages, onPage, idleMs = 150) {
|
|
|
313
299
|
if (!frame)
|
|
314
300
|
frame = requestAnimationFrame(measure);
|
|
315
301
|
};
|
|
302
|
+
const onUserInput = (event) => {
|
|
303
|
+
const target = event.target;
|
|
304
|
+
if (!target || !root()?.contains(target))
|
|
305
|
+
return;
|
|
306
|
+
held = false;
|
|
307
|
+
clearTimeout(idle);
|
|
308
|
+
};
|
|
316
309
|
document.addEventListener("scroll", onScroll, {
|
|
317
310
|
capture: true,
|
|
318
311
|
passive: true
|
|
319
312
|
});
|
|
313
|
+
const stopInput = listenForUserInput(document, onUserInput);
|
|
320
314
|
return {
|
|
321
315
|
hold() {
|
|
322
316
|
held = true;
|
|
@@ -326,6 +320,7 @@ function createScrollSpy(root, pages, onPage, idleMs = 150) {
|
|
|
326
320
|
},
|
|
327
321
|
stop() {
|
|
328
322
|
document.removeEventListener("scroll", onScroll, { capture: true });
|
|
323
|
+
stopInput();
|
|
329
324
|
cancelAnimationFrame(frame);
|
|
330
325
|
clearTimeout(idle);
|
|
331
326
|
}
|
|
@@ -347,6 +342,45 @@ function revealHit(findPage, hit, beforeScroll = () => {}, timeout = 5000) {
|
|
|
347
342
|
frame = requestAnimationFrame(look);
|
|
348
343
|
return () => cancelAnimationFrame(frame);
|
|
349
344
|
}
|
|
345
|
+
|
|
346
|
+
// src/pdf-viewer/pdf-pin-page.ts
|
|
347
|
+
var VIEWPORT = '[data-slot="scroll-area-viewport"]';
|
|
348
|
+
function pinToPage(node, beforeScroll, onRelease = () => {}) {
|
|
349
|
+
const area = node()?.closest(VIEWPORT);
|
|
350
|
+
const content = area?.firstElementChild;
|
|
351
|
+
if (!area || !content || typeof ResizeObserver === "undefined") {
|
|
352
|
+
onRelease();
|
|
353
|
+
return () => {};
|
|
354
|
+
}
|
|
355
|
+
const surface = area.closest('[data-slot="scroll-area"]') ?? area;
|
|
356
|
+
const observer = new ResizeObserver(() => {
|
|
357
|
+
const target = node();
|
|
358
|
+
if (!target)
|
|
359
|
+
return;
|
|
360
|
+
beforeScroll();
|
|
361
|
+
scrollIntoArea(target, "start", "auto");
|
|
362
|
+
});
|
|
363
|
+
observer.observe(content);
|
|
364
|
+
let pinned = true;
|
|
365
|
+
const unpin = () => {
|
|
366
|
+
if (!pinned)
|
|
367
|
+
return;
|
|
368
|
+
pinned = false;
|
|
369
|
+
observer.disconnect();
|
|
370
|
+
stopListening();
|
|
371
|
+
onRelease();
|
|
372
|
+
};
|
|
373
|
+
const stopListening = listenForUserInput(surface, unpin);
|
|
374
|
+
return unpin;
|
|
375
|
+
}
|
|
376
|
+
function pinHolds(node) {
|
|
377
|
+
const area = node?.closest(VIEWPORT);
|
|
378
|
+
if (!node || !area)
|
|
379
|
+
return false;
|
|
380
|
+
const atEnd = area.scrollTop + area.clientHeight >= area.scrollHeight - 2;
|
|
381
|
+
const offset = node.getBoundingClientRect().top - area.getBoundingClientRect().top;
|
|
382
|
+
return atEnd && offset >= -2 || Math.abs(offset) <= 2;
|
|
383
|
+
}
|
|
350
384
|
export {
|
|
351
385
|
DEFAULT_PAGE_SIZE,
|
|
352
386
|
FIT_PAGES,
|
|
@@ -364,6 +398,7 @@ export {
|
|
|
364
398
|
mostVisiblePage,
|
|
365
399
|
pageRotation,
|
|
366
400
|
pageTextFromItems,
|
|
401
|
+
pinHolds,
|
|
367
402
|
pinToPage,
|
|
368
403
|
placeholderSize,
|
|
369
404
|
readPageSizes,
|
|
@@ -376,5 +411,5 @@ export {
|
|
|
376
411
|
withPageMatches
|
|
377
412
|
};
|
|
378
413
|
|
|
379
|
-
//# debugId=
|
|
414
|
+
//# debugId=71863DCA45A690D164756E2164756E21
|
|
380
415
|
//# sourceMappingURL=index.js.map
|