pdfjs-reader-core 0.4.0 → 0.4.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.
- package/README.md +7 -0
- package/dist/index.cjs +1598 -453
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -26
- package/dist/index.d.ts +151 -26
- package/dist/index.js +1587 -442
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1782,11 +1782,45 @@ interface TutorModeContainerProps {
|
|
|
1782
1782
|
* Default: 3500ms.
|
|
1783
1783
|
*/
|
|
1784
1784
|
minOverlayDurationMs?: number;
|
|
1785
|
+
/**
|
|
1786
|
+
* Background colour of the container surround (visible around the PDF when
|
|
1787
|
+
* the viewport is larger than the page fit). Default: `#ffffff`. Pass a
|
|
1788
|
+
* dark value for dark-themed hosts.
|
|
1789
|
+
*/
|
|
1790
|
+
backgroundColor?: string;
|
|
1791
|
+
/**
|
|
1792
|
+
* Optional content to render while the PDF document/page is still loading.
|
|
1793
|
+
* Receives the loading stage so the host can show a spinner, a skeleton,
|
|
1794
|
+
* or a custom brand. If omitted, a minimal default spinner is rendered on
|
|
1795
|
+
* the `backgroundColor` surround.
|
|
1796
|
+
*/
|
|
1797
|
+
loadingComponent?: react__default.ReactNode;
|
|
1798
|
+
/**
|
|
1799
|
+
* Fired when the underlying viewer's page changes from any source — the
|
|
1800
|
+
* agent API (`agentTools.goToPage / nextPage / previousPage`), the sidebar
|
|
1801
|
+
* (bookmarks, thumbnails, search), or a programmatic
|
|
1802
|
+
* `useViewerStore().goToPage` call. Use this to keep your own
|
|
1803
|
+
* `pageNumber` state (the controlled prop you pass in) in lockstep with
|
|
1804
|
+
* the viewer, so agent-driven navigation actually moves the rendered
|
|
1805
|
+
* page and downstream concerns (progress save, recap, etc.) see the
|
|
1806
|
+
* right value.
|
|
1807
|
+
*
|
|
1808
|
+
* ```tsx
|
|
1809
|
+
* const [currentPage, setCurrentPage] = useState(1);
|
|
1810
|
+
* <TutorModeContainer
|
|
1811
|
+
* pageNumber={currentPage}
|
|
1812
|
+
* onPageChange={setCurrentPage} // ← bidirectional sync
|
|
1813
|
+
* />
|
|
1814
|
+
* ```
|
|
1815
|
+
*
|
|
1816
|
+
* Added in v0.4.2.
|
|
1817
|
+
*/
|
|
1818
|
+
onPageChange?: (page: number) => void;
|
|
1785
1819
|
className?: string;
|
|
1786
1820
|
}
|
|
1787
1821
|
/** Build a cross-page/block index from the raw bbox list. */
|
|
1788
1822
|
declare function buildBBoxIndex(bboxData: PageBBoxData[]): BBoxIndex;
|
|
1789
|
-
declare function TutorModeContainer({ pageNumber, bboxData, narrationStore, scale, rotation, currentChunk, llm, idleTimeoutMs, llmTimeoutMs, embeddingProvider, showSubtitles, showExitButton, onExitTutorMode, minOverlayDurationMs, className, }: TutorModeContainerProps): react_jsx_runtime.JSX.Element;
|
|
1823
|
+
declare function TutorModeContainer({ pageNumber, bboxData, narrationStore, scale, rotation, currentChunk, llm, idleTimeoutMs, llmTimeoutMs, embeddingProvider, showSubtitles, showExitButton, onExitTutorMode, minOverlayDurationMs, backgroundColor, loadingComponent, onPageChange, className, }: TutorModeContainerProps): react_jsx_runtime.JSX.Element;
|
|
1790
1824
|
|
|
1791
1825
|
interface CinemaLayerProps {
|
|
1792
1826
|
page: PageBBoxData;
|
|
@@ -1816,13 +1850,19 @@ interface SpotlightMaskProps {
|
|
|
1816
1850
|
durationMs?: number;
|
|
1817
1851
|
}
|
|
1818
1852
|
/**
|
|
1819
|
-
*
|
|
1820
|
-
*
|
|
1821
|
-
*
|
|
1822
|
-
*
|
|
1853
|
+
* Design: **Theatrical spotlight.** A warm-ink dim (not pure black)
|
|
1854
|
+
* closes over the whole page, then a feathered cutout reveals the
|
|
1855
|
+
* target block. A thin terracotta accent ring follows the cutout shape
|
|
1856
|
+
* — the same colour used by every other overlay so the spotlit region
|
|
1857
|
+
* is clearly part of the same annotation system.
|
|
1858
|
+
*
|
|
1859
|
+
* The dim colour is warm INK (`#2a2420`) rather than `#000` so the
|
|
1860
|
+
* dimmed area looks like the PDF pushed into shadow rather than
|
|
1861
|
+
* blacked out. On light textbook pages this reads as "atmosphere"
|
|
1862
|
+
* instead of "censorship".
|
|
1823
1863
|
*
|
|
1824
|
-
*
|
|
1825
|
-
*
|
|
1864
|
+
* The accent ring animates with a slight stagger after the dim, so the
|
|
1865
|
+
* reveal has a subtle two-beat cadence: darken → point.
|
|
1826
1866
|
*/
|
|
1827
1867
|
declare function SpotlightMask({ page, bbox, action, durationMs, }: SpotlightMaskProps): react_jsx_runtime.JSX.Element;
|
|
1828
1868
|
|
|
@@ -1836,12 +1876,40 @@ interface AnimatedHighlightProps {
|
|
|
1836
1876
|
bbox: BBoxCoords;
|
|
1837
1877
|
action: ActionHighlight;
|
|
1838
1878
|
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Design: **Real highlighter stroke.** A flat rectangle feels digital;
|
|
1881
|
+
* a real highlighter has fibrous texture, a soft inner + harder outer
|
|
1882
|
+
* edge, a slight over-bleed past the baseline, and visible uneven
|
|
1883
|
+
* starts/ends where the pen hit and lifted the paper.
|
|
1884
|
+
*
|
|
1885
|
+
* Implementation:
|
|
1886
|
+
* - Double-stroke — a broad soft wash behind a tighter primary stroke
|
|
1887
|
+
* so the mark has depth where they overlap.
|
|
1888
|
+
* - Slight vertical over-bleed (2–3 px above/below the bbox) so the
|
|
1889
|
+
* highlight doesn't look clipped to the text baseline.
|
|
1890
|
+
* - Rounded caps + uneven left/right ends via tapered start/finish
|
|
1891
|
+
* for the "pen hit the page" look.
|
|
1892
|
+
* - Feathered edge mask via SVG filter for the fibrous marker feel.
|
|
1893
|
+
*/
|
|
1839
1894
|
declare function AnimatedHighlight({ bbox, action }: AnimatedHighlightProps): react_jsx_runtime.JSX.Element;
|
|
1840
1895
|
|
|
1841
1896
|
interface PulseOverlayProps {
|
|
1842
1897
|
bbox: BBoxCoords;
|
|
1843
1898
|
action: ActionPulse;
|
|
1844
1899
|
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Design: **Camera viewfinder brackets.** Four L-shapes slide in from
|
|
1902
|
+
* each corner of the target block, like framing crosshairs on a camera.
|
|
1903
|
+
* Behind them, a soft radial glow pulses in sync with the bracket
|
|
1904
|
+
* emphasis — a "look here" cue that points without blocking content.
|
|
1905
|
+
*
|
|
1906
|
+
* Intensity controls bracket length + stroke weight + glow strength.
|
|
1907
|
+
* `count` controls how many emphasis pulses happen before the overlay
|
|
1908
|
+
* settles.
|
|
1909
|
+
*
|
|
1910
|
+
* Brackets slide in from OUTSIDE the block then snap to the corners,
|
|
1911
|
+
* which reads as "framing" rather than the usual bordered box.
|
|
1912
|
+
*/
|
|
1845
1913
|
declare function PulseOverlay({ bbox, action }: PulseOverlayProps): react_jsx_runtime.JSX.Element;
|
|
1846
1914
|
|
|
1847
1915
|
interface CalloutArrowProps {
|
|
@@ -1849,6 +1917,17 @@ interface CalloutArrowProps {
|
|
|
1849
1917
|
toBbox: BBoxCoords;
|
|
1850
1918
|
action: ActionCallout;
|
|
1851
1919
|
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Design: **Editorial connector.** Hand-drawn feel via a refined stroke
|
|
1922
|
+
* + a small origin dot at the "from" end (like a teacher's pen planted
|
|
1923
|
+
* on the page before they draw the arrow). The arrowhead is a slender
|
|
1924
|
+
* open caret rather than a heavy filled triangle — reads as annotation,
|
|
1925
|
+
* not direction-signage.
|
|
1926
|
+
*
|
|
1927
|
+
* An optional label pill rides the arrow's trailing end using the same
|
|
1928
|
+
* editorial pin language as StickyLabel (cream paper, terracotta rule,
|
|
1929
|
+
* serif small-caps). Everything uses ACCENT for colour consistency.
|
|
1930
|
+
*/
|
|
1852
1931
|
declare function CalloutArrow({ fromBbox, toBbox, action }: CalloutArrowProps): react_jsx_runtime.JSX.Element;
|
|
1853
1932
|
|
|
1854
1933
|
interface GhostReferenceProps {
|
|
@@ -1858,24 +1937,50 @@ interface GhostReferenceProps {
|
|
|
1858
1937
|
sourcePageNumber: number;
|
|
1859
1938
|
action: ActionGhostReference;
|
|
1860
1939
|
}
|
|
1861
|
-
|
|
1862
|
-
* Renders a floating "ghost" card referencing a block from another page.
|
|
1863
|
-
* Shows a minimap of the source page with the target bbox highlighted,
|
|
1864
|
-
* plus the block's text description as a caption.
|
|
1865
|
-
*/
|
|
1866
|
-
declare function GhostReference({ page, sourceBbox, sourceBlockText, sourcePageNumber, action, }: GhostReferenceProps): react_jsx_runtime.JSX.Element;
|
|
1940
|
+
declare function GhostReference({ page, sourceBbox, sourceBlockText, action, }: GhostReferenceProps): react_jsx_runtime.JSX.Element;
|
|
1867
1941
|
|
|
1868
1942
|
interface BoxOverlayProps {
|
|
1869
1943
|
bbox: BBoxCoords;
|
|
1870
1944
|
action: ActionBox;
|
|
1871
1945
|
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Design: **Framed region.** A structural region marker — thinner and
|
|
1948
|
+
* more refined than the previous generic 3px coloured border. A subtle
|
|
1949
|
+
* accent-tinted wash fills the interior so the framed region reads as
|
|
1950
|
+
* "selected" even without a thick border. Dashed style uses a custom
|
|
1951
|
+
* dash pattern that matches the editorial vocabulary.
|
|
1952
|
+
*
|
|
1953
|
+
* Honours `action.color` when the LLM specifies something non-default,
|
|
1954
|
+
* otherwise falls through to the terracotta accent so boxes fit the
|
|
1955
|
+
* system.
|
|
1956
|
+
*/
|
|
1872
1957
|
declare function BoxOverlay({ bbox, action }: BoxOverlayProps): react_jsx_runtime.JSX.Element;
|
|
1873
1958
|
|
|
1874
1959
|
interface StickyLabelProps {
|
|
1875
|
-
|
|
1960
|
+
/**
|
|
1961
|
+
* Pre-computed anchor point in viewport pixels — the label will be
|
|
1962
|
+
* placed at this point and positioned relative to it via
|
|
1963
|
+
* `action.position`. See `LabelOverlay` for the coordinate math that
|
|
1964
|
+
* maps a block's bbox + camera state to this value.
|
|
1965
|
+
*/
|
|
1966
|
+
screenAnchor: {
|
|
1967
|
+
x: number;
|
|
1968
|
+
y: number;
|
|
1969
|
+
};
|
|
1876
1970
|
action: ActionLabel;
|
|
1877
1971
|
}
|
|
1878
|
-
|
|
1972
|
+
/**
|
|
1973
|
+
* Editorial annotation pin. The label body sits a short distance from
|
|
1974
|
+
* the target block, connected by a hairline stem and a small marker
|
|
1975
|
+
* disc at the anchor point. Body uses a classical serif at small-caps
|
|
1976
|
+
* sizing — feels like a scholar's tag, not a browser toast.
|
|
1977
|
+
*
|
|
1978
|
+
* Positioning math: caller pre-computes the `screenAnchor` (usually the
|
|
1979
|
+
* midpoint of the block edge the label is attached to), and this
|
|
1980
|
+
* component lays out the pin on the appropriate side via CSS translate
|
|
1981
|
+
* offsets.
|
|
1982
|
+
*/
|
|
1983
|
+
declare function StickyLabel({ screenAnchor, action }: StickyLabelProps): react_jsx_runtime.JSX.Element;
|
|
1879
1984
|
|
|
1880
1985
|
interface SubtitleBarProps {
|
|
1881
1986
|
text: string | null;
|
|
@@ -1902,7 +2007,20 @@ interface EngineDeps {
|
|
|
1902
2007
|
}
|
|
1903
2008
|
declare class StoryboardEngine {
|
|
1904
2009
|
private deps;
|
|
1905
|
-
|
|
2010
|
+
/**
|
|
2011
|
+
* Timers that schedule the START of a step (via `setTimeout(runStep, at_ms)`).
|
|
2012
|
+
* These are storyboard-scoped: when a new storyboard arrives, anything still
|
|
2013
|
+
* pending should be abandoned.
|
|
2014
|
+
*/
|
|
2015
|
+
private pendingStepTimers;
|
|
2016
|
+
/**
|
|
2017
|
+
* Timers that auto-REMOVE an already-placed overlay after its visible
|
|
2018
|
+
* duration. Keyed by overlay id so we can cancel one specifically. These are
|
|
2019
|
+
* NOT cancelled when a new storyboard starts — otherwise the still-visible
|
|
2020
|
+
* overlay from the previous beat would get stranded in the store forever
|
|
2021
|
+
* (the "stuck spotlight" bug).
|
|
2022
|
+
*/
|
|
2023
|
+
private overlayRemovalTimers;
|
|
1906
2024
|
private currentStoryboardId;
|
|
1907
2025
|
constructor(deps: EngineDeps);
|
|
1908
2026
|
/**
|
|
@@ -1910,9 +2028,16 @@ declare class StoryboardEngine {
|
|
|
1910
2028
|
* and smoothly transitions the camera/overlays from the current state.
|
|
1911
2029
|
*/
|
|
1912
2030
|
execute(storyboard: Storyboard): void;
|
|
1913
|
-
/**
|
|
2031
|
+
/**
|
|
2032
|
+
* Abort pending STEP dispatches from the current storyboard. Overlay
|
|
2033
|
+
* removal timers are left alone so already-visible overlays still auto-
|
|
2034
|
+
* expire on their own schedule. To force-clear every overlay, call
|
|
2035
|
+
* `resetVisuals()` instead.
|
|
2036
|
+
*/
|
|
1914
2037
|
cancelPending(): void;
|
|
1915
|
-
/**
|
|
2038
|
+
/** Cancel every removal timer (used by resetVisuals only). */
|
|
2039
|
+
private cancelAllRemovalTimers;
|
|
2040
|
+
/** Reset visuals: clear overlays, cancel every removal timer, fit camera. */
|
|
1916
2041
|
resetVisuals(): void;
|
|
1917
2042
|
/** Execute one step — dispatch to narrationStore. Returns true if applied. */
|
|
1918
2043
|
private runStep;
|
|
@@ -2012,14 +2137,14 @@ declare const StoryboardActionSchema: z.ZodUnion<[z.ZodEffects<z.ZodObject<{
|
|
|
2012
2137
|
intensity: z.ZodDefault<z.ZodEnum<["subtle", "normal", "strong"]>>;
|
|
2013
2138
|
}, "strip", z.ZodTypeAny, {
|
|
2014
2139
|
type: "pulse";
|
|
2140
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2015
2141
|
target_block: string;
|
|
2016
2142
|
count: number;
|
|
2017
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2018
2143
|
}, {
|
|
2019
2144
|
type: "pulse";
|
|
2020
2145
|
target_block: string;
|
|
2021
|
-
count?: number | undefined;
|
|
2022
2146
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2147
|
+
count?: number | undefined;
|
|
2023
2148
|
}>, z.ZodObject<{
|
|
2024
2149
|
type: z.ZodLiteral<"callout">;
|
|
2025
2150
|
from_block: z.ZodString;
|
|
@@ -2192,14 +2317,14 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2192
2317
|
intensity: z.ZodDefault<z.ZodEnum<["subtle", "normal", "strong"]>>;
|
|
2193
2318
|
}, "strip", z.ZodTypeAny, {
|
|
2194
2319
|
type: "pulse";
|
|
2320
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2195
2321
|
target_block: string;
|
|
2196
2322
|
count: number;
|
|
2197
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2198
2323
|
}, {
|
|
2199
2324
|
type: "pulse";
|
|
2200
2325
|
target_block: string;
|
|
2201
|
-
count?: number | undefined;
|
|
2202
2326
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2327
|
+
count?: number | undefined;
|
|
2203
2328
|
}>, z.ZodObject<{
|
|
2204
2329
|
type: z.ZodLiteral<"callout">;
|
|
2205
2330
|
from_block: z.ZodString;
|
|
@@ -2300,9 +2425,9 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2300
2425
|
draw_duration_ms: number;
|
|
2301
2426
|
} | {
|
|
2302
2427
|
type: "pulse";
|
|
2428
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2303
2429
|
target_block: string;
|
|
2304
2430
|
count: number;
|
|
2305
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2306
2431
|
} | {
|
|
2307
2432
|
type: "callout";
|
|
2308
2433
|
curve: "straight" | "curved" | "zigzag";
|
|
@@ -2358,8 +2483,8 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2358
2483
|
} | {
|
|
2359
2484
|
type: "pulse";
|
|
2360
2485
|
target_block: string;
|
|
2361
|
-
count?: number | undefined;
|
|
2362
2486
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2487
|
+
count?: number | undefined;
|
|
2363
2488
|
} | {
|
|
2364
2489
|
type: "callout";
|
|
2365
2490
|
from_block: string;
|
|
@@ -2418,9 +2543,9 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2418
2543
|
draw_duration_ms: number;
|
|
2419
2544
|
} | {
|
|
2420
2545
|
type: "pulse";
|
|
2546
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2421
2547
|
target_block: string;
|
|
2422
2548
|
count: number;
|
|
2423
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2424
2549
|
} | {
|
|
2425
2550
|
type: "callout";
|
|
2426
2551
|
curve: "straight" | "curved" | "zigzag";
|
|
@@ -2479,8 +2604,8 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2479
2604
|
} | {
|
|
2480
2605
|
type: "pulse";
|
|
2481
2606
|
target_block: string;
|
|
2482
|
-
count?: number | undefined;
|
|
2483
2607
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2608
|
+
count?: number | undefined;
|
|
2484
2609
|
} | {
|
|
2485
2610
|
type: "callout";
|
|
2486
2611
|
from_block: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1782,11 +1782,45 @@ interface TutorModeContainerProps {
|
|
|
1782
1782
|
* Default: 3500ms.
|
|
1783
1783
|
*/
|
|
1784
1784
|
minOverlayDurationMs?: number;
|
|
1785
|
+
/**
|
|
1786
|
+
* Background colour of the container surround (visible around the PDF when
|
|
1787
|
+
* the viewport is larger than the page fit). Default: `#ffffff`. Pass a
|
|
1788
|
+
* dark value for dark-themed hosts.
|
|
1789
|
+
*/
|
|
1790
|
+
backgroundColor?: string;
|
|
1791
|
+
/**
|
|
1792
|
+
* Optional content to render while the PDF document/page is still loading.
|
|
1793
|
+
* Receives the loading stage so the host can show a spinner, a skeleton,
|
|
1794
|
+
* or a custom brand. If omitted, a minimal default spinner is rendered on
|
|
1795
|
+
* the `backgroundColor` surround.
|
|
1796
|
+
*/
|
|
1797
|
+
loadingComponent?: react__default.ReactNode;
|
|
1798
|
+
/**
|
|
1799
|
+
* Fired when the underlying viewer's page changes from any source — the
|
|
1800
|
+
* agent API (`agentTools.goToPage / nextPage / previousPage`), the sidebar
|
|
1801
|
+
* (bookmarks, thumbnails, search), or a programmatic
|
|
1802
|
+
* `useViewerStore().goToPage` call. Use this to keep your own
|
|
1803
|
+
* `pageNumber` state (the controlled prop you pass in) in lockstep with
|
|
1804
|
+
* the viewer, so agent-driven navigation actually moves the rendered
|
|
1805
|
+
* page and downstream concerns (progress save, recap, etc.) see the
|
|
1806
|
+
* right value.
|
|
1807
|
+
*
|
|
1808
|
+
* ```tsx
|
|
1809
|
+
* const [currentPage, setCurrentPage] = useState(1);
|
|
1810
|
+
* <TutorModeContainer
|
|
1811
|
+
* pageNumber={currentPage}
|
|
1812
|
+
* onPageChange={setCurrentPage} // ← bidirectional sync
|
|
1813
|
+
* />
|
|
1814
|
+
* ```
|
|
1815
|
+
*
|
|
1816
|
+
* Added in v0.4.2.
|
|
1817
|
+
*/
|
|
1818
|
+
onPageChange?: (page: number) => void;
|
|
1785
1819
|
className?: string;
|
|
1786
1820
|
}
|
|
1787
1821
|
/** Build a cross-page/block index from the raw bbox list. */
|
|
1788
1822
|
declare function buildBBoxIndex(bboxData: PageBBoxData[]): BBoxIndex;
|
|
1789
|
-
declare function TutorModeContainer({ pageNumber, bboxData, narrationStore, scale, rotation, currentChunk, llm, idleTimeoutMs, llmTimeoutMs, embeddingProvider, showSubtitles, showExitButton, onExitTutorMode, minOverlayDurationMs, className, }: TutorModeContainerProps): react_jsx_runtime.JSX.Element;
|
|
1823
|
+
declare function TutorModeContainer({ pageNumber, bboxData, narrationStore, scale, rotation, currentChunk, llm, idleTimeoutMs, llmTimeoutMs, embeddingProvider, showSubtitles, showExitButton, onExitTutorMode, minOverlayDurationMs, backgroundColor, loadingComponent, onPageChange, className, }: TutorModeContainerProps): react_jsx_runtime.JSX.Element;
|
|
1790
1824
|
|
|
1791
1825
|
interface CinemaLayerProps {
|
|
1792
1826
|
page: PageBBoxData;
|
|
@@ -1816,13 +1850,19 @@ interface SpotlightMaskProps {
|
|
|
1816
1850
|
durationMs?: number;
|
|
1817
1851
|
}
|
|
1818
1852
|
/**
|
|
1819
|
-
*
|
|
1820
|
-
*
|
|
1821
|
-
*
|
|
1822
|
-
*
|
|
1853
|
+
* Design: **Theatrical spotlight.** A warm-ink dim (not pure black)
|
|
1854
|
+
* closes over the whole page, then a feathered cutout reveals the
|
|
1855
|
+
* target block. A thin terracotta accent ring follows the cutout shape
|
|
1856
|
+
* — the same colour used by every other overlay so the spotlit region
|
|
1857
|
+
* is clearly part of the same annotation system.
|
|
1858
|
+
*
|
|
1859
|
+
* The dim colour is warm INK (`#2a2420`) rather than `#000` so the
|
|
1860
|
+
* dimmed area looks like the PDF pushed into shadow rather than
|
|
1861
|
+
* blacked out. On light textbook pages this reads as "atmosphere"
|
|
1862
|
+
* instead of "censorship".
|
|
1823
1863
|
*
|
|
1824
|
-
*
|
|
1825
|
-
*
|
|
1864
|
+
* The accent ring animates with a slight stagger after the dim, so the
|
|
1865
|
+
* reveal has a subtle two-beat cadence: darken → point.
|
|
1826
1866
|
*/
|
|
1827
1867
|
declare function SpotlightMask({ page, bbox, action, durationMs, }: SpotlightMaskProps): react_jsx_runtime.JSX.Element;
|
|
1828
1868
|
|
|
@@ -1836,12 +1876,40 @@ interface AnimatedHighlightProps {
|
|
|
1836
1876
|
bbox: BBoxCoords;
|
|
1837
1877
|
action: ActionHighlight;
|
|
1838
1878
|
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Design: **Real highlighter stroke.** A flat rectangle feels digital;
|
|
1881
|
+
* a real highlighter has fibrous texture, a soft inner + harder outer
|
|
1882
|
+
* edge, a slight over-bleed past the baseline, and visible uneven
|
|
1883
|
+
* starts/ends where the pen hit and lifted the paper.
|
|
1884
|
+
*
|
|
1885
|
+
* Implementation:
|
|
1886
|
+
* - Double-stroke — a broad soft wash behind a tighter primary stroke
|
|
1887
|
+
* so the mark has depth where they overlap.
|
|
1888
|
+
* - Slight vertical over-bleed (2–3 px above/below the bbox) so the
|
|
1889
|
+
* highlight doesn't look clipped to the text baseline.
|
|
1890
|
+
* - Rounded caps + uneven left/right ends via tapered start/finish
|
|
1891
|
+
* for the "pen hit the page" look.
|
|
1892
|
+
* - Feathered edge mask via SVG filter for the fibrous marker feel.
|
|
1893
|
+
*/
|
|
1839
1894
|
declare function AnimatedHighlight({ bbox, action }: AnimatedHighlightProps): react_jsx_runtime.JSX.Element;
|
|
1840
1895
|
|
|
1841
1896
|
interface PulseOverlayProps {
|
|
1842
1897
|
bbox: BBoxCoords;
|
|
1843
1898
|
action: ActionPulse;
|
|
1844
1899
|
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Design: **Camera viewfinder brackets.** Four L-shapes slide in from
|
|
1902
|
+
* each corner of the target block, like framing crosshairs on a camera.
|
|
1903
|
+
* Behind them, a soft radial glow pulses in sync with the bracket
|
|
1904
|
+
* emphasis — a "look here" cue that points without blocking content.
|
|
1905
|
+
*
|
|
1906
|
+
* Intensity controls bracket length + stroke weight + glow strength.
|
|
1907
|
+
* `count` controls how many emphasis pulses happen before the overlay
|
|
1908
|
+
* settles.
|
|
1909
|
+
*
|
|
1910
|
+
* Brackets slide in from OUTSIDE the block then snap to the corners,
|
|
1911
|
+
* which reads as "framing" rather than the usual bordered box.
|
|
1912
|
+
*/
|
|
1845
1913
|
declare function PulseOverlay({ bbox, action }: PulseOverlayProps): react_jsx_runtime.JSX.Element;
|
|
1846
1914
|
|
|
1847
1915
|
interface CalloutArrowProps {
|
|
@@ -1849,6 +1917,17 @@ interface CalloutArrowProps {
|
|
|
1849
1917
|
toBbox: BBoxCoords;
|
|
1850
1918
|
action: ActionCallout;
|
|
1851
1919
|
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Design: **Editorial connector.** Hand-drawn feel via a refined stroke
|
|
1922
|
+
* + a small origin dot at the "from" end (like a teacher's pen planted
|
|
1923
|
+
* on the page before they draw the arrow). The arrowhead is a slender
|
|
1924
|
+
* open caret rather than a heavy filled triangle — reads as annotation,
|
|
1925
|
+
* not direction-signage.
|
|
1926
|
+
*
|
|
1927
|
+
* An optional label pill rides the arrow's trailing end using the same
|
|
1928
|
+
* editorial pin language as StickyLabel (cream paper, terracotta rule,
|
|
1929
|
+
* serif small-caps). Everything uses ACCENT for colour consistency.
|
|
1930
|
+
*/
|
|
1852
1931
|
declare function CalloutArrow({ fromBbox, toBbox, action }: CalloutArrowProps): react_jsx_runtime.JSX.Element;
|
|
1853
1932
|
|
|
1854
1933
|
interface GhostReferenceProps {
|
|
@@ -1858,24 +1937,50 @@ interface GhostReferenceProps {
|
|
|
1858
1937
|
sourcePageNumber: number;
|
|
1859
1938
|
action: ActionGhostReference;
|
|
1860
1939
|
}
|
|
1861
|
-
|
|
1862
|
-
* Renders a floating "ghost" card referencing a block from another page.
|
|
1863
|
-
* Shows a minimap of the source page with the target bbox highlighted,
|
|
1864
|
-
* plus the block's text description as a caption.
|
|
1865
|
-
*/
|
|
1866
|
-
declare function GhostReference({ page, sourceBbox, sourceBlockText, sourcePageNumber, action, }: GhostReferenceProps): react_jsx_runtime.JSX.Element;
|
|
1940
|
+
declare function GhostReference({ page, sourceBbox, sourceBlockText, action, }: GhostReferenceProps): react_jsx_runtime.JSX.Element;
|
|
1867
1941
|
|
|
1868
1942
|
interface BoxOverlayProps {
|
|
1869
1943
|
bbox: BBoxCoords;
|
|
1870
1944
|
action: ActionBox;
|
|
1871
1945
|
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Design: **Framed region.** A structural region marker — thinner and
|
|
1948
|
+
* more refined than the previous generic 3px coloured border. A subtle
|
|
1949
|
+
* accent-tinted wash fills the interior so the framed region reads as
|
|
1950
|
+
* "selected" even without a thick border. Dashed style uses a custom
|
|
1951
|
+
* dash pattern that matches the editorial vocabulary.
|
|
1952
|
+
*
|
|
1953
|
+
* Honours `action.color` when the LLM specifies something non-default,
|
|
1954
|
+
* otherwise falls through to the terracotta accent so boxes fit the
|
|
1955
|
+
* system.
|
|
1956
|
+
*/
|
|
1872
1957
|
declare function BoxOverlay({ bbox, action }: BoxOverlayProps): react_jsx_runtime.JSX.Element;
|
|
1873
1958
|
|
|
1874
1959
|
interface StickyLabelProps {
|
|
1875
|
-
|
|
1960
|
+
/**
|
|
1961
|
+
* Pre-computed anchor point in viewport pixels — the label will be
|
|
1962
|
+
* placed at this point and positioned relative to it via
|
|
1963
|
+
* `action.position`. See `LabelOverlay` for the coordinate math that
|
|
1964
|
+
* maps a block's bbox + camera state to this value.
|
|
1965
|
+
*/
|
|
1966
|
+
screenAnchor: {
|
|
1967
|
+
x: number;
|
|
1968
|
+
y: number;
|
|
1969
|
+
};
|
|
1876
1970
|
action: ActionLabel;
|
|
1877
1971
|
}
|
|
1878
|
-
|
|
1972
|
+
/**
|
|
1973
|
+
* Editorial annotation pin. The label body sits a short distance from
|
|
1974
|
+
* the target block, connected by a hairline stem and a small marker
|
|
1975
|
+
* disc at the anchor point. Body uses a classical serif at small-caps
|
|
1976
|
+
* sizing — feels like a scholar's tag, not a browser toast.
|
|
1977
|
+
*
|
|
1978
|
+
* Positioning math: caller pre-computes the `screenAnchor` (usually the
|
|
1979
|
+
* midpoint of the block edge the label is attached to), and this
|
|
1980
|
+
* component lays out the pin on the appropriate side via CSS translate
|
|
1981
|
+
* offsets.
|
|
1982
|
+
*/
|
|
1983
|
+
declare function StickyLabel({ screenAnchor, action }: StickyLabelProps): react_jsx_runtime.JSX.Element;
|
|
1879
1984
|
|
|
1880
1985
|
interface SubtitleBarProps {
|
|
1881
1986
|
text: string | null;
|
|
@@ -1902,7 +2007,20 @@ interface EngineDeps {
|
|
|
1902
2007
|
}
|
|
1903
2008
|
declare class StoryboardEngine {
|
|
1904
2009
|
private deps;
|
|
1905
|
-
|
|
2010
|
+
/**
|
|
2011
|
+
* Timers that schedule the START of a step (via `setTimeout(runStep, at_ms)`).
|
|
2012
|
+
* These are storyboard-scoped: when a new storyboard arrives, anything still
|
|
2013
|
+
* pending should be abandoned.
|
|
2014
|
+
*/
|
|
2015
|
+
private pendingStepTimers;
|
|
2016
|
+
/**
|
|
2017
|
+
* Timers that auto-REMOVE an already-placed overlay after its visible
|
|
2018
|
+
* duration. Keyed by overlay id so we can cancel one specifically. These are
|
|
2019
|
+
* NOT cancelled when a new storyboard starts — otherwise the still-visible
|
|
2020
|
+
* overlay from the previous beat would get stranded in the store forever
|
|
2021
|
+
* (the "stuck spotlight" bug).
|
|
2022
|
+
*/
|
|
2023
|
+
private overlayRemovalTimers;
|
|
1906
2024
|
private currentStoryboardId;
|
|
1907
2025
|
constructor(deps: EngineDeps);
|
|
1908
2026
|
/**
|
|
@@ -1910,9 +2028,16 @@ declare class StoryboardEngine {
|
|
|
1910
2028
|
* and smoothly transitions the camera/overlays from the current state.
|
|
1911
2029
|
*/
|
|
1912
2030
|
execute(storyboard: Storyboard): void;
|
|
1913
|
-
/**
|
|
2031
|
+
/**
|
|
2032
|
+
* Abort pending STEP dispatches from the current storyboard. Overlay
|
|
2033
|
+
* removal timers are left alone so already-visible overlays still auto-
|
|
2034
|
+
* expire on their own schedule. To force-clear every overlay, call
|
|
2035
|
+
* `resetVisuals()` instead.
|
|
2036
|
+
*/
|
|
1914
2037
|
cancelPending(): void;
|
|
1915
|
-
/**
|
|
2038
|
+
/** Cancel every removal timer (used by resetVisuals only). */
|
|
2039
|
+
private cancelAllRemovalTimers;
|
|
2040
|
+
/** Reset visuals: clear overlays, cancel every removal timer, fit camera. */
|
|
1916
2041
|
resetVisuals(): void;
|
|
1917
2042
|
/** Execute one step — dispatch to narrationStore. Returns true if applied. */
|
|
1918
2043
|
private runStep;
|
|
@@ -2012,14 +2137,14 @@ declare const StoryboardActionSchema: z.ZodUnion<[z.ZodEffects<z.ZodObject<{
|
|
|
2012
2137
|
intensity: z.ZodDefault<z.ZodEnum<["subtle", "normal", "strong"]>>;
|
|
2013
2138
|
}, "strip", z.ZodTypeAny, {
|
|
2014
2139
|
type: "pulse";
|
|
2140
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2015
2141
|
target_block: string;
|
|
2016
2142
|
count: number;
|
|
2017
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2018
2143
|
}, {
|
|
2019
2144
|
type: "pulse";
|
|
2020
2145
|
target_block: string;
|
|
2021
|
-
count?: number | undefined;
|
|
2022
2146
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2147
|
+
count?: number | undefined;
|
|
2023
2148
|
}>, z.ZodObject<{
|
|
2024
2149
|
type: z.ZodLiteral<"callout">;
|
|
2025
2150
|
from_block: z.ZodString;
|
|
@@ -2192,14 +2317,14 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2192
2317
|
intensity: z.ZodDefault<z.ZodEnum<["subtle", "normal", "strong"]>>;
|
|
2193
2318
|
}, "strip", z.ZodTypeAny, {
|
|
2194
2319
|
type: "pulse";
|
|
2320
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2195
2321
|
target_block: string;
|
|
2196
2322
|
count: number;
|
|
2197
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2198
2323
|
}, {
|
|
2199
2324
|
type: "pulse";
|
|
2200
2325
|
target_block: string;
|
|
2201
|
-
count?: number | undefined;
|
|
2202
2326
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2327
|
+
count?: number | undefined;
|
|
2203
2328
|
}>, z.ZodObject<{
|
|
2204
2329
|
type: z.ZodLiteral<"callout">;
|
|
2205
2330
|
from_block: z.ZodString;
|
|
@@ -2300,9 +2425,9 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2300
2425
|
draw_duration_ms: number;
|
|
2301
2426
|
} | {
|
|
2302
2427
|
type: "pulse";
|
|
2428
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2303
2429
|
target_block: string;
|
|
2304
2430
|
count: number;
|
|
2305
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2306
2431
|
} | {
|
|
2307
2432
|
type: "callout";
|
|
2308
2433
|
curve: "straight" | "curved" | "zigzag";
|
|
@@ -2358,8 +2483,8 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2358
2483
|
} | {
|
|
2359
2484
|
type: "pulse";
|
|
2360
2485
|
target_block: string;
|
|
2361
|
-
count?: number | undefined;
|
|
2362
2486
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2487
|
+
count?: number | undefined;
|
|
2363
2488
|
} | {
|
|
2364
2489
|
type: "callout";
|
|
2365
2490
|
from_block: string;
|
|
@@ -2418,9 +2543,9 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2418
2543
|
draw_duration_ms: number;
|
|
2419
2544
|
} | {
|
|
2420
2545
|
type: "pulse";
|
|
2546
|
+
intensity: "subtle" | "normal" | "strong";
|
|
2421
2547
|
target_block: string;
|
|
2422
2548
|
count: number;
|
|
2423
|
-
intensity: "subtle" | "normal" | "strong";
|
|
2424
2549
|
} | {
|
|
2425
2550
|
type: "callout";
|
|
2426
2551
|
curve: "straight" | "curved" | "zigzag";
|
|
@@ -2479,8 +2604,8 @@ declare const StoryboardSchema: z.ZodObject<{
|
|
|
2479
2604
|
} | {
|
|
2480
2605
|
type: "pulse";
|
|
2481
2606
|
target_block: string;
|
|
2482
|
-
count?: number | undefined;
|
|
2483
2607
|
intensity?: "subtle" | "normal" | "strong" | undefined;
|
|
2608
|
+
count?: number | undefined;
|
|
2484
2609
|
} | {
|
|
2485
2610
|
type: "callout";
|
|
2486
2611
|
from_block: string;
|