@poco-ai/agentero-dsh-pdf 0.0.0-stage → 0.1.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/lib/client/bookmark.d.ts +34 -0
- package/lib/client/button.d.ts +16 -0
- package/lib/client/chat-actions.d.ts +7 -0
- package/lib/client/cn.d.ts +3 -0
- package/lib/client/comment-cards.d.ts +35 -0
- package/lib/client/embed-reader.d.ts +48 -0
- package/lib/client/engine.d.ts +3 -0
- package/lib/client/find.d.ts +22 -0
- package/lib/client/highlight-color-stack.d.ts +24 -0
- package/lib/client/index.d.ts +31 -0
- package/lib/client/link-layer.d.ts +27 -0
- package/lib/client/link-target.d.ts +2 -0
- package/lib/client/locale.d.ts +80 -0
- package/lib/client/outline.d.ts +25 -0
- package/lib/client/page-theme.d.ts +36 -0
- package/lib/client/palette.d.ts +25 -0
- package/lib/client/pan-drag.d.ts +31 -0
- package/lib/client/pan-handler.d.ts +20 -0
- package/lib/client/pdf-bottom-bar.d.ts +25 -0
- package/lib/client/pdf-chrome-surface.d.ts +23 -0
- package/lib/client/pdf-panel.d.ts +66 -0
- package/lib/client/pdf-toolbar.d.ts +11 -0
- package/lib/client/popover.d.ts +10 -0
- package/lib/client/selection-menu.d.ts +30 -0
- package/lib/client/tooltip.d.ts +7 -0
- package/lib/client/translate-card.d.ts +37 -0
- package/lib/client/translation/coverage.d.ts +15 -0
- package/lib/client/translation/extract.d.ts +7 -0
- package/lib/client/translation/fonts.d.ts +6 -0
- package/lib/client/translation/layout.d.ts +19 -0
- package/lib/client/translation/page-overlay.d.ts +10 -0
- package/lib/client/translation/reading-order.d.ts +20 -0
- package/lib/client/translation/regions.d.ts +17 -0
- package/lib/client/translation/translate-paragraph.d.ts +5 -0
- package/lib/client/translation/types.d.ts +107 -0
- package/lib/client/translation/use-page-translation.d.ts +23 -0
- package/lib/client/zoom.d.ts +32 -0
- package/lib/client.js +58413 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -0
- package/package.json +57 -3
- package/src/client/translation/MOTIF-LICENSE.txt +21 -0
- package/README.md +0 -3
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF outline (bookmark) helpers for the sidebar panel.
|
|
3
|
+
*
|
|
4
|
+
* The panel edits a local tree and hands it back to the parent through
|
|
5
|
+
* `onSave`, so these helpers only deal with the in-memory shape: converting
|
|
6
|
+
* the reader's `PdfBookmarkObject[]`, resolving a destination page, and
|
|
7
|
+
* updating / removing a node. Writing the outline back into the PDF belongs to
|
|
8
|
+
* the parent.
|
|
9
|
+
*/
|
|
10
|
+
import { type PdfBookmarkObject } from '@embedpdf/models';
|
|
11
|
+
/** One outline node while it is being edited in the sidebar. */
|
|
12
|
+
export type EditableBookmark = {
|
|
13
|
+
id: string;
|
|
14
|
+
/** Original tree path; null for a new bookmark. */
|
|
15
|
+
origin: string | null;
|
|
16
|
+
originalTitle?: string;
|
|
17
|
+
title: string;
|
|
18
|
+
/** Only set for a new / explicitly retargeted bookmark (zero-based). */
|
|
19
|
+
pageIndex?: number;
|
|
20
|
+
target?: PdfBookmarkObject['target'];
|
|
21
|
+
children: EditableBookmark[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the zero-based page index a PDF bookmark points to.
|
|
25
|
+
* Supports direct destinations and GoTo action destinations.
|
|
26
|
+
* Returns null for bookmarks with no target or unsupported action types.
|
|
27
|
+
*/
|
|
28
|
+
export declare function bookmarkPageIndex(node: Pick<PdfBookmarkObject, 'target'>): number | null;
|
|
29
|
+
/** Convert the reader's bookmark tree into editable nodes. */
|
|
30
|
+
export declare function editableBookmarks(nodes: PdfBookmarkObject[], prefix?: string): EditableBookmark[];
|
|
31
|
+
/** Replace one node (or drop it when `update` returns null). */
|
|
32
|
+
export declare function updateBookmark(nodes: EditableBookmark[], id: string, update: (node: EditableBookmark) => EditableBookmark | null): EditableBookmark[];
|
|
33
|
+
/** Remove one node but promote its children to its position. */
|
|
34
|
+
export declare function removeBookmark(nodes: EditableBookmark[], id: string): EditableBookmark[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type * as React from "react";
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | null | undefined;
|
|
5
|
+
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
type ButtonProps = React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* `forwardRef` matters: Tooltip/Popover triggers clone the child with an anchor
|
|
12
|
+
* ref. A plain function component drops that ref, so the popper never measured
|
|
13
|
+
* the trigger and the content stayed parked offscreen.
|
|
14
|
+
*/
|
|
15
|
+
declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
16
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
type SessionId = Parameters<Context['sessions']['binding']>[0];
|
|
3
|
+
/** Bind PDF actions to their own sidebar session, even after navigation. */
|
|
4
|
+
export declare function pdfChatActions(ctx: Context, sessionId: SessionId): {
|
|
5
|
+
ask(text: string): Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PropsLocale } from "@deepseek-ai/dsh-client-ui-slots";
|
|
2
|
+
type PdfT = PropsLocale<"agentero.pdf">["t"];
|
|
3
|
+
type CommentRect = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
w: number;
|
|
7
|
+
h: number;
|
|
8
|
+
};
|
|
9
|
+
export type CommentMark = {
|
|
10
|
+
id: string;
|
|
11
|
+
kind: string;
|
|
12
|
+
note: string;
|
|
13
|
+
rects: CommentRect[];
|
|
14
|
+
space: "norm" | "pt";
|
|
15
|
+
/** Vault-relative PNG for a visual region mark. */
|
|
16
|
+
asset?: string;
|
|
17
|
+
};
|
|
18
|
+
type CommentCardsProps = {
|
|
19
|
+
marks: readonly CommentMark[];
|
|
20
|
+
/** Rendered page height in CSS px. */
|
|
21
|
+
pageHeight: number;
|
|
22
|
+
/** PDF page size at scale 1, used to normalize point-space rects. */
|
|
23
|
+
pageSize: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
t: PdfT;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* One static card per current-page mark that has a note or a crop, pinned to
|
|
31
|
+
* the page's right edge. Chrome only: the in-place editor, crop tool, and
|
|
32
|
+
* action bar stay out.
|
|
33
|
+
*/
|
|
34
|
+
export declare function CommentCards({ marks, pageHeight, pageSize, t }: CommentCardsProps): import("react").JSX.Element | null;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { EditableBookmark } from './bookmark';
|
|
4
|
+
import { type PdfPaperTone } from './page-theme';
|
|
5
|
+
import type { PaintMark, PdfPageSize, PdfRect } from './pdf-panel';
|
|
6
|
+
type PdfT = PropsLocale<'agentero.pdf'>['t'];
|
|
7
|
+
export interface SelectionHit {
|
|
8
|
+
quote: string;
|
|
9
|
+
page: number;
|
|
10
|
+
/** Page-point rectangles from the live selection. */
|
|
11
|
+
rects: PdfRect[];
|
|
12
|
+
/** Page size at scale 1, for normalizing per-id mark anchors. */
|
|
13
|
+
pageWidth: number;
|
|
14
|
+
pageHeight: number;
|
|
15
|
+
screenX: number;
|
|
16
|
+
screenY: number;
|
|
17
|
+
}
|
|
18
|
+
interface EmbedReaderProps {
|
|
19
|
+
bytes: ArrayBuffer;
|
|
20
|
+
docId: string;
|
|
21
|
+
marks: readonly PaintMark[];
|
|
22
|
+
pdfTone: PdfPaperTone;
|
|
23
|
+
onSetPdfTone: (tone: PdfPaperTone) => void;
|
|
24
|
+
onSelect: (hit: SelectionHit) => void;
|
|
25
|
+
/** The live text selection went away; the floating menu must hide. */
|
|
26
|
+
onDeselect: () => void;
|
|
27
|
+
/** Persist the outline back into the PDF; resolves after the host wrote it. */
|
|
28
|
+
saveBookmarks: (nodes: EditableBookmark[]) => Promise<void>;
|
|
29
|
+
/** Translate one page's text through the host. */
|
|
30
|
+
translate: (text: string, signal?: AbortSignal) => Promise<string>;
|
|
31
|
+
loadLayout: (ref: string, signal?: AbortSignal) => Promise<unknown>;
|
|
32
|
+
/** Pinned translation chip, drawn inside the page so it scrolls with it. */
|
|
33
|
+
translatePin?: {
|
|
34
|
+
page: number;
|
|
35
|
+
rects: PdfRect[];
|
|
36
|
+
pageSize: PdfPageSize;
|
|
37
|
+
onOpen: (screen: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
}) => void;
|
|
41
|
+
};
|
|
42
|
+
menu: ReactNode;
|
|
43
|
+
/** Increment after a mark is saved so the blue selection does not cover it. */
|
|
44
|
+
selectionClearVersion: number;
|
|
45
|
+
t: PdfT;
|
|
46
|
+
}
|
|
47
|
+
export declare function EmbedReader(props: EmbedReaderProps): ReactNode;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode, RefObject } from 'react';
|
|
2
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
type PdfT = PropsLocale<'agentero.pdf'>['t'];
|
|
4
|
+
/**
|
|
5
|
+
* In-document find (⌘F): the floating query bar, the debounced full-document
|
|
6
|
+
* search, and prev / next navigation that scrolls the focused hit into view.
|
|
7
|
+
*
|
|
8
|
+
* The bar lives inside the PDF host so the shortcut only opens it while the
|
|
9
|
+
* reader is hovered or focused; the hit highlights are rendered separately by
|
|
10
|
+
* {@link PdfSearchLayer} inside each page.
|
|
11
|
+
*/
|
|
12
|
+
export declare function PdfFindLayer({ docId, hostRef, t, }: {
|
|
13
|
+
docId: string;
|
|
14
|
+
hostRef: RefObject<HTMLDivElement | null>;
|
|
15
|
+
t: PdfT;
|
|
16
|
+
}): ReactNode;
|
|
17
|
+
/** Hit highlights for the current find query, one layer per rendered page. */
|
|
18
|
+
export declare function PdfSearchLayer({ docId, pageIndex, }: {
|
|
19
|
+
docId: string;
|
|
20
|
+
pageIndex: number;
|
|
21
|
+
}): ReactNode;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Ref } from "react";
|
|
2
|
+
import type { PropsLocale } from "@deepseek-ai/dsh-client-ui-slots";
|
|
3
|
+
import { type HighlightColor } from "./palette";
|
|
4
|
+
export declare const HIGHLIGHT_COLOR_STACK_COLLAPSED_W: number;
|
|
5
|
+
export declare const HIGHLIGHT_COLOR_STACK_EXPANDED_W: number;
|
|
6
|
+
type PdfT = PropsLocale<"agentero.pdf">["t"];
|
|
7
|
+
type HighlightColorStackProps = {
|
|
8
|
+
ref?: Ref<HTMLFieldSetElement>;
|
|
9
|
+
onSelect: (color: HighlightColor) => void;
|
|
10
|
+
/** Currently active color (annotation recolor menu). */
|
|
11
|
+
activeColor?: HighlightColor;
|
|
12
|
+
/** Tooltip / expand direction relative to the toolbar. */
|
|
13
|
+
tooltipSide?: "top" | "bottom";
|
|
14
|
+
className?: string;
|
|
15
|
+
t: PdfT;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Semi-overlapping highlight color dots. Hover / focus-within fans them out
|
|
19
|
+
* to the left (right edge stays anchored near the toolbar divider) with a
|
|
20
|
+
* compact spring. Only this slot's width animates — parents should pin the
|
|
21
|
+
* toolbar by its right edge so sibling actions do not move.
|
|
22
|
+
*/
|
|
23
|
+
export declare function HighlightColorStack({ ref, onSelect, activeColor, tooltipSide, className, t, }: HighlightColorStackProps): import("react").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
declare module '@deepseek-ai/cordis' {
|
|
3
|
+
interface Context {
|
|
4
|
+
/** Opener registry from the host browser plugin. */
|
|
5
|
+
agentero: {
|
|
6
|
+
registerOpener(kind: 'paper' | 'note', opener: (id: string) => void): () => void;
|
|
7
|
+
request(url: string, init?: RequestInit): Promise<Response>;
|
|
8
|
+
getVault(): Promise<{
|
|
9
|
+
scope: string;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
declare module '@deepseek-ai/dsh-client-ui-sidebar-right/client' {
|
|
15
|
+
interface SidebarRightTabParamsMap {
|
|
16
|
+
/** Paper directory passed when the library opens this page. */
|
|
17
|
+
'agentero.pdf': {
|
|
18
|
+
readonly ref?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Browser plugin name. */
|
|
23
|
+
export declare const name = "agentero-pdf";
|
|
24
|
+
/** Slot services, the opener registry, and the session's right sidebar. */
|
|
25
|
+
export declare const inject: string[];
|
|
26
|
+
/**
|
|
27
|
+
* Register the PDF page in the session's right sidebar and the paper opener.
|
|
28
|
+
* The library still calls `agentero.open`. This opener focuses the one PDF tab.
|
|
29
|
+
* @param ctx - Browser plugin context.
|
|
30
|
+
*/
|
|
31
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PdfAnnotationObject, PdfLinkAnnoObject, PdfLinkTarget } from '@embedpdf/models';
|
|
2
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
type PdfT = PropsLocale<'agentero.pdf'>['t'];
|
|
5
|
+
export declare function isLinkObject(object: PdfAnnotationObject): object is PdfLinkAnnoObject;
|
|
6
|
+
/**
|
|
7
|
+
* Extract the destination page + anchor position from a link target, if any.
|
|
8
|
+
* Coordinates are PDF-native (origin bottom-left). `pdfX` is null when the
|
|
9
|
+
* destination only pins a row (FitH) or the viewer does not expose x.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getLinkDestination(target: PdfLinkTarget | undefined): {
|
|
12
|
+
pageIndex: number;
|
|
13
|
+
pdfX: number | null;
|
|
14
|
+
pdfY: number;
|
|
15
|
+
} | null;
|
|
16
|
+
/**
|
|
17
|
+
* Transparent hit targets over each link rect. Positioned in page-percentage
|
|
18
|
+
* units so they track zoom for free.
|
|
19
|
+
*/
|
|
20
|
+
export declare function PdfLinkLayer({ docId, pageIndex, pageWidth, pageHeight, t, }: {
|
|
21
|
+
docId: string;
|
|
22
|
+
pageIndex: number;
|
|
23
|
+
pageWidth: number;
|
|
24
|
+
pageHeight: number;
|
|
25
|
+
t: PdfT;
|
|
26
|
+
}): ReactNode;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** PDF panel copy, Chinese source. */
|
|
2
|
+
export declare const zh: {
|
|
3
|
+
title: string;
|
|
4
|
+
empty: string;
|
|
5
|
+
loading: string;
|
|
6
|
+
loadFailed: string;
|
|
7
|
+
missing: string;
|
|
8
|
+
vaultMissing: string;
|
|
9
|
+
prev: string;
|
|
10
|
+
next: string;
|
|
11
|
+
page: string;
|
|
12
|
+
copy: string;
|
|
13
|
+
copied: string;
|
|
14
|
+
highlight: string;
|
|
15
|
+
comment: string;
|
|
16
|
+
translate: string;
|
|
17
|
+
ask: string;
|
|
18
|
+
menu: string;
|
|
19
|
+
commentHint: string;
|
|
20
|
+
askHint: string;
|
|
21
|
+
save: string;
|
|
22
|
+
send: string;
|
|
23
|
+
noSession: string;
|
|
24
|
+
markFailed: string;
|
|
25
|
+
asked: string;
|
|
26
|
+
askFailed: string;
|
|
27
|
+
askedMarkFailed: string;
|
|
28
|
+
translated: string;
|
|
29
|
+
goToPage: string;
|
|
30
|
+
zoom: string;
|
|
31
|
+
paperTone: string;
|
|
32
|
+
paperToneWhite: string;
|
|
33
|
+
paperToneDark: string;
|
|
34
|
+
colorGroup: string;
|
|
35
|
+
colorYellow: string;
|
|
36
|
+
colorGreen: string;
|
|
37
|
+
colorBlue: string;
|
|
38
|
+
colorPink: string;
|
|
39
|
+
colorPurple: string;
|
|
40
|
+
find: string;
|
|
41
|
+
findPlaceholder: string;
|
|
42
|
+
findNoResults: string;
|
|
43
|
+
findPrev: string;
|
|
44
|
+
findNext: string;
|
|
45
|
+
findClose: string;
|
|
46
|
+
linkAria: string;
|
|
47
|
+
outline: string;
|
|
48
|
+
outlineEmpty: string;
|
|
49
|
+
bookmarkAdd: string;
|
|
50
|
+
bookmarkTitle: string;
|
|
51
|
+
bookmarkApply: string;
|
|
52
|
+
bookmarkCancel: string;
|
|
53
|
+
bookmarkRename: string;
|
|
54
|
+
bookmarkDelete: string;
|
|
55
|
+
bookmarkSaving: string;
|
|
56
|
+
bookmarkFailed: string;
|
|
57
|
+
bookmarkPageTitle: string;
|
|
58
|
+
translatePage: string;
|
|
59
|
+
translateAll: string;
|
|
60
|
+
translating: string;
|
|
61
|
+
translation: string;
|
|
62
|
+
translationEmpty: string;
|
|
63
|
+
translationFailed: string;
|
|
64
|
+
translationRetry: string;
|
|
65
|
+
showOriginal: string;
|
|
66
|
+
translateFailed: string;
|
|
67
|
+
pin: string;
|
|
68
|
+
unpin: string;
|
|
69
|
+
close: string;
|
|
70
|
+
};
|
|
71
|
+
/** PDF panel copy, English. */
|
|
72
|
+
export declare const en: {
|
|
73
|
+
[K in keyof typeof zh]: string;
|
|
74
|
+
};
|
|
75
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
76
|
+
interface LocaleNamespaceMap {
|
|
77
|
+
/** PDF panel copy. */
|
|
78
|
+
'agentero.pdf': keyof typeof zh;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF outline (bookmarks) layer: the top-left toolbar chip that opens the
|
|
3
|
+
* outline panel, plus its inline-editable tree.
|
|
4
|
+
*
|
|
5
|
+
* The panel owns only its draft tree. Loading comes from the bookmark plugin
|
|
6
|
+
* capability and every add / rename / delete is persisted by the parent via
|
|
7
|
+
* `onSave`, which writes the outline back into the PDF.
|
|
8
|
+
*/
|
|
9
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
10
|
+
import { type ReactNode } from 'react';
|
|
11
|
+
import { type EditableBookmark } from './bookmark';
|
|
12
|
+
type PdfT = PropsLocale<'agentero.pdf'>['t'];
|
|
13
|
+
type PdfOutlineLayerProps = {
|
|
14
|
+
docId: string;
|
|
15
|
+
/** One-based current page, used when adding a bookmark. */
|
|
16
|
+
currentPage: number;
|
|
17
|
+
/** One-based page navigation, handled by the parent's scroller. */
|
|
18
|
+
onGoToPage: (page: number) => void;
|
|
19
|
+
/** Persist the whole outline; the parent writes it back into the PDF. */
|
|
20
|
+
onSave: (nodes: EditableBookmark[]) => Promise<void>;
|
|
21
|
+
t: PdfT;
|
|
22
|
+
};
|
|
23
|
+
/** Top-left outline toggle + inline-editable outline panel. */
|
|
24
|
+
export declare function PdfOutlineLayer({ docId, currentPage, onGoToPage, onSave, t, }: PdfOutlineLayerProps): ReactNode;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF page paper tones and dark-mode raster styling.
|
|
3
|
+
*
|
|
4
|
+
* Page content has no color-scheme API, so paper colour is applied at the DOM
|
|
5
|
+
* layer over the pdf.js canvas.
|
|
6
|
+
*
|
|
7
|
+
* Only two paper tones exist: solid white and solid black. Black paper is a
|
|
8
|
+
* full invert so white raster areas land exactly on #000 and black text lands
|
|
9
|
+
* on #fff; hue-rotate keeps figure colors roughly correct. Partial inverts were
|
|
10
|
+
* dropped because they left the paper at an ambiguous grey.
|
|
11
|
+
*/
|
|
12
|
+
export type PdfPaperTone = "white" | "dark";
|
|
13
|
+
/** Picker order: light first, black last. */
|
|
14
|
+
export declare const PDF_PAPER_TONES: PdfPaperTone[];
|
|
15
|
+
/** Page shell background, so loading/zoom gaps match the finished paper. */
|
|
16
|
+
export declare const PDF_PAPER_SHELL_CLASS: Record<PdfPaperTone, string>;
|
|
17
|
+
/** Swatch fill for the paper-tone picker. */
|
|
18
|
+
export declare const PDF_PAPER_SWATCH_CLASS: Record<PdfPaperTone, string>;
|
|
19
|
+
export declare function isPdfPaperTone(value: unknown): value is PdfPaperTone;
|
|
20
|
+
/**
|
|
21
|
+
* Dark-mode page raster styling.
|
|
22
|
+
*
|
|
23
|
+
* Full invert: white paper becomes #000 and black ink becomes #fff, so the
|
|
24
|
+
* page reads as a solid black sheet instead of a grey wash. Hue-rotate keeps
|
|
25
|
+
* figure colors roughly correct.
|
|
26
|
+
*/
|
|
27
|
+
export declare const PDF_PAGE_RASTER_DARK_CLASS = "[filter:invert(1)_hue-rotate(180deg)]";
|
|
28
|
+
/**
|
|
29
|
+
* Dark-mode annotation overlay styling.
|
|
30
|
+
*
|
|
31
|
+
* Highlight annotations keep their stored bright palette colors; in dark mode
|
|
32
|
+
* they sit on top of inverted black paper and can look glaring. A gentle
|
|
33
|
+
* brightness + saturation reduction keeps them readable without overwhelming
|
|
34
|
+
* the page.
|
|
35
|
+
*/
|
|
36
|
+
export declare const PDF_ANNOTATION_DARK_CLASS = "[filter:brightness(0.88)_saturate(0.85)]";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** PDF annotation color palette (highlight fill + underline bar). */
|
|
2
|
+
export type HighlightColor = "yellow" | "green" | "blue" | "pink" | "purple";
|
|
3
|
+
export declare const HIGHLIGHT_COLORS: HighlightColor[];
|
|
4
|
+
export declare const DEFAULT_HIGHLIGHT_COLOR: HighlightColor;
|
|
5
|
+
/**
|
|
6
|
+
* Hex colors for highlight swatches. Kept in sync with the translucent fills
|
|
7
|
+
* below so the on-page highlight matches the swatch.
|
|
8
|
+
*/
|
|
9
|
+
export declare const HIGHLIGHT_HEX: Record<HighlightColor, string>;
|
|
10
|
+
/** Default fill opacity for highlight annotations. */
|
|
11
|
+
export declare const HIGHLIGHT_OPACITY = 0.4;
|
|
12
|
+
/** Same fill the annotation layer paints, as an rgba string. */
|
|
13
|
+
export declare function highlightFill(color: HighlightColor): string;
|
|
14
|
+
/** Ordered hex list for color presets. */
|
|
15
|
+
export declare const HIGHLIGHT_HEX_LIST: string[];
|
|
16
|
+
/** Map a stored hex color back to the nearest known palette key. */
|
|
17
|
+
export declare function highlightColorFromHex(hex: string | undefined): HighlightColor;
|
|
18
|
+
/** Coerce an arbitrary stored color string to a known palette key. */
|
|
19
|
+
export declare function normalizeHighlightColor(color: string | undefined): HighlightColor;
|
|
20
|
+
/** Solid dot class for the color picker swatch. */
|
|
21
|
+
export declare function swatchColorClass(color: HighlightColor): string;
|
|
22
|
+
/** Border-color class matching a highlight color (e.g. quoted-text rule). */
|
|
23
|
+
export declare function swatchBorderClass(color: HighlightColor): string;
|
|
24
|
+
/** Hover/edit emphasis overlay color. */
|
|
25
|
+
export declare function highlightHoverOverlayColor(color: HighlightColor): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drag-to-pan (momentary hand tool) for the PDF viewport.
|
|
3
|
+
*
|
|
4
|
+
* Matches the common PDF-reader interaction: hold the middle button, or hold
|
|
5
|
+
* Space and use the left button, and the page follows the cursor 1:1 on both
|
|
6
|
+
* axes until the button is released.
|
|
7
|
+
*
|
|
8
|
+
* The gesture writes native `scrollLeft` / `scrollTop` on the viewport element;
|
|
9
|
+
* the plugin viewport already coalesces the resulting scroll events into
|
|
10
|
+
* EmbedPDF's per-frame scroll metrics, so tiling, fit modes and floating card
|
|
11
|
+
* anchors stay in sync without further work.
|
|
12
|
+
*/
|
|
13
|
+
export type PanDragState = "idle" | "panning";
|
|
14
|
+
/** Scroll container the gesture drives; structural so it stays testable. */
|
|
15
|
+
export type PanDragTarget = Pick<HTMLElement, "addEventListener" | "removeEventListener" | "setPointerCapture" | "releasePointerCapture" | "hasPointerCapture" | "scrollLeft" | "scrollTop">;
|
|
16
|
+
type PanDragGestureOptions = {
|
|
17
|
+
target: PanDragTarget;
|
|
18
|
+
/** True while Space is held, arming left-button drag as well. */
|
|
19
|
+
isLeftDragArmed: () => boolean;
|
|
20
|
+
/** True for targets that must keep their own pointer behavior (editors). */
|
|
21
|
+
isExcludedTarget: (target: EventTarget | null) => boolean;
|
|
22
|
+
/** Cursor feedback; `"panning"` for the duration of a drag. */
|
|
23
|
+
onStateChange?: (state: PanDragState) => void;
|
|
24
|
+
};
|
|
25
|
+
export type PanDragBinding = {
|
|
26
|
+
/** End an in-flight drag (window lost focus) without detaching listeners. */
|
|
27
|
+
cancel(): void;
|
|
28
|
+
dispose(): void;
|
|
29
|
+
};
|
|
30
|
+
export declare function bindPanDragGesture({ target, isLeftDragArmed, isExcludedTarget, onStateChange, }: PanDragGestureOptions): PanDragBinding;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
type PanDragHandlerProps = {
|
|
3
|
+
/** PDF host; Space is claimed with the same ownership rule as `⌘F`. */
|
|
4
|
+
hostRef: RefObject<HTMLDivElement | null>;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Momentary hand tool: middle-button drag always pans, and holding Space arms
|
|
8
|
+
* the left button to behave exactly the same.
|
|
9
|
+
*
|
|
10
|
+
* Space is a bare key with no modifier, so claiming it needs an ownership rule:
|
|
11
|
+
* the hovered viewer wins (focus usually sits on a tab or a neighbouring panel
|
|
12
|
+
* while reading), otherwise the viewer when focus is inside its host or still
|
|
13
|
+
* neutral on `body` after a page click. Editable and button-like targets always
|
|
14
|
+
* keep their native behavior. The pointer gesture is not gated on ownership at
|
|
15
|
+
* all — a drag starts on whatever viewport the pointer is actually on.
|
|
16
|
+
*
|
|
17
|
+
* Must render inside the plugin `<Viewport>` (ViewportElementContext).
|
|
18
|
+
*/
|
|
19
|
+
export declare function PanDragHandler({ hostRef }: PanDragHandlerProps): null;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PropsLocale } from "@deepseek-ai/dsh-client-ui-slots";
|
|
2
|
+
import { type PdfPaperTone } from "./page-theme";
|
|
3
|
+
type PdfT = PropsLocale<"agentero.pdf">["t"];
|
|
4
|
+
type PdfBottomBarProps = {
|
|
5
|
+
/** Hidden until the document reports its page count. */
|
|
6
|
+
totalPages: number;
|
|
7
|
+
/** Editable page number (raw digits while typing). */
|
|
8
|
+
pageField: string;
|
|
9
|
+
onPageFieldChange: (value: string) => void;
|
|
10
|
+
/** True while the field owns focus, so scrolling does not clobber typing. */
|
|
11
|
+
pageFocusedRef: {
|
|
12
|
+
current: boolean;
|
|
13
|
+
};
|
|
14
|
+
onCommitPageField: () => void;
|
|
15
|
+
pdfTone: PdfPaperTone;
|
|
16
|
+
onSetPdfTone: (tone: PdfPaperTone) => void;
|
|
17
|
+
/** Current zoom scale (1 = 100% of the fit-to-width scale). */
|
|
18
|
+
zoomLevel: number;
|
|
19
|
+
/** Apply a zoom scale from the slider. */
|
|
20
|
+
onZoomChange: (zoom: number) => void;
|
|
21
|
+
t: PdfT;
|
|
22
|
+
};
|
|
23
|
+
/** Bottom bar: page field + zoom slider + PDF paper tone. */
|
|
24
|
+
export declare const PdfBottomBar: import("react").MemoExoticComponent<({ totalPages, pageField, onPageFieldChange, pageFocusedRef, onCommitPageField, pdfTone, onSetPdfTone, zoomLevel, onZoomChange, t, }: PdfBottomBarProps) => import("react").JSX.Element | null>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared PDF floating chrome surfaces (Apple-style materials).
|
|
3
|
+
*
|
|
4
|
+
* Small chips (toolbars / find / bottom bar) are lighter glass.
|
|
5
|
+
* Side panels are thicker (stronger blur + shadow).
|
|
6
|
+
* Selection cards stay near-opaque for long-form readability.
|
|
7
|
+
* Mark hosts with `data-pdf-chrome` so reduced-transparency can frost them.
|
|
8
|
+
*/
|
|
9
|
+
/** Compact HUD chips: top toolbars, bottom bar, find bar, page-edge tabs. */
|
|
10
|
+
export declare const PDF_CHROME_CHIP = "border border-border/50 bg-background/80 shadow-sm ring-1 ring-black/5 backdrop-blur-md backdrop-saturate-150 supports-backdrop-blur:bg-background/60 dark:border-white/10 dark:ring-white/10";
|
|
11
|
+
/** Auto-hide chrome: materialize (opacity + slight rise), not a plain fade. */
|
|
12
|
+
export declare const PDF_CHROME_VIS = "transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-opacity motion-reduce:duration-150";
|
|
13
|
+
export declare const PDF_CHROME_VIS_SHOW = "translate-y-0 scale-100 opacity-100";
|
|
14
|
+
export declare const PDF_CHROME_VIS_HIDE = "-translate-y-1 scale-[0.98] opacity-0 motion-reduce:translate-y-0 motion-reduce:scale-100";
|
|
15
|
+
/**
|
|
16
|
+
* Left outline / references / figures panel.
|
|
17
|
+
* Heavier material than chips; enters from the left (spatial consistency).
|
|
18
|
+
*/
|
|
19
|
+
export declare const PDF_SIDE_PANEL = "absolute inset-y-0 left-0 z-20 w-80 select-none border-r border-border/50 bg-background/90 pt-11 pb-2 shadow-lg backdrop-blur-xl backdrop-saturate-150 supports-backdrop-blur:bg-background/75 motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-left-2 motion-safe:duration-200 motion-reduce:animate-none";
|
|
20
|
+
/** Icon-only selection menu — glassier than long-form cards. */
|
|
21
|
+
export declare const PDF_SELECTION_MENU = "rounded-xl border border-border/50 bg-background/90 shadow-xl ring-1 ring-black/5 backdrop-blur-md backdrop-saturate-150 supports-backdrop-blur:bg-background/75 dark:ring-white/10";
|
|
22
|
+
/** Ask / translate / preview cards — near-solid for dense text. */
|
|
23
|
+
export declare const PDF_FLOAT_CARD = "rounded-xl border border-border/60 bg-background/95 text-foreground shadow-xl ring-1 ring-black/5 backdrop-blur-sm supports-backdrop-blur:bg-background/90 dark:ring-white/10";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { EditableBookmark } from './bookmark';
|
|
4
|
+
import { type HighlightColor } from './palette';
|
|
5
|
+
export interface PaintRect {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
w: number;
|
|
9
|
+
h: number;
|
|
10
|
+
}
|
|
11
|
+
export interface PaintMark {
|
|
12
|
+
id: string;
|
|
13
|
+
kind: string;
|
|
14
|
+
page: number;
|
|
15
|
+
rects: PaintRect[];
|
|
16
|
+
space: 'norm' | 'pt';
|
|
17
|
+
note: string;
|
|
18
|
+
/** Highlight palette key, when the store carries one. */
|
|
19
|
+
color?: HighlightColor;
|
|
20
|
+
/** Host image URL tied to the source knowledge base. */
|
|
21
|
+
asset?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Page rectangle in PDF points, the shape the selection plugin reports. */
|
|
24
|
+
export interface PdfRect {
|
|
25
|
+
origin: {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
size: {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface PdfPageSize {
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
}
|
|
38
|
+
export interface MarkAdd {
|
|
39
|
+
ref: string;
|
|
40
|
+
kind: 'highlight' | 'ask' | 'translate';
|
|
41
|
+
quote: string;
|
|
42
|
+
page: number;
|
|
43
|
+
/** Page-point selection rectangles; lets the host write without the CLI. */
|
|
44
|
+
rects?: PdfRect[];
|
|
45
|
+
pageSize?: PdfPageSize;
|
|
46
|
+
color?: HighlightColor;
|
|
47
|
+
comment?: string;
|
|
48
|
+
question?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface PdfInjected {
|
|
51
|
+
loadPdf: (ref: string) => Promise<ArrayBuffer>;
|
|
52
|
+
loadMarks: (ref: string) => Promise<PaintMark[]>;
|
|
53
|
+
addMark: (body: MarkAdd) => Promise<string | undefined>;
|
|
54
|
+
/** Send a question and citation as a new conversation turn. */
|
|
55
|
+
ask: (text: string) => Promise<void>;
|
|
56
|
+
/** Write the PDF outline back to the file; resolves after the host saved it. */
|
|
57
|
+
saveBookmarks: (ref: string, nodes: EditableBookmark[]) => Promise<void>;
|
|
58
|
+
loadLayout: (ref: string, signal?: AbortSignal) => Promise<unknown>;
|
|
59
|
+
/** Translate one page's text; rejects with the host error message. */
|
|
60
|
+
translate: (text: string, signal?: AbortSignal) => Promise<string>;
|
|
61
|
+
}
|
|
62
|
+
type PdfPanelProps = PropsRuntime<'sidebar.right.pane.tab'> & InjectFace<PdfInjected> & PropsLocale<'agentero.pdf'>;
|
|
63
|
+
export declare function paperRef(params: unknown): string;
|
|
64
|
+
export declare function PdfTitle({ useTabInfo, t }: PropsRuntime<'sidebar.right.pane.tab.title'> & PropsLocale<'agentero.pdf'>): ReactNode;
|
|
65
|
+
export declare function PdfPanel(props: PdfPanelProps): ReactNode;
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
type PdfT = PropsLocale<'agentero.pdf'>['t'];
|
|
4
|
+
/** Top-right chrome: full-text translate. */
|
|
5
|
+
export declare function PdfToolbar({ translating, translateOpen, onToggleTranslate, t, }: {
|
|
6
|
+
translating: boolean;
|
|
7
|
+
translateOpen: boolean;
|
|
8
|
+
onToggleTranslate: () => void;
|
|
9
|
+
t: PdfT;
|
|
10
|
+
}): ReactNode;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Popover as PopoverPrimitive } from "radix-ui";
|
|
2
|
+
import type * as React from "react";
|
|
3
|
+
declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element;
|
|
5
|
+
declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): React.JSX.Element;
|
|
6
|
+
declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): React.JSX.Element;
|
|
7
|
+
declare function PopoverHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
8
|
+
declare function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">): React.JSX.Element;
|
|
9
|
+
declare function PopoverDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
|
|
10
|
+
export { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, };
|