pdfjs-reader-core 0.1.3 → 0.1.5

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/dist/index.js CHANGED
@@ -316,13 +316,21 @@ function createViewerStore(initialOverrides = {}) {
316
316
  ...initialOverrides,
317
317
  // Document actions
318
318
  setDocument: (document2) => {
319
- set({
320
- document: document2,
321
- numPages: document2.numPages,
322
- isLoading: false,
323
- error: null,
324
- currentPage: 1
325
- });
319
+ if (document2) {
320
+ set({
321
+ document: document2,
322
+ numPages: document2.numPages,
323
+ isLoading: false,
324
+ error: null,
325
+ currentPage: 1
326
+ });
327
+ } else {
328
+ set({
329
+ document: null,
330
+ numPages: 0,
331
+ isLoading: false
332
+ });
333
+ }
326
334
  },
327
335
  setLoading: (isLoading) => {
328
336
  set({ isLoading });
@@ -1353,6 +1361,12 @@ function createSearchStore(initialOverrides = {}) {
1353
1361
  set({ currentResultIndex: index });
1354
1362
  }
1355
1363
  },
1364
+ setCaseSensitive: (value) => {
1365
+ set({ caseSensitive: value });
1366
+ },
1367
+ setWholeWord: (value) => {
1368
+ set({ wholeWord: value });
1369
+ },
1356
1370
  toggleCaseSensitive: () => {
1357
1371
  set((state) => ({ caseSensitive: !state.caseSensitive }));
1358
1372
  },
@@ -8735,14 +8749,186 @@ var init_DualPageContainer = __esm({
8735
8749
  }
8736
8750
  });
8737
8751
 
8752
+ // src/components/FloatingZoomControls/FloatingZoomControls.tsx
8753
+ import { memo as memo24, useCallback as useCallback32 } from "react";
8754
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
8755
+ var FloatingZoomControls;
8756
+ var init_FloatingZoomControls = __esm({
8757
+ "src/components/FloatingZoomControls/FloatingZoomControls.tsx"() {
8758
+ "use strict";
8759
+ init_hooks();
8760
+ init_utils();
8761
+ FloatingZoomControls = memo24(function FloatingZoomControls2({
8762
+ position = "bottom-right",
8763
+ className,
8764
+ showFitToWidth = true,
8765
+ showFitToPage = false,
8766
+ showZoomLevel = true
8767
+ }) {
8768
+ const { viewerStore } = usePDFViewerStores();
8769
+ const scale = useViewerStore((s) => s.scale);
8770
+ const document2 = useViewerStore((s) => s.document);
8771
+ const handleZoomIn = useCallback32(() => {
8772
+ viewerStore.getState().zoomIn();
8773
+ }, [viewerStore]);
8774
+ const handleZoomOut = useCallback32(() => {
8775
+ viewerStore.getState().zoomOut();
8776
+ }, [viewerStore]);
8777
+ const handleFitToWidth = useCallback32(() => {
8778
+ viewerStore.getState().setScale(1);
8779
+ }, [viewerStore]);
8780
+ const handleFitToPage = useCallback32(() => {
8781
+ viewerStore.getState().setScale(0.75);
8782
+ }, [viewerStore]);
8783
+ if (!document2) return null;
8784
+ const positionClasses = {
8785
+ "bottom-right": "bottom-4 right-4",
8786
+ "bottom-left": "bottom-4 left-4",
8787
+ "top-right": "top-4 right-4",
8788
+ "top-left": "top-4 left-4"
8789
+ };
8790
+ const zoomPercentage = Math.round(scale * 100);
8791
+ return /* @__PURE__ */ jsxs21(
8792
+ "div",
8793
+ {
8794
+ className: cn(
8795
+ "fixed z-50 flex items-center gap-1",
8796
+ "bg-white dark:bg-gray-800 rounded-lg shadow-lg",
8797
+ "border border-gray-200 dark:border-gray-700",
8798
+ "p-1",
8799
+ positionClasses[position],
8800
+ className
8801
+ ),
8802
+ children: [
8803
+ /* @__PURE__ */ jsx25(
8804
+ "button",
8805
+ {
8806
+ onClick: handleZoomOut,
8807
+ className: cn(
8808
+ "w-8 h-8 flex items-center justify-center rounded",
8809
+ "text-gray-700 dark:text-gray-300",
8810
+ "hover:bg-gray-100 dark:hover:bg-gray-700",
8811
+ "transition-colors",
8812
+ "disabled:opacity-50 disabled:cursor-not-allowed"
8813
+ ),
8814
+ disabled: scale <= 0.25,
8815
+ title: "Zoom Out",
8816
+ "aria-label": "Zoom Out",
8817
+ children: /* @__PURE__ */ jsx25("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx25("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20 12H4" }) })
8818
+ }
8819
+ ),
8820
+ showZoomLevel && /* @__PURE__ */ jsxs21("span", { className: "min-w-[48px] text-center text-sm font-medium text-gray-700 dark:text-gray-300", children: [
8821
+ zoomPercentage,
8822
+ "%"
8823
+ ] }),
8824
+ /* @__PURE__ */ jsx25(
8825
+ "button",
8826
+ {
8827
+ onClick: handleZoomIn,
8828
+ className: cn(
8829
+ "w-8 h-8 flex items-center justify-center rounded",
8830
+ "text-gray-700 dark:text-gray-300",
8831
+ "hover:bg-gray-100 dark:hover:bg-gray-700",
8832
+ "transition-colors",
8833
+ "disabled:opacity-50 disabled:cursor-not-allowed"
8834
+ ),
8835
+ disabled: scale >= 4,
8836
+ title: "Zoom In",
8837
+ "aria-label": "Zoom In",
8838
+ children: /* @__PURE__ */ jsx25("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx25("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) })
8839
+ }
8840
+ ),
8841
+ (showFitToWidth || showFitToPage) && /* @__PURE__ */ jsx25("div", { className: "w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1" }),
8842
+ showFitToWidth && /* @__PURE__ */ jsx25(
8843
+ "button",
8844
+ {
8845
+ onClick: handleFitToWidth,
8846
+ className: cn(
8847
+ "w-8 h-8 flex items-center justify-center rounded",
8848
+ "text-gray-700 dark:text-gray-300",
8849
+ "hover:bg-gray-100 dark:hover:bg-gray-700",
8850
+ "transition-colors"
8851
+ ),
8852
+ title: "Fit to Width",
8853
+ "aria-label": "Fit to Width",
8854
+ children: /* @__PURE__ */ jsx25("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx25("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) })
8855
+ }
8856
+ ),
8857
+ showFitToPage && /* @__PURE__ */ jsx25(
8858
+ "button",
8859
+ {
8860
+ onClick: handleFitToPage,
8861
+ className: cn(
8862
+ "w-8 h-8 flex items-center justify-center rounded",
8863
+ "text-gray-700 dark:text-gray-300",
8864
+ "hover:bg-gray-100 dark:hover:bg-gray-700",
8865
+ "transition-colors"
8866
+ ),
8867
+ title: "Fit to Page",
8868
+ "aria-label": "Fit to Page",
8869
+ children: /* @__PURE__ */ jsx25("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx25("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) })
8870
+ }
8871
+ )
8872
+ ]
8873
+ }
8874
+ );
8875
+ });
8876
+ }
8877
+ });
8878
+
8879
+ // src/components/FloatingZoomControls/index.ts
8880
+ var init_FloatingZoomControls2 = __esm({
8881
+ "src/components/FloatingZoomControls/index.ts"() {
8882
+ "use strict";
8883
+ init_FloatingZoomControls();
8884
+ }
8885
+ });
8886
+
8738
8887
  // src/components/PDFViewer/PDFViewerClient.tsx
8739
8888
  var PDFViewerClient_exports = {};
8740
8889
  __export(PDFViewerClient_exports, {
8741
8890
  PDFViewerClient: () => PDFViewerClient
8742
8891
  });
8743
- import { useEffect as useEffect22, useCallback as useCallback32, memo as memo24, useRef as useRef19, useState as useState21 } from "react";
8744
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
8745
- var PDFViewerInner, PDFViewerClient;
8892
+ import {
8893
+ useEffect as useEffect22,
8894
+ useCallback as useCallback33,
8895
+ memo as memo25,
8896
+ useRef as useRef19,
8897
+ useState as useState21,
8898
+ forwardRef
8899
+ } from "react";
8900
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
8901
+ function getSrcIdentifier(src) {
8902
+ if (typeof src === "string") {
8903
+ return src;
8904
+ }
8905
+ const data = src instanceof ArrayBuffer ? new Uint8Array(src) : src;
8906
+ const len = data.byteLength;
8907
+ if (len === 0) return "empty";
8908
+ const first = Array.from(data.slice(0, 4)).map((b) => b.toString(16).padStart(2, "0")).join("");
8909
+ const last = Array.from(data.slice(-4)).map((b) => b.toString(16).padStart(2, "0")).join("");
8910
+ return `binary:${len}:${first}:${last}`;
8911
+ }
8912
+ function mergeRects2(rects) {
8913
+ if (rects.length === 0) return [];
8914
+ const sorted = [...rects].sort((a, b) => a.y - b.y || a.x - b.x);
8915
+ const merged = [];
8916
+ let current = { ...sorted[0] };
8917
+ for (let i = 1; i < sorted.length; i++) {
8918
+ const rect = sorted[i];
8919
+ if (Math.abs(rect.y - current.y) < 2 && rect.x <= current.x + current.width + 2) {
8920
+ const newRight = Math.max(current.x + current.width, rect.x + rect.width);
8921
+ current.width = newRight - current.x;
8922
+ current.height = Math.max(current.height, rect.height);
8923
+ } else {
8924
+ merged.push(current);
8925
+ current = { ...rect };
8926
+ }
8927
+ }
8928
+ merged.push(current);
8929
+ return merged;
8930
+ }
8931
+ var PDFViewerInner, PDFViewerInnerWithRef, PDFViewerClient;
8746
8932
  var init_PDFViewerClient = __esm({
8747
8933
  "src/components/PDFViewer/PDFViewerClient.tsx"() {
8748
8934
  "use strict";
@@ -8754,99 +8940,313 @@ var init_PDFViewerClient = __esm({
8754
8940
  init_DocumentContainer();
8755
8941
  init_ContinuousScrollContainer();
8756
8942
  init_DualPageContainer();
8943
+ init_FloatingZoomControls2();
8757
8944
  init_utils();
8758
- PDFViewerInner = memo24(function PDFViewerInner2({
8945
+ PDFViewerInner = memo25(function PDFViewerInner2({
8759
8946
  src,
8760
8947
  initialPage = 1,
8761
- initialScale = 1,
8948
+ initialScale = "auto",
8762
8949
  showToolbar = true,
8763
8950
  showSidebar = true,
8764
8951
  showAnnotationToolbar = false,
8952
+ showFloatingZoom = true,
8765
8953
  viewMode = "single",
8766
8954
  onDocumentLoad,
8767
8955
  onPageChange,
8768
8956
  onScaleChange,
8769
8957
  onError,
8770
8958
  workerSrc,
8771
- className
8959
+ className,
8960
+ onReady
8772
8961
  }) {
8773
- const { viewerStore } = usePDFViewerStores();
8774
- const loadingRef = useRef19(false);
8775
- const srcRef = useRef19(src);
8962
+ const { viewerStore, annotationStore, searchStore } = usePDFViewerStores();
8963
+ const mountedRef = useRef19(true);
8964
+ const [, setLoadState] = useState21("idle");
8776
8965
  const onDocumentLoadRef = useRef19(onDocumentLoad);
8777
8966
  const onErrorRef = useRef19(onError);
8778
8967
  const onPageChangeRef = useRef19(onPageChange);
8779
8968
  const onScaleChangeRef = useRef19(onScaleChange);
8969
+ const onReadyRef = useRef19(onReady);
8780
8970
  onDocumentLoadRef.current = onDocumentLoad;
8781
8971
  onErrorRef.current = onError;
8782
8972
  onPageChangeRef.current = onPageChange;
8783
8973
  onScaleChangeRef.current = onScaleChange;
8974
+ onReadyRef.current = onReady;
8975
+ const srcIdRef = useRef19(null);
8784
8976
  const currentPage = useViewerStore((s) => s.currentPage);
8785
8977
  const scale = useViewerStore((s) => s.scale);
8786
8978
  const theme = useViewerStore((s) => s.theme);
8787
8979
  const isLoading = useViewerStore((s) => s.isLoading);
8788
8980
  const error = useViewerStore((s) => s.error);
8789
8981
  const sidebarOpen = useViewerStore((s) => s.sidebarOpen);
8790
- const [retryTrigger, setRetryTrigger] = useState21(0);
8791
- const handleRetry = useCallback32(() => {
8792
- loadingRef.current = false;
8793
- srcRef.current = null;
8982
+ const srcId = getSrcIdentifier(src);
8983
+ const handleRef = useRef19(null);
8984
+ useEffect22(() => {
8985
+ const handle = {
8986
+ // ==================== Text Highlighting ====================
8987
+ highlightText: async (text, options) => {
8988
+ const doc = viewerStore.getState().document;
8989
+ if (!doc) return [];
8990
+ const color = options?.color ?? "yellow";
8991
+ const targetPage = options?.page;
8992
+ const caseSensitive = options?.caseSensitive ?? false;
8993
+ const scrollTo = options?.scrollTo ?? true;
8994
+ const highlightIds = [];
8995
+ const searchText = caseSensitive ? text : text.toLowerCase();
8996
+ const pagesToSearch = targetPage ? [targetPage] : Array.from({ length: doc.numPages }, (_, i) => i + 1);
8997
+ for (const pageNum of pagesToSearch) {
8998
+ try {
8999
+ const page = await doc.getPage(pageNum);
9000
+ const textContent = await page.getTextContent();
9001
+ const viewport = page.getViewport({ scale: 1 });
9002
+ let fullText = "";
9003
+ const charPositions = [];
9004
+ for (const item of textContent.items) {
9005
+ if ("str" in item && item.str) {
9006
+ const tx = item.transform;
9007
+ const x = tx[4];
9008
+ const y = viewport.height - tx[5];
9009
+ const width = item.width ?? 0;
9010
+ const height = item.height ?? 12;
9011
+ const charWidth = item.str.length > 0 ? width / item.str.length : width;
9012
+ for (let i = 0; i < item.str.length; i++) {
9013
+ charPositions.push({
9014
+ char: item.str[i],
9015
+ rect: {
9016
+ x: x + i * charWidth,
9017
+ y: y - height,
9018
+ width: charWidth,
9019
+ height
9020
+ }
9021
+ });
9022
+ }
9023
+ fullText += item.str;
9024
+ }
9025
+ }
9026
+ const textToSearch = caseSensitive ? fullText : fullText.toLowerCase();
9027
+ let startIndex = 0;
9028
+ while (true) {
9029
+ const matchIndex = textToSearch.indexOf(searchText, startIndex);
9030
+ if (matchIndex === -1) break;
9031
+ const matchRects = [];
9032
+ for (let i = matchIndex; i < matchIndex + text.length && i < charPositions.length; i++) {
9033
+ matchRects.push(charPositions[i].rect);
9034
+ }
9035
+ const mergedRects = mergeRects2(matchRects);
9036
+ const highlight = annotationStore.getState().addHighlight({
9037
+ pageNumber: pageNum,
9038
+ rects: mergedRects,
9039
+ color,
9040
+ text: fullText.substring(matchIndex, matchIndex + text.length)
9041
+ });
9042
+ highlightIds.push(highlight.id);
9043
+ startIndex = matchIndex + 1;
9044
+ }
9045
+ } catch {
9046
+ }
9047
+ }
9048
+ if (scrollTo && highlightIds.length > 0) {
9049
+ const firstHighlight = annotationStore.getState().highlights.find((h) => h.id === highlightIds[0]);
9050
+ if (firstHighlight) {
9051
+ viewerStore.getState().goToPage(firstHighlight.pageNumber);
9052
+ }
9053
+ }
9054
+ return highlightIds;
9055
+ },
9056
+ removeHighlight: (id) => {
9057
+ annotationStore.getState().removeHighlight(id);
9058
+ },
9059
+ clearHighlights: () => {
9060
+ const highlights = annotationStore.getState().highlights;
9061
+ for (const h of highlights) {
9062
+ annotationStore.getState().removeHighlight(h.id);
9063
+ }
9064
+ },
9065
+ // ==================== Annotations ====================
9066
+ drawRect: (options) => {
9067
+ const annotation = annotationStore.getState().addAnnotation({
9068
+ type: "shape",
9069
+ shapeType: "rect",
9070
+ pageNumber: options.page,
9071
+ x: options.x,
9072
+ y: options.y,
9073
+ width: options.width,
9074
+ height: options.height,
9075
+ color: options.color ?? "blue",
9076
+ strokeWidth: options.strokeWidth ?? 2
9077
+ });
9078
+ return annotation.id;
9079
+ },
9080
+ drawCircle: (options) => {
9081
+ const annotation = annotationStore.getState().addAnnotation({
9082
+ type: "shape",
9083
+ shapeType: "circle",
9084
+ pageNumber: options.page,
9085
+ x: options.x,
9086
+ y: options.y,
9087
+ width: options.radius * 2,
9088
+ height: options.radius * 2,
9089
+ color: options.color ?? "blue",
9090
+ strokeWidth: options.strokeWidth ?? 2
9091
+ });
9092
+ return annotation.id;
9093
+ },
9094
+ addNote: (options) => {
9095
+ const annotation = annotationStore.getState().addAnnotation({
9096
+ type: "note",
9097
+ pageNumber: options.page,
9098
+ x: options.x,
9099
+ y: options.y,
9100
+ content: options.content,
9101
+ color: options.color ?? "yellow"
9102
+ });
9103
+ return annotation.id;
9104
+ },
9105
+ removeAnnotation: (id) => {
9106
+ annotationStore.getState().removeAnnotation(id);
9107
+ },
9108
+ clearAnnotations: () => {
9109
+ const annotations = annotationStore.getState().annotations;
9110
+ for (const a of annotations) {
9111
+ annotationStore.getState().removeAnnotation(a.id);
9112
+ }
9113
+ },
9114
+ // ==================== Navigation ====================
9115
+ goToPage: (page) => {
9116
+ viewerStore.getState().goToPage(page);
9117
+ },
9118
+ nextPage: () => {
9119
+ viewerStore.getState().nextPage();
9120
+ },
9121
+ previousPage: () => {
9122
+ viewerStore.getState().previousPage();
9123
+ },
9124
+ getCurrentPage: () => {
9125
+ return viewerStore.getState().currentPage;
9126
+ },
9127
+ getNumPages: () => {
9128
+ return viewerStore.getState().numPages;
9129
+ },
9130
+ // ==================== Zoom ====================
9131
+ setZoom: (scale2) => {
9132
+ viewerStore.getState().setScale(scale2);
9133
+ },
9134
+ getZoom: () => {
9135
+ return viewerStore.getState().scale;
9136
+ },
9137
+ zoomIn: () => {
9138
+ viewerStore.getState().zoomIn();
9139
+ },
9140
+ zoomOut: () => {
9141
+ viewerStore.getState().zoomOut();
9142
+ },
9143
+ // ==================== Search ====================
9144
+ search: async (query, options) => {
9145
+ const doc = viewerStore.getState().document;
9146
+ if (!doc) return [];
9147
+ searchStore.getState().setQuery(query);
9148
+ if (options?.caseSensitive !== void 0) {
9149
+ searchStore.getState().setCaseSensitive(options.caseSensitive);
9150
+ }
9151
+ if (options?.wholeWord !== void 0) {
9152
+ searchStore.getState().setWholeWord(options.wholeWord);
9153
+ }
9154
+ await searchStore.getState().search(doc);
9155
+ return searchStore.getState().results;
9156
+ },
9157
+ nextSearchResult: () => {
9158
+ searchStore.getState().nextResult();
9159
+ const results = searchStore.getState().results;
9160
+ const index = searchStore.getState().currentResultIndex;
9161
+ if (results[index]) {
9162
+ viewerStore.getState().goToPage(results[index].pageNumber);
9163
+ }
9164
+ },
9165
+ previousSearchResult: () => {
9166
+ searchStore.getState().previousResult();
9167
+ const results = searchStore.getState().results;
9168
+ const index = searchStore.getState().currentResultIndex;
9169
+ if (results[index]) {
9170
+ viewerStore.getState().goToPage(results[index].pageNumber);
9171
+ }
9172
+ },
9173
+ clearSearch: () => {
9174
+ searchStore.getState().clearSearch();
9175
+ },
9176
+ // ==================== Document ====================
9177
+ getDocument: () => {
9178
+ return viewerStore.getState().document;
9179
+ },
9180
+ isLoaded: () => {
9181
+ return viewerStore.getState().document !== null;
9182
+ }
9183
+ };
9184
+ handleRef.current = handle;
9185
+ onReadyRef.current?.(handle);
9186
+ }, [viewerStore, annotationStore, searchStore]);
9187
+ const handleRetry = useCallback33(() => {
9188
+ srcIdRef.current = null;
8794
9189
  viewerStore.getState().setError(null);
8795
- setRetryTrigger((c) => c + 1);
8796
- }, [viewerStore, src]);
9190
+ setLoadState("idle");
9191
+ }, [viewerStore]);
8797
9192
  useEffect22(() => {
8798
- if (loadingRef.current) {
8799
- return;
8800
- }
8801
- if (srcRef.current === src && viewerStore.getState().document) {
9193
+ mountedRef.current = true;
9194
+ return () => {
9195
+ mountedRef.current = false;
9196
+ };
9197
+ }, []);
9198
+ useEffect22(() => {
9199
+ if (srcIdRef.current === srcId && viewerStore.getState().document) {
8802
9200
  return;
8803
9201
  }
8804
- srcRef.current = src;
8805
- loadingRef.current = true;
9202
+ const loadId = srcId;
9203
+ srcIdRef.current = srcId;
8806
9204
  const currentDoc = viewerStore.getState().document;
8807
9205
  if (currentDoc) {
8808
- viewerStore.getState().reset();
9206
+ currentDoc.destroy();
9207
+ viewerStore.getState().setDocument(null);
8809
9208
  }
8810
9209
  const loadDoc = async () => {
9210
+ if (!mountedRef.current) return;
8811
9211
  try {
8812
9212
  viewerStore.getState().setLoading(true);
8813
9213
  viewerStore.getState().setError(null);
9214
+ setLoadState("loading");
8814
9215
  const { document: document2, numPages } = await loadDocument({
8815
9216
  src,
8816
9217
  workerSrc
8817
9218
  });
8818
- if (srcRef.current === src) {
9219
+ if (mountedRef.current && srcIdRef.current === loadId) {
8819
9220
  viewerStore.getState().setDocument(document2);
9221
+ setLoadState("loaded");
8820
9222
  if (initialPage !== 1) {
8821
9223
  viewerStore.getState().goToPage(initialPage);
8822
9224
  }
8823
- if (typeof initialScale === "number" && initialScale !== 1) {
9225
+ if (typeof initialScale === "number") {
8824
9226
  viewerStore.getState().setScale(initialScale);
9227
+ } else if (initialScale === "auto" || initialScale === "page-width") {
9228
+ viewerStore.getState().setScale(1);
9229
+ } else if (initialScale === "page-fit") {
9230
+ viewerStore.getState().setScale(0.75);
8825
9231
  }
8826
9232
  onDocumentLoadRef.current?.({ document: document2, numPages });
8827
9233
  } else {
8828
9234
  document2.destroy();
8829
9235
  }
8830
9236
  } catch (err) {
8831
- if (srcRef.current === src) {
9237
+ if (mountedRef.current && srcIdRef.current === loadId) {
8832
9238
  const error2 = err instanceof Error ? err : new Error("Failed to load document");
8833
9239
  viewerStore.getState().setError(error2);
9240
+ viewerStore.getState().setLoading(false);
9241
+ setLoadState("error");
8834
9242
  onErrorRef.current?.(error2);
8835
9243
  }
8836
- } finally {
8837
- loadingRef.current = false;
8838
9244
  }
8839
9245
  };
8840
9246
  loadDoc();
8841
9247
  return () => {
8842
- srcRef.current = null;
8843
- };
8844
- }, [src, workerSrc, initialPage, initialScale, viewerStore, retryTrigger]);
8845
- useEffect22(() => {
8846
- return () => {
8847
- viewerStore.getState().reset();
8848
9248
  };
8849
- }, [viewerStore]);
9249
+ }, [srcId, src, workerSrc, initialPage, initialScale, viewerStore]);
8850
9250
  const prevPageRef = useRef19(currentPage);
8851
9251
  useEffect22(() => {
8852
9252
  if (prevPageRef.current !== currentPage) {
@@ -8863,7 +9263,7 @@ var init_PDFViewerClient = __esm({
8863
9263
  }, [scale]);
8864
9264
  const themeClass = theme === "dark" ? "dark" : "";
8865
9265
  if (error) {
8866
- return /* @__PURE__ */ jsx25(
9266
+ return /* @__PURE__ */ jsx26(
8867
9267
  "div",
8868
9268
  {
8869
9269
  className: cn(
@@ -8873,10 +9273,10 @@ var init_PDFViewerClient = __esm({
8873
9273
  themeClass,
8874
9274
  className
8875
9275
  ),
8876
- children: /* @__PURE__ */ jsx25("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs21("div", { className: "text-center p-8", children: [
8877
- /* @__PURE__ */ jsx25("div", { className: "text-red-500 text-lg font-semibold mb-2", children: "Failed to load PDF" }),
8878
- /* @__PURE__ */ jsx25("div", { className: "text-gray-500 text-sm", children: error.message }),
8879
- /* @__PURE__ */ jsx25(
9276
+ children: /* @__PURE__ */ jsx26("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs22("div", { className: "text-center p-8", children: [
9277
+ /* @__PURE__ */ jsx26("div", { className: "text-red-500 text-lg font-semibold mb-2", children: "Failed to load PDF" }),
9278
+ /* @__PURE__ */ jsx26("div", { className: "text-gray-500 text-sm", children: error.message }),
9279
+ /* @__PURE__ */ jsx26(
8880
9280
  "button",
8881
9281
  {
8882
9282
  onClick: handleRetry,
@@ -8891,56 +9291,73 @@ var init_PDFViewerClient = __esm({
8891
9291
  const renderContainer = () => {
8892
9292
  switch (viewMode) {
8893
9293
  case "continuous":
8894
- return /* @__PURE__ */ jsx25(ContinuousScrollContainer, {});
9294
+ return /* @__PURE__ */ jsx26(ContinuousScrollContainer, {});
8895
9295
  case "dual":
8896
- return /* @__PURE__ */ jsx25(DualPageContainer, {});
9296
+ return /* @__PURE__ */ jsx26(DualPageContainer, {});
8897
9297
  case "single":
8898
9298
  default:
8899
- return /* @__PURE__ */ jsx25(DocumentContainer, {});
9299
+ return /* @__PURE__ */ jsx26(DocumentContainer, {});
8900
9300
  }
8901
9301
  };
8902
- return /* @__PURE__ */ jsxs21(
9302
+ return /* @__PURE__ */ jsxs22(
8903
9303
  "div",
8904
9304
  {
8905
9305
  className: cn(
8906
9306
  "pdf-viewer",
8907
- "flex flex-col h-full",
9307
+ "flex flex-col h-full relative",
8908
9308
  "bg-white dark:bg-gray-900",
8909
9309
  "text-gray-900 dark:text-gray-100",
8910
9310
  themeClass,
8911
9311
  className
8912
9312
  ),
8913
9313
  children: [
8914
- showToolbar && /* @__PURE__ */ jsx25(Toolbar, {}),
8915
- showAnnotationToolbar && /* @__PURE__ */ jsx25(AnnotationToolbar, {}),
8916
- /* @__PURE__ */ jsxs21("div", { className: "flex flex-1 overflow-hidden", children: [
8917
- showSidebar && sidebarOpen && /* @__PURE__ */ jsx25(Sidebar, {}),
9314
+ showToolbar && /* @__PURE__ */ jsx26(Toolbar, {}),
9315
+ showAnnotationToolbar && /* @__PURE__ */ jsx26(AnnotationToolbar, {}),
9316
+ /* @__PURE__ */ jsxs22("div", { className: "flex flex-1 overflow-hidden", children: [
9317
+ showSidebar && sidebarOpen && /* @__PURE__ */ jsx26(Sidebar, {}),
8918
9318
  renderContainer()
8919
9319
  ] }),
8920
- isLoading && /* @__PURE__ */ jsx25("div", { className: "absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-900/80", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center", children: [
8921
- /* @__PURE__ */ jsx25("div", { className: "w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" }),
8922
- /* @__PURE__ */ jsx25("div", { className: "mt-2 text-sm text-gray-500", children: "Loading PDF..." })
9320
+ showFloatingZoom && /* @__PURE__ */ jsx26(FloatingZoomControls, { position: "bottom-right" }),
9321
+ isLoading && /* @__PURE__ */ jsx26("div", { className: "absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-900/80", children: /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-center", children: [
9322
+ /* @__PURE__ */ jsx26("div", { className: "w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" }),
9323
+ /* @__PURE__ */ jsx26("div", { className: "mt-2 text-sm text-gray-500", children: "Loading PDF..." })
8923
9324
  ] }) })
8924
9325
  ]
8925
9326
  }
8926
9327
  );
8927
9328
  });
8928
- PDFViewerClient = memo24(function PDFViewerClient2(props) {
8929
- return /* @__PURE__ */ jsx25(
8930
- PDFViewerProvider,
8931
- {
8932
- theme: props.theme,
8933
- defaultSidebarPanel: props.defaultSidebarPanel,
8934
- children: /* @__PURE__ */ jsx25(PDFViewerInner, { ...props })
8935
- }
8936
- );
8937
- });
9329
+ PDFViewerInnerWithRef = forwardRef(
9330
+ function PDFViewerInnerWithRef2(props, ref) {
9331
+ const handleRef = useRef19(null);
9332
+ const handleReady = useCallback33((handle) => {
9333
+ handleRef.current = handle;
9334
+ if (typeof ref === "function") {
9335
+ ref(handle);
9336
+ } else if (ref) {
9337
+ ref.current = handle;
9338
+ }
9339
+ }, [ref]);
9340
+ return /* @__PURE__ */ jsx26(PDFViewerInner, { ...props, onReady: handleReady });
9341
+ }
9342
+ );
9343
+ PDFViewerClient = memo25(
9344
+ forwardRef(function PDFViewerClient2(props, ref) {
9345
+ return /* @__PURE__ */ jsx26(
9346
+ PDFViewerProvider,
9347
+ {
9348
+ theme: props.theme,
9349
+ defaultSidebarPanel: props.defaultSidebarPanel,
9350
+ children: /* @__PURE__ */ jsx26(PDFViewerInnerWithRef, { ref, ...props })
9351
+ }
9352
+ );
9353
+ })
9354
+ );
8938
9355
  }
8939
9356
  });
8940
9357
 
8941
9358
  // src/components/PDFViewer/PDFViewer.tsx
8942
- import { lazy, Suspense, memo as memo25 } from "react";
8943
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
9359
+ import { lazy, Suspense, memo as memo26 } from "react";
9360
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
8944
9361
  var PDFViewerClient3, PDFViewerLoading, PDFViewer;
8945
9362
  var init_PDFViewer = __esm({
8946
9363
  "src/components/PDFViewer/PDFViewer.tsx"() {
@@ -8949,10 +9366,10 @@ var init_PDFViewer = __esm({
8949
9366
  PDFViewerClient3 = lazy(
8950
9367
  () => Promise.resolve().then(() => (init_PDFViewerClient(), PDFViewerClient_exports)).then((mod) => ({ default: mod.PDFViewerClient }))
8951
9368
  );
8952
- PDFViewerLoading = memo25(function PDFViewerLoading2({
9369
+ PDFViewerLoading = memo26(function PDFViewerLoading2({
8953
9370
  className
8954
9371
  }) {
8955
- return /* @__PURE__ */ jsx26(
9372
+ return /* @__PURE__ */ jsx27(
8956
9373
  "div",
8957
9374
  {
8958
9375
  className: cn(
@@ -8961,18 +9378,18 @@ var init_PDFViewer = __esm({
8961
9378
  "bg-white dark:bg-gray-900",
8962
9379
  className
8963
9380
  ),
8964
- children: /* @__PURE__ */ jsx26("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-center", children: [
8965
- /* @__PURE__ */ jsx26("div", { className: "w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" }),
8966
- /* @__PURE__ */ jsx26("div", { className: "mt-2 text-sm text-gray-500", children: "Loading PDF viewer..." })
9381
+ children: /* @__PURE__ */ jsx27("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center", children: [
9382
+ /* @__PURE__ */ jsx27("div", { className: "w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" }),
9383
+ /* @__PURE__ */ jsx27("div", { className: "mt-2 text-sm text-gray-500", children: "Loading PDF viewer..." })
8967
9384
  ] }) })
8968
9385
  }
8969
9386
  );
8970
9387
  });
8971
- PDFViewer = memo25(function PDFViewer2(props) {
9388
+ PDFViewer = memo26(function PDFViewer2(props) {
8972
9389
  if (typeof window === "undefined") {
8973
- return /* @__PURE__ */ jsx26(PDFViewerLoading, { className: props.className });
9390
+ return /* @__PURE__ */ jsx27(PDFViewerLoading, { className: props.className });
8974
9391
  }
8975
- return /* @__PURE__ */ jsx26(Suspense, { fallback: /* @__PURE__ */ jsx26(PDFViewerLoading, { className: props.className }), children: /* @__PURE__ */ jsx26(PDFViewerClient3, { ...props }) });
9392
+ return /* @__PURE__ */ jsx27(Suspense, { fallback: /* @__PURE__ */ jsx27(PDFViewerLoading, { className: props.className }), children: /* @__PURE__ */ jsx27(PDFViewerClient3, { ...props }) });
8976
9393
  });
8977
9394
  }
8978
9395
  });
@@ -9001,8 +9418,8 @@ init_AnnotationToolbar2();
9001
9418
 
9002
9419
  // src/components/Annotations/StickyNote.tsx
9003
9420
  init_utils();
9004
- import { memo as memo26, useState as useState22, useRef as useRef20, useEffect as useEffect23, useCallback as useCallback33 } from "react";
9005
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
9421
+ import { memo as memo27, useState as useState22, useRef as useRef20, useEffect as useEffect23, useCallback as useCallback34 } from "react";
9422
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
9006
9423
  var NOTE_COLORS = [
9007
9424
  "#fef08a",
9008
9425
  // yellow
@@ -9015,7 +9432,7 @@ var NOTE_COLORS = [
9015
9432
  "#fed7aa"
9016
9433
  // orange
9017
9434
  ];
9018
- var StickyNote = memo26(function StickyNote2({
9435
+ var StickyNote = memo27(function StickyNote2({
9019
9436
  note,
9020
9437
  scale,
9021
9438
  isSelected,
@@ -9041,24 +9458,24 @@ var StickyNote = memo26(function StickyNote2({
9041
9458
  textareaRef.current.select();
9042
9459
  }
9043
9460
  }, [isEditing]);
9044
- const handleClick = useCallback33((e) => {
9461
+ const handleClick = useCallback34((e) => {
9045
9462
  e.stopPropagation();
9046
9463
  onSelect?.();
9047
9464
  if (!isExpanded) {
9048
9465
  setIsExpanded(true);
9049
9466
  }
9050
9467
  }, [isExpanded, onSelect]);
9051
- const handleDoubleClick = useCallback33((e) => {
9468
+ const handleDoubleClick = useCallback34((e) => {
9052
9469
  e.stopPropagation();
9053
9470
  onStartEdit?.();
9054
9471
  }, [onStartEdit]);
9055
- const handleBlur = useCallback33(() => {
9472
+ const handleBlur = useCallback34(() => {
9056
9473
  if (isEditing && localContent !== note.content) {
9057
9474
  onUpdate?.({ content: localContent });
9058
9475
  }
9059
9476
  onEndEdit?.();
9060
9477
  }, [isEditing, localContent, note.content, onUpdate, onEndEdit]);
9061
- const handleKeyDown = useCallback33((e) => {
9478
+ const handleKeyDown = useCallback34((e) => {
9062
9479
  if (e.key === "Escape") {
9063
9480
  setLocalContent(note.content);
9064
9481
  onEndEdit?.();
@@ -9066,16 +9483,16 @@ var StickyNote = memo26(function StickyNote2({
9066
9483
  handleBlur();
9067
9484
  }
9068
9485
  }, [note.content, onEndEdit, handleBlur]);
9069
- const handleColorChange = useCallback33((color) => {
9486
+ const handleColorChange = useCallback34((color) => {
9070
9487
  onUpdate?.({ color });
9071
9488
  }, [onUpdate]);
9072
- const handleCollapse = useCallback33((e) => {
9489
+ const handleCollapse = useCallback34((e) => {
9073
9490
  e.stopPropagation();
9074
9491
  setIsExpanded(false);
9075
9492
  onEndEdit?.();
9076
9493
  }, [onEndEdit]);
9077
9494
  if (!isExpanded) {
9078
- return /* @__PURE__ */ jsx27(
9495
+ return /* @__PURE__ */ jsx28(
9079
9496
  "div",
9080
9497
  {
9081
9498
  ref: noteRef,
@@ -9096,14 +9513,14 @@ var StickyNote = memo26(function StickyNote2({
9096
9513
  onMouseDown: onDragStart,
9097
9514
  onTouchStart: onDragStart,
9098
9515
  title: note.content || "Empty note",
9099
- children: /* @__PURE__ */ jsx27(
9516
+ children: /* @__PURE__ */ jsx28(
9100
9517
  "svg",
9101
9518
  {
9102
9519
  className: "w-4 h-4 opacity-70",
9103
9520
  fill: "currentColor",
9104
9521
  viewBox: "0 0 20 20",
9105
9522
  style: { color: "#333" },
9106
- children: /* @__PURE__ */ jsx27(
9523
+ children: /* @__PURE__ */ jsx28(
9107
9524
  "path",
9108
9525
  {
9109
9526
  fillRule: "evenodd",
@@ -9116,7 +9533,7 @@ var StickyNote = memo26(function StickyNote2({
9116
9533
  }
9117
9534
  );
9118
9535
  }
9119
- return /* @__PURE__ */ jsxs23(
9536
+ return /* @__PURE__ */ jsxs24(
9120
9537
  "div",
9121
9538
  {
9122
9539
  ref: noteRef,
@@ -9134,14 +9551,14 @@ var StickyNote = memo26(function StickyNote2({
9134
9551
  },
9135
9552
  onClick: handleClick,
9136
9553
  children: [
9137
- /* @__PURE__ */ jsxs23(
9554
+ /* @__PURE__ */ jsxs24(
9138
9555
  "div",
9139
9556
  {
9140
9557
  className: "flex items-center justify-between px-2 py-1 border-b border-black/10 cursor-move",
9141
9558
  onMouseDown: onDragStart,
9142
9559
  onTouchStart: onDragStart,
9143
9560
  children: [
9144
- /* @__PURE__ */ jsx27("div", { className: "flex gap-1", children: NOTE_COLORS.map((color) => /* @__PURE__ */ jsx27(
9561
+ /* @__PURE__ */ jsx28("div", { className: "flex gap-1", children: NOTE_COLORS.map((color) => /* @__PURE__ */ jsx28(
9145
9562
  "button",
9146
9563
  {
9147
9564
  className: cn(
@@ -9158,8 +9575,8 @@ var StickyNote = memo26(function StickyNote2({
9158
9575
  },
9159
9576
  color
9160
9577
  )) }),
9161
- /* @__PURE__ */ jsxs23("div", { className: "flex gap-1", children: [
9162
- /* @__PURE__ */ jsx27(
9578
+ /* @__PURE__ */ jsxs24("div", { className: "flex gap-1", children: [
9579
+ /* @__PURE__ */ jsx28(
9163
9580
  "button",
9164
9581
  {
9165
9582
  className: "p-0.5 hover:bg-black/10 rounded",
@@ -9168,23 +9585,23 @@ var StickyNote = memo26(function StickyNote2({
9168
9585
  onDelete?.();
9169
9586
  },
9170
9587
  title: "Delete note",
9171
- children: /* @__PURE__ */ jsx27("svg", { className: "w-3.5 h-3.5 text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx27("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
9588
+ children: /* @__PURE__ */ jsx28("svg", { className: "w-3.5 h-3.5 text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx28("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
9172
9589
  }
9173
9590
  ),
9174
- /* @__PURE__ */ jsx27(
9591
+ /* @__PURE__ */ jsx28(
9175
9592
  "button",
9176
9593
  {
9177
9594
  className: "p-0.5 hover:bg-black/10 rounded",
9178
9595
  onClick: handleCollapse,
9179
9596
  title: "Collapse note",
9180
- children: /* @__PURE__ */ jsx27("svg", { className: "w-3.5 h-3.5 text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx27("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
9597
+ children: /* @__PURE__ */ jsx28("svg", { className: "w-3.5 h-3.5 text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx28("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
9181
9598
  }
9182
9599
  )
9183
9600
  ] })
9184
9601
  ]
9185
9602
  }
9186
9603
  ),
9187
- /* @__PURE__ */ jsx27("div", { className: "p-2", children: isEditing ? /* @__PURE__ */ jsx27(
9604
+ /* @__PURE__ */ jsx28("div", { className: "p-2", children: isEditing ? /* @__PURE__ */ jsx28(
9188
9605
  "textarea",
9189
9606
  {
9190
9607
  ref: textareaRef,
@@ -9199,7 +9616,7 @@ var StickyNote = memo26(function StickyNote2({
9199
9616
  onKeyDown: handleKeyDown,
9200
9617
  placeholder: "Enter note..."
9201
9618
  }
9202
- ) : /* @__PURE__ */ jsx27(
9619
+ ) : /* @__PURE__ */ jsx28(
9203
9620
  "div",
9204
9621
  {
9205
9622
  className: cn(
@@ -9210,7 +9627,7 @@ var StickyNote = memo26(function StickyNote2({
9210
9627
  children: note.content || "Double-click to edit..."
9211
9628
  }
9212
9629
  ) }),
9213
- /* @__PURE__ */ jsx27("div", { className: "px-2 pb-1 text-[10px] text-gray-500", children: new Date(note.updatedAt).toLocaleDateString() })
9630
+ /* @__PURE__ */ jsx28("div", { className: "px-2 pb-1 text-[10px] text-gray-500", children: new Date(note.updatedAt).toLocaleDateString() })
9214
9631
  ]
9215
9632
  }
9216
9633
  );
@@ -9218,8 +9635,8 @@ var StickyNote = memo26(function StickyNote2({
9218
9635
 
9219
9636
  // src/components/Annotations/DrawingCanvas.tsx
9220
9637
  init_utils();
9221
- import { memo as memo27, useRef as useRef21, useCallback as useCallback34, useState as useState23 } from "react";
9222
- import { jsx as jsx28 } from "react/jsx-runtime";
9638
+ import { memo as memo28, useRef as useRef21, useCallback as useCallback35, useState as useState23 } from "react";
9639
+ import { jsx as jsx29 } from "react/jsx-runtime";
9223
9640
  function pointsToSvgPath(points) {
9224
9641
  if (points.length === 0) return "";
9225
9642
  if (points.length === 1) {
@@ -9257,7 +9674,7 @@ function simplifyPath(points, tolerance = 1) {
9257
9674
  result.push(points[points.length - 1]);
9258
9675
  return result;
9259
9676
  }
9260
- var DrawingCanvas = memo27(function DrawingCanvas2({
9677
+ var DrawingCanvas = memo28(function DrawingCanvas2({
9261
9678
  width,
9262
9679
  height,
9263
9680
  scale,
@@ -9270,7 +9687,7 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9270
9687
  const svgRef = useRef21(null);
9271
9688
  const [isDrawing, setIsDrawing] = useState23(false);
9272
9689
  const [currentPath, setCurrentPath] = useState23([]);
9273
- const getPoint = useCallback34((e) => {
9690
+ const getPoint = useCallback35((e) => {
9274
9691
  if (!svgRef.current) return null;
9275
9692
  const svg = svgRef.current;
9276
9693
  const rect = svg.getBoundingClientRect();
@@ -9290,7 +9707,7 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9290
9707
  y: (clientY - rect.top) / scale
9291
9708
  };
9292
9709
  }, [scale]);
9293
- const handleStart = useCallback34((e) => {
9710
+ const handleStart = useCallback35((e) => {
9294
9711
  if (!isActive) return;
9295
9712
  const point = getPoint(e);
9296
9713
  if (point) {
@@ -9298,14 +9715,14 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9298
9715
  setCurrentPath([point]);
9299
9716
  }
9300
9717
  }, [isActive, getPoint]);
9301
- const handleMove = useCallback34((e) => {
9718
+ const handleMove = useCallback35((e) => {
9302
9719
  if (!isDrawing || !isActive) return;
9303
9720
  const point = getPoint(e);
9304
9721
  if (point) {
9305
9722
  setCurrentPath((prev) => [...prev, point]);
9306
9723
  }
9307
9724
  }, [isDrawing, isActive, getPoint]);
9308
- const handleEnd = useCallback34(() => {
9725
+ const handleEnd = useCallback35(() => {
9309
9726
  if (!isDrawing) return;
9310
9727
  setIsDrawing(false);
9311
9728
  if (currentPath.length >= 2) {
@@ -9314,7 +9731,7 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9314
9731
  }
9315
9732
  setCurrentPath([]);
9316
9733
  }, [isDrawing, currentPath, onDrawingComplete]);
9317
- return /* @__PURE__ */ jsx28(
9734
+ return /* @__PURE__ */ jsx29(
9318
9735
  "svg",
9319
9736
  {
9320
9737
  ref: svgRef,
@@ -9334,7 +9751,7 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9334
9751
  onTouchStart: handleStart,
9335
9752
  onTouchMove: handleMove,
9336
9753
  onTouchEnd: handleEnd,
9337
- children: isDrawing && currentPath.length > 0 && /* @__PURE__ */ jsx28(
9754
+ children: isDrawing && currentPath.length > 0 && /* @__PURE__ */ jsx29(
9338
9755
  "path",
9339
9756
  {
9340
9757
  d: pointsToSvgPath(currentPath),
@@ -9352,9 +9769,9 @@ var DrawingCanvas = memo27(function DrawingCanvas2({
9352
9769
 
9353
9770
  // src/components/Annotations/ShapeRenderer.tsx
9354
9771
  init_utils();
9355
- import { memo as memo28, useCallback as useCallback35, useState as useState24, useRef as useRef22 } from "react";
9356
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
9357
- var ShapeRenderer = memo28(function ShapeRenderer2({
9772
+ import { memo as memo29, useCallback as useCallback36, useState as useState24, useRef as useRef22 } from "react";
9773
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
9774
+ var ShapeRenderer = memo29(function ShapeRenderer2({
9358
9775
  shape,
9359
9776
  scale,
9360
9777
  isSelected,
@@ -9375,7 +9792,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9375
9792
  const scaledWidth = width * scale;
9376
9793
  const scaledHeight = height * scale;
9377
9794
  const scaledStroke = strokeWidth * scale;
9378
- const getResizeHandles = useCallback35(() => {
9795
+ const getResizeHandles = useCallback36(() => {
9379
9796
  const handleSize = 8;
9380
9797
  const half = handleSize / 2;
9381
9798
  return [
@@ -9389,7 +9806,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9389
9806
  { position: "w", cursor: "ew-resize", x: scaledX - half, y: scaledY + scaledHeight / 2 - half }
9390
9807
  ];
9391
9808
  }, [scaledX, scaledY, scaledWidth, scaledHeight]);
9392
- const handleMouseDown = useCallback35((e, handle) => {
9809
+ const handleMouseDown = useCallback36((e, handle) => {
9393
9810
  e.stopPropagation();
9394
9811
  onSelect?.();
9395
9812
  if (!isEditing) return;
@@ -9465,7 +9882,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9465
9882
  document.addEventListener("mousemove", handleMouseMove);
9466
9883
  document.addEventListener("mouseup", handleMouseUp);
9467
9884
  }, [isEditing, x, y, width, height, scale, onSelect, onUpdate]);
9468
- const renderShape2 = useCallback35(() => {
9885
+ const renderShape2 = useCallback36(() => {
9469
9886
  const commonProps = {
9470
9887
  stroke: color,
9471
9888
  strokeWidth: scaledStroke,
@@ -9477,7 +9894,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9477
9894
  };
9478
9895
  switch (shapeType) {
9479
9896
  case "rect":
9480
- return /* @__PURE__ */ jsx29(
9897
+ return /* @__PURE__ */ jsx30(
9481
9898
  "rect",
9482
9899
  {
9483
9900
  x: scaledX,
@@ -9488,7 +9905,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9488
9905
  }
9489
9906
  );
9490
9907
  case "circle":
9491
- return /* @__PURE__ */ jsx29(
9908
+ return /* @__PURE__ */ jsx30(
9492
9909
  "ellipse",
9493
9910
  {
9494
9911
  cx: scaledX + scaledWidth / 2,
@@ -9499,7 +9916,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9499
9916
  }
9500
9917
  );
9501
9918
  case "line":
9502
- return /* @__PURE__ */ jsx29(
9919
+ return /* @__PURE__ */ jsx30(
9503
9920
  "line",
9504
9921
  {
9505
9922
  x1: scaledX,
@@ -9519,22 +9936,22 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9519
9936
  const arrow1Y = endY - arrowLength * Math.sin(angle - arrowAngle);
9520
9937
  const arrow2X = endX - arrowLength * Math.cos(angle + arrowAngle);
9521
9938
  const arrow2Y = endY - arrowLength * Math.sin(angle + arrowAngle);
9522
- return /* @__PURE__ */ jsxs24("g", { children: [
9523
- /* @__PURE__ */ jsx29("line", { x1: scaledX, y1: scaledY, x2: endX, y2: endY, ...commonProps }),
9524
- /* @__PURE__ */ jsx29("line", { x1: endX, y1: endY, x2: arrow1X, y2: arrow1Y, ...commonProps }),
9525
- /* @__PURE__ */ jsx29("line", { x1: endX, y1: endY, x2: arrow2X, y2: arrow2Y, ...commonProps })
9939
+ return /* @__PURE__ */ jsxs25("g", { children: [
9940
+ /* @__PURE__ */ jsx30("line", { x1: scaledX, y1: scaledY, x2: endX, y2: endY, ...commonProps }),
9941
+ /* @__PURE__ */ jsx30("line", { x1: endX, y1: endY, x2: arrow1X, y2: arrow1Y, ...commonProps }),
9942
+ /* @__PURE__ */ jsx30("line", { x1: endX, y1: endY, x2: arrow2X, y2: arrow2Y, ...commonProps })
9526
9943
  ] });
9527
9944
  default:
9528
9945
  return null;
9529
9946
  }
9530
9947
  }, [shapeType, scaledX, scaledY, scaledWidth, scaledHeight, color, scaledStroke, isSelected]);
9531
- return /* @__PURE__ */ jsxs24(
9948
+ return /* @__PURE__ */ jsxs25(
9532
9949
  "g",
9533
9950
  {
9534
9951
  className: cn("shape-renderer", className),
9535
9952
  onMouseDown: (e) => handleMouseDown(e),
9536
9953
  children: [
9537
- /* @__PURE__ */ jsx29(
9954
+ /* @__PURE__ */ jsx30(
9538
9955
  "rect",
9539
9956
  {
9540
9957
  x: scaledX - 5,
@@ -9547,7 +9964,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9547
9964
  }
9548
9965
  ),
9549
9966
  renderShape2(),
9550
- isSelected && /* @__PURE__ */ jsx29(
9967
+ isSelected && /* @__PURE__ */ jsx30(
9551
9968
  "rect",
9552
9969
  {
9553
9970
  x: scaledX - 2,
@@ -9560,7 +9977,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9560
9977
  strokeDasharray: "4 2"
9561
9978
  }
9562
9979
  ),
9563
- isSelected && isEditing && getResizeHandles().map((handle) => /* @__PURE__ */ jsx29(
9980
+ isSelected && isEditing && getResizeHandles().map((handle) => /* @__PURE__ */ jsx30(
9564
9981
  "rect",
9565
9982
  {
9566
9983
  x: handle.x,
@@ -9580,7 +9997,7 @@ var ShapeRenderer = memo28(function ShapeRenderer2({
9580
9997
  }
9581
9998
  );
9582
9999
  });
9583
- var ShapePreview = memo28(function ShapePreview2({
10000
+ var ShapePreview = memo29(function ShapePreview2({
9584
10001
  shapeType,
9585
10002
  startPoint,
9586
10003
  endPoint,
@@ -9601,9 +10018,9 @@ var ShapePreview = memo28(function ShapePreview2({
9601
10018
  };
9602
10019
  switch (shapeType) {
9603
10020
  case "rect":
9604
- return /* @__PURE__ */ jsx29("rect", { x, y, width, height, ...commonProps });
10021
+ return /* @__PURE__ */ jsx30("rect", { x, y, width, height, ...commonProps });
9605
10022
  case "circle":
9606
- return /* @__PURE__ */ jsx29(
10023
+ return /* @__PURE__ */ jsx30(
9607
10024
  "ellipse",
9608
10025
  {
9609
10026
  cx: x + width / 2,
@@ -9614,7 +10031,7 @@ var ShapePreview = memo28(function ShapePreview2({
9614
10031
  }
9615
10032
  );
9616
10033
  case "line":
9617
- return /* @__PURE__ */ jsx29(
10034
+ return /* @__PURE__ */ jsx30(
9618
10035
  "line",
9619
10036
  {
9620
10037
  x1: startPoint.x * scale,
@@ -9636,8 +10053,8 @@ var ShapePreview = memo28(function ShapePreview2({
9636
10053
  const arrow1Y = endY - arrowLength * Math.sin(angle - arrowAngle);
9637
10054
  const arrow2X = endX - arrowLength * Math.cos(angle + arrowAngle);
9638
10055
  const arrow2Y = endY - arrowLength * Math.sin(angle + arrowAngle);
9639
- return /* @__PURE__ */ jsxs24("g", { children: [
9640
- /* @__PURE__ */ jsx29(
10056
+ return /* @__PURE__ */ jsxs25("g", { children: [
10057
+ /* @__PURE__ */ jsx30(
9641
10058
  "line",
9642
10059
  {
9643
10060
  x1: startPoint.x * scale,
@@ -9647,8 +10064,8 @@ var ShapePreview = memo28(function ShapePreview2({
9647
10064
  ...commonProps
9648
10065
  }
9649
10066
  ),
9650
- /* @__PURE__ */ jsx29("line", { x1: endX, y1: endY, x2: arrow1X, y2: arrow1Y, ...commonProps }),
9651
- /* @__PURE__ */ jsx29("line", { x1: endX, y1: endY, x2: arrow2X, y2: arrow2Y, ...commonProps })
10067
+ /* @__PURE__ */ jsx30("line", { x1: endX, y1: endY, x2: arrow1X, y2: arrow1Y, ...commonProps }),
10068
+ /* @__PURE__ */ jsx30("line", { x1: endX, y1: endY, x2: arrow2X, y2: arrow2Y, ...commonProps })
9652
10069
  ] });
9653
10070
  default:
9654
10071
  return null;
@@ -9657,9 +10074,9 @@ var ShapePreview = memo28(function ShapePreview2({
9657
10074
 
9658
10075
  // src/components/Annotations/QuickNoteButton.tsx
9659
10076
  init_utils();
9660
- import { memo as memo29, useCallback as useCallback36, useState as useState25 } from "react";
9661
- import { jsx as jsx30 } from "react/jsx-runtime";
9662
- var QuickNoteButton = memo29(function QuickNoteButton2({
10077
+ import { memo as memo30, useCallback as useCallback37, useState as useState25 } from "react";
10078
+ import { jsx as jsx31 } from "react/jsx-runtime";
10079
+ var QuickNoteButton = memo30(function QuickNoteButton2({
9663
10080
  pageNumber,
9664
10081
  scale,
9665
10082
  position = "top-right",
@@ -9668,7 +10085,7 @@ var QuickNoteButton = memo29(function QuickNoteButton2({
9668
10085
  visible = true
9669
10086
  }) {
9670
10087
  const [isHovered, setIsHovered] = useState25(false);
9671
- const handleClick = useCallback36(
10088
+ const handleClick = useCallback37(
9672
10089
  (e) => {
9673
10090
  e.stopPropagation();
9674
10091
  const x = position === "top-right" ? 80 : 80;
@@ -9680,7 +10097,7 @@ var QuickNoteButton = memo29(function QuickNoteButton2({
9680
10097
  if (!visible) {
9681
10098
  return null;
9682
10099
  }
9683
- return /* @__PURE__ */ jsx30(
10100
+ return /* @__PURE__ */ jsx31(
9684
10101
  "button",
9685
10102
  {
9686
10103
  onClick: handleClick,
@@ -9702,7 +10119,7 @@ var QuickNoteButton = memo29(function QuickNoteButton2({
9702
10119
  ),
9703
10120
  title: "Add quick note",
9704
10121
  "aria-label": "Add quick note",
9705
- children: /* @__PURE__ */ jsx30(
10122
+ children: /* @__PURE__ */ jsx31(
9706
10123
  "svg",
9707
10124
  {
9708
10125
  className: "w-4 h-4 text-yellow-900",
@@ -9710,7 +10127,7 @@ var QuickNoteButton = memo29(function QuickNoteButton2({
9710
10127
  viewBox: "0 0 24 24",
9711
10128
  stroke: "currentColor",
9712
10129
  strokeWidth: 2,
9713
- children: /* @__PURE__ */ jsx30("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4v16m8-8H4" })
10130
+ children: /* @__PURE__ */ jsx31("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4v16m8-8H4" })
9714
10131
  }
9715
10132
  )
9716
10133
  }
@@ -9719,9 +10136,9 @@ var QuickNoteButton = memo29(function QuickNoteButton2({
9719
10136
 
9720
10137
  // src/components/Annotations/QuickNotePopover.tsx
9721
10138
  init_utils();
9722
- import { memo as memo30, useCallback as useCallback37, useState as useState26, useRef as useRef23, useEffect as useEffect24 } from "react";
9723
- import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
9724
- var QuickNotePopover = memo30(function QuickNotePopover2({
10139
+ import { memo as memo31, useCallback as useCallback38, useState as useState26, useRef as useRef23, useEffect as useEffect24 } from "react";
10140
+ import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
10141
+ var QuickNotePopover = memo31(function QuickNotePopover2({
9725
10142
  visible,
9726
10143
  position,
9727
10144
  initialContent = "",
@@ -9763,14 +10180,14 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9763
10180
  }
9764
10181
  setAdjustedPosition({ x, y });
9765
10182
  }, [position, visible]);
9766
- const handleSave = useCallback37(() => {
10183
+ const handleSave = useCallback38(() => {
9767
10184
  if (content.trim()) {
9768
10185
  onSave(content.trim());
9769
10186
  } else {
9770
10187
  onCancel();
9771
10188
  }
9772
10189
  }, [content, onSave, onCancel]);
9773
- const handleKeyDown = useCallback37(
10190
+ const handleKeyDown = useCallback38(
9774
10191
  (e) => {
9775
10192
  if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
9776
10193
  e.preventDefault();
@@ -9785,7 +10202,7 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9785
10202
  if (!visible) {
9786
10203
  return null;
9787
10204
  }
9788
- return /* @__PURE__ */ jsxs25(
10205
+ return /* @__PURE__ */ jsxs26(
9789
10206
  "div",
9790
10207
  {
9791
10208
  ref: popoverRef,
@@ -9804,15 +10221,15 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9804
10221
  top: adjustedPosition.y
9805
10222
  },
9806
10223
  children: [
9807
- agentLastStatement && /* @__PURE__ */ jsx31("div", { className: "mb-2 p-2 bg-blue-50 dark:bg-blue-900/50 rounded text-xs text-blue-600 dark:text-blue-300 border border-blue-100 dark:border-blue-800", children: /* @__PURE__ */ jsxs25("div", { className: "flex items-start gap-1", children: [
9808
- /* @__PURE__ */ jsx31("svg", { className: "w-3 h-3 mt-0.5 flex-shrink-0", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx31("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }),
9809
- /* @__PURE__ */ jsxs25("span", { className: "line-clamp-2", children: [
10224
+ agentLastStatement && /* @__PURE__ */ jsx32("div", { className: "mb-2 p-2 bg-blue-50 dark:bg-blue-900/50 rounded text-xs text-blue-600 dark:text-blue-300 border border-blue-100 dark:border-blue-800", children: /* @__PURE__ */ jsxs26("div", { className: "flex items-start gap-1", children: [
10225
+ /* @__PURE__ */ jsx32("svg", { className: "w-3 h-3 mt-0.5 flex-shrink-0", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx32("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }),
10226
+ /* @__PURE__ */ jsxs26("span", { className: "line-clamp-2", children: [
9810
10227
  "AI discussed: \u201C",
9811
10228
  agentLastStatement,
9812
10229
  "\u201D"
9813
10230
  ] })
9814
10231
  ] }) }),
9815
- /* @__PURE__ */ jsx31(
10232
+ /* @__PURE__ */ jsx32(
9816
10233
  "textarea",
9817
10234
  {
9818
10235
  ref: textareaRef,
@@ -9831,13 +10248,13 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9831
10248
  )
9832
10249
  }
9833
10250
  ),
9834
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between mt-2", children: [
9835
- /* @__PURE__ */ jsxs25("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
10251
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between mt-2", children: [
10252
+ /* @__PURE__ */ jsxs26("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
9836
10253
  navigator.platform.includes("Mac") ? "\u2318" : "Ctrl",
9837
10254
  "+Enter to save"
9838
10255
  ] }),
9839
- /* @__PURE__ */ jsxs25("div", { className: "flex gap-2", children: [
9840
- /* @__PURE__ */ jsx31(
10256
+ /* @__PURE__ */ jsxs26("div", { className: "flex gap-2", children: [
10257
+ /* @__PURE__ */ jsx32(
9841
10258
  "button",
9842
10259
  {
9843
10260
  onClick: onCancel,
@@ -9850,7 +10267,7 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9850
10267
  children: "Cancel"
9851
10268
  }
9852
10269
  ),
9853
- /* @__PURE__ */ jsx31(
10270
+ /* @__PURE__ */ jsx32(
9854
10271
  "button",
9855
10272
  {
9856
10273
  onClick: handleSave,
@@ -9874,9 +10291,9 @@ var QuickNotePopover = memo30(function QuickNotePopover2({
9874
10291
 
9875
10292
  // src/components/AskAbout/AskAboutOverlay.tsx
9876
10293
  init_utils();
9877
- import { memo as memo31 } from "react";
9878
- import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
9879
- var AskAboutOverlay = memo31(function AskAboutOverlay2({
10294
+ import { memo as memo32 } from "react";
10295
+ import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
10296
+ var AskAboutOverlay = memo32(function AskAboutOverlay2({
9880
10297
  visible,
9881
10298
  progress,
9882
10299
  position,
@@ -9890,7 +10307,7 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9890
10307
  const radius = (size - strokeWidth) / 2;
9891
10308
  const circumference = 2 * Math.PI * radius;
9892
10309
  const strokeDashoffset = circumference * (1 - progress);
9893
- return /* @__PURE__ */ jsxs26(
10310
+ return /* @__PURE__ */ jsxs27(
9894
10311
  "div",
9895
10312
  {
9896
10313
  className: cn(
@@ -9903,7 +10320,7 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9903
10320
  top: position.y - size / 2
9904
10321
  },
9905
10322
  children: [
9906
- /* @__PURE__ */ jsxs26(
10323
+ /* @__PURE__ */ jsxs27(
9907
10324
  "svg",
9908
10325
  {
9909
10326
  width: size,
@@ -9911,7 +10328,7 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9911
10328
  viewBox: `0 0 ${size} ${size}`,
9912
10329
  className: "transform -rotate-90",
9913
10330
  children: [
9914
- /* @__PURE__ */ jsx32(
10331
+ /* @__PURE__ */ jsx33(
9915
10332
  "circle",
9916
10333
  {
9917
10334
  cx: size / 2,
@@ -9922,7 +10339,7 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9922
10339
  strokeWidth
9923
10340
  }
9924
10341
  ),
9925
- /* @__PURE__ */ jsx32(
10342
+ /* @__PURE__ */ jsx33(
9926
10343
  "circle",
9927
10344
  {
9928
10345
  cx: size / 2,
@@ -9940,12 +10357,12 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9940
10357
  ]
9941
10358
  }
9942
10359
  ),
9943
- /* @__PURE__ */ jsx32(
10360
+ /* @__PURE__ */ jsx33(
9944
10361
  "div",
9945
10362
  {
9946
10363
  className: "absolute inset-0 flex items-center justify-center",
9947
10364
  style: { color: progress >= 1 ? "#22c55e" : "white" },
9948
- children: progress >= 1 ? /* @__PURE__ */ jsx32(
10365
+ children: progress >= 1 ? /* @__PURE__ */ jsx33(
9949
10366
  "svg",
9950
10367
  {
9951
10368
  width: "24",
@@ -9956,9 +10373,9 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9956
10373
  strokeWidth: "2",
9957
10374
  strokeLinecap: "round",
9958
10375
  strokeLinejoin: "round",
9959
- children: /* @__PURE__ */ jsx32("polyline", { points: "20 6 9 17 4 12" })
10376
+ children: /* @__PURE__ */ jsx33("polyline", { points: "20 6 9 17 4 12" })
9960
10377
  }
9961
- ) : /* @__PURE__ */ jsxs26(
10378
+ ) : /* @__PURE__ */ jsxs27(
9962
10379
  "svg",
9963
10380
  {
9964
10381
  width: "20",
@@ -9970,9 +10387,9 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9970
10387
  strokeLinecap: "round",
9971
10388
  strokeLinejoin: "round",
9972
10389
  children: [
9973
- /* @__PURE__ */ jsx32("circle", { cx: "12", cy: "12", r: "10" }),
9974
- /* @__PURE__ */ jsx32("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
9975
- /* @__PURE__ */ jsx32("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
10390
+ /* @__PURE__ */ jsx33("circle", { cx: "12", cy: "12", r: "10" }),
10391
+ /* @__PURE__ */ jsx33("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
10392
+ /* @__PURE__ */ jsx33("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
9976
10393
  ]
9977
10394
  }
9978
10395
  )
@@ -9985,9 +10402,9 @@ var AskAboutOverlay = memo31(function AskAboutOverlay2({
9985
10402
 
9986
10403
  // src/components/AskAbout/AskAboutTrigger.tsx
9987
10404
  init_utils();
9988
- import { memo as memo32, useCallback as useCallback38, useState as useState27, useRef as useRef24, useEffect as useEffect25 } from "react";
9989
- import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
9990
- var AskAboutTrigger = memo32(function AskAboutTrigger2({
10405
+ import { memo as memo33, useCallback as useCallback39, useState as useState27, useRef as useRef24, useEffect as useEffect25 } from "react";
10406
+ import { jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
10407
+ var AskAboutTrigger = memo33(function AskAboutTrigger2({
9991
10408
  position,
9992
10409
  onConfirm,
9993
10410
  onCancel,
@@ -10018,14 +10435,14 @@ var AskAboutTrigger = memo32(function AskAboutTrigger2({
10018
10435
  const timer = setTimeout(onCancel, autoHideDelay);
10019
10436
  return () => clearTimeout(timer);
10020
10437
  }, [visible, autoHideDelay, onCancel]);
10021
- const handleConfirm = useCallback38(
10438
+ const handleConfirm = useCallback39(
10022
10439
  (e) => {
10023
10440
  e.stopPropagation();
10024
10441
  onConfirm();
10025
10442
  },
10026
10443
  [onConfirm]
10027
10444
  );
10028
- const handleCancel = useCallback38(
10445
+ const handleCancel = useCallback39(
10029
10446
  (e) => {
10030
10447
  e.stopPropagation();
10031
10448
  onCancel();
@@ -10035,7 +10452,7 @@ var AskAboutTrigger = memo32(function AskAboutTrigger2({
10035
10452
  if (!visible) {
10036
10453
  return null;
10037
10454
  }
10038
- return /* @__PURE__ */ jsxs27(
10455
+ return /* @__PURE__ */ jsxs28(
10039
10456
  "div",
10040
10457
  {
10041
10458
  ref: triggerRef,
@@ -10054,8 +10471,8 @@ var AskAboutTrigger = memo32(function AskAboutTrigger2({
10054
10471
  transform: "translate(-50%, 0)"
10055
10472
  },
10056
10473
  children: [
10057
- /* @__PURE__ */ jsx33("span", { className: "text-sm text-gray-600 dark:text-gray-300 px-2", children: "Ask about this?" }),
10058
- /* @__PURE__ */ jsx33(
10474
+ /* @__PURE__ */ jsx34("span", { className: "text-sm text-gray-600 dark:text-gray-300 px-2", children: "Ask about this?" }),
10475
+ /* @__PURE__ */ jsx34(
10059
10476
  "button",
10060
10477
  {
10061
10478
  onClick: handleConfirm,
@@ -10068,7 +10485,7 @@ var AskAboutTrigger = memo32(function AskAboutTrigger2({
10068
10485
  children: "Ask"
10069
10486
  }
10070
10487
  ),
10071
- /* @__PURE__ */ jsx33(
10488
+ /* @__PURE__ */ jsx34(
10072
10489
  "button",
10073
10490
  {
10074
10491
  onClick: handleCancel,
@@ -10090,9 +10507,9 @@ var AskAboutTrigger = memo32(function AskAboutTrigger2({
10090
10507
  // src/components/Minimap/Minimap.tsx
10091
10508
  init_hooks();
10092
10509
  init_utils();
10093
- import { memo as memo33, useMemo as useMemo14, useCallback as useCallback39 } from "react";
10094
- import { Fragment as Fragment3, jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
10095
- var PageIndicator = memo33(function PageIndicator2({
10510
+ import { memo as memo34, useMemo as useMemo14, useCallback as useCallback40 } from "react";
10511
+ import { Fragment as Fragment3, jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
10512
+ var PageIndicator = memo34(function PageIndicator2({
10096
10513
  pageNumber,
10097
10514
  status,
10098
10515
  isBookmarked,
@@ -10106,7 +10523,7 @@ var PageIndicator = memo33(function PageIndicator2({
10106
10523
  if (status === "visited") return "bg-green-400";
10107
10524
  return "bg-gray-200 dark:bg-gray-700";
10108
10525
  };
10109
- return /* @__PURE__ */ jsxs28(
10526
+ return /* @__PURE__ */ jsxs29(
10110
10527
  "button",
10111
10528
  {
10112
10529
  onClick,
@@ -10122,13 +10539,13 @@ var PageIndicator = memo33(function PageIndicator2({
10122
10539
  title: `Page ${pageNumber}${isBookmarked ? " (bookmarked)" : ""}`,
10123
10540
  "aria-label": `Go to page ${pageNumber}`,
10124
10541
  children: [
10125
- isBookmarked && !compact && /* @__PURE__ */ jsx34("div", { className: "absolute -top-1 -right-1 w-2 h-2 bg-yellow-500 rounded-full border border-white" }),
10126
- showNumber && !compact && /* @__PURE__ */ jsx34("span", { className: "absolute inset-0 flex items-center justify-center text-[8px] font-medium text-white", children: pageNumber })
10542
+ isBookmarked && !compact && /* @__PURE__ */ jsx35("div", { className: "absolute -top-1 -right-1 w-2 h-2 bg-yellow-500 rounded-full border border-white" }),
10543
+ showNumber && !compact && /* @__PURE__ */ jsx35("span", { className: "absolute inset-0 flex items-center justify-center text-[8px] font-medium text-white", children: pageNumber })
10127
10544
  ]
10128
10545
  }
10129
10546
  );
10130
10547
  });
10131
- var Minimap = memo33(function Minimap2({
10548
+ var Minimap = memo34(function Minimap2({
10132
10549
  variant = "sidebar",
10133
10550
  floatingPosition = "right",
10134
10551
  maxHeight = 300,
@@ -10145,14 +10562,14 @@ var Minimap = memo33(function Minimap2({
10145
10562
  return new Set(bookmarks.map((b) => b.pageNumber));
10146
10563
  }, [bookmarks]);
10147
10564
  const compact = numPages > 50;
10148
- const handlePageClick = useCallback39(
10565
+ const handlePageClick = useCallback40(
10149
10566
  (pageNumber) => {
10150
10567
  goToPage(pageNumber);
10151
10568
  onPageClick?.(pageNumber);
10152
10569
  },
10153
10570
  [goToPage, onPageClick]
10154
10571
  );
10155
- const getPageStatus = useCallback39(
10572
+ const getPageStatus = useCallback40(
10156
10573
  (pageNumber) => {
10157
10574
  if (pageNumber === currentPage) return "current";
10158
10575
  if (bookmarkedPages.has(pageNumber)) return "bookmarked";
@@ -10165,7 +10582,7 @@ var Minimap = memo33(function Minimap2({
10165
10582
  const pages = [];
10166
10583
  for (let i = 1; i <= numPages; i++) {
10167
10584
  pages.push(
10168
- /* @__PURE__ */ jsx34(
10585
+ /* @__PURE__ */ jsx35(
10169
10586
  PageIndicator,
10170
10587
  {
10171
10588
  pageNumber: i,
@@ -10186,16 +10603,16 @@ var Minimap = memo33(function Minimap2({
10186
10603
  if (numPages === 0) {
10187
10604
  return null;
10188
10605
  }
10189
- const content = /* @__PURE__ */ jsxs28(Fragment3, { children: [
10190
- /* @__PURE__ */ jsxs28("div", { className: "mb-3", children: [
10191
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between text-xs text-gray-500 dark:text-gray-400 mb-1", children: [
10192
- /* @__PURE__ */ jsx34("span", { children: "Progress" }),
10193
- /* @__PURE__ */ jsxs28("span", { children: [
10606
+ const content = /* @__PURE__ */ jsxs29(Fragment3, { children: [
10607
+ /* @__PURE__ */ jsxs29("div", { className: "mb-3", children: [
10608
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between text-xs text-gray-500 dark:text-gray-400 mb-1", children: [
10609
+ /* @__PURE__ */ jsx35("span", { children: "Progress" }),
10610
+ /* @__PURE__ */ jsxs29("span", { children: [
10194
10611
  progressPercentage,
10195
10612
  "%"
10196
10613
  ] })
10197
10614
  ] }),
10198
- /* @__PURE__ */ jsx34("div", { className: "h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx34(
10615
+ /* @__PURE__ */ jsx35("div", { className: "h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx35(
10199
10616
  "div",
10200
10617
  {
10201
10618
  className: "h-full bg-green-500 rounded-full transition-all duration-300",
@@ -10203,7 +10620,7 @@ var Minimap = memo33(function Minimap2({
10203
10620
  }
10204
10621
  ) })
10205
10622
  ] }),
10206
- /* @__PURE__ */ jsx34(
10623
+ /* @__PURE__ */ jsx35(
10207
10624
  "div",
10208
10625
  {
10209
10626
  className: cn(
@@ -10214,21 +10631,21 @@ var Minimap = memo33(function Minimap2({
10214
10631
  children: pageIndicators
10215
10632
  }
10216
10633
  ),
10217
- /* @__PURE__ */ jsx34("div", { className: "mt-3 pt-2 border-t border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400", children: [
10218
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1", children: [
10219
- /* @__PURE__ */ jsx34("div", { className: "w-2 h-2 rounded-sm bg-blue-500" }),
10220
- /* @__PURE__ */ jsx34("span", { children: "Current" })
10634
+ /* @__PURE__ */ jsx35("div", { className: "mt-3 pt-2 border-t border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400", children: [
10635
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1", children: [
10636
+ /* @__PURE__ */ jsx35("div", { className: "w-2 h-2 rounded-sm bg-blue-500" }),
10637
+ /* @__PURE__ */ jsx35("span", { children: "Current" })
10221
10638
  ] }),
10222
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1", children: [
10223
- /* @__PURE__ */ jsx34("div", { className: "w-2 h-2 rounded-sm bg-green-400" }),
10224
- /* @__PURE__ */ jsx34("span", { children: "Visited" })
10639
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1", children: [
10640
+ /* @__PURE__ */ jsx35("div", { className: "w-2 h-2 rounded-sm bg-green-400" }),
10641
+ /* @__PURE__ */ jsx35("span", { children: "Visited" })
10225
10642
  ] }),
10226
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-1", children: [
10227
- /* @__PURE__ */ jsx34("div", { className: "w-2 h-2 rounded-sm bg-yellow-400" }),
10228
- /* @__PURE__ */ jsx34("span", { children: "Bookmarked" })
10643
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1", children: [
10644
+ /* @__PURE__ */ jsx35("div", { className: "w-2 h-2 rounded-sm bg-yellow-400" }),
10645
+ /* @__PURE__ */ jsx35("span", { children: "Bookmarked" })
10229
10646
  ] })
10230
10647
  ] }) }),
10231
- /* @__PURE__ */ jsxs28("div", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: [
10648
+ /* @__PURE__ */ jsxs29("div", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: [
10232
10649
  visitedCount,
10233
10650
  " of ",
10234
10651
  numPages,
@@ -10236,7 +10653,7 @@ var Minimap = memo33(function Minimap2({
10236
10653
  ] })
10237
10654
  ] });
10238
10655
  if (variant === "floating") {
10239
- return /* @__PURE__ */ jsxs28(
10656
+ return /* @__PURE__ */ jsxs29(
10240
10657
  "div",
10241
10658
  {
10242
10659
  className: cn(
@@ -10252,13 +10669,13 @@ var Minimap = memo33(function Minimap2({
10252
10669
  ),
10253
10670
  style: { maxHeight },
10254
10671
  children: [
10255
- /* @__PURE__ */ jsx34("h3", { className: "text-sm font-semibold text-gray-700 dark:text-gray-200 mb-2", children: "Reading Progress" }),
10672
+ /* @__PURE__ */ jsx35("h3", { className: "text-sm font-semibold text-gray-700 dark:text-gray-200 mb-2", children: "Reading Progress" }),
10256
10673
  content
10257
10674
  ]
10258
10675
  }
10259
10676
  );
10260
10677
  }
10261
- return /* @__PURE__ */ jsx34(
10678
+ return /* @__PURE__ */ jsx35(
10262
10679
  "div",
10263
10680
  {
10264
10681
  className: cn(
@@ -10272,10 +10689,13 @@ var Minimap = memo33(function Minimap2({
10272
10689
  );
10273
10690
  });
10274
10691
 
10692
+ // src/components/index.ts
10693
+ init_FloatingZoomControls2();
10694
+
10275
10695
  // src/components/ErrorBoundary/PDFErrorBoundary.tsx
10276
10696
  init_utils();
10277
10697
  import { Component } from "react";
10278
- import { jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
10698
+ import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
10279
10699
  var PDFErrorBoundary = class extends Component {
10280
10700
  constructor(props) {
10281
10701
  super(props);
@@ -10303,7 +10723,7 @@ var PDFErrorBoundary = class extends Component {
10303
10723
  return fallback;
10304
10724
  }
10305
10725
  if (showDefaultUI) {
10306
- return /* @__PURE__ */ jsx35(
10726
+ return /* @__PURE__ */ jsx36(
10307
10727
  DefaultErrorUI,
10308
10728
  {
10309
10729
  error,
@@ -10322,7 +10742,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10322
10742
  const isNetworkError = error.message.includes("fetch") || error.message.includes("network") || error.message.includes("Failed to load");
10323
10743
  let title = "Something went wrong";
10324
10744
  let description = error.message;
10325
- let icon = /* @__PURE__ */ jsx35("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx35(
10745
+ let icon = /* @__PURE__ */ jsx36("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx36(
10326
10746
  "path",
10327
10747
  {
10328
10748
  strokeLinecap: "round",
@@ -10334,7 +10754,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10334
10754
  if (isPDFError) {
10335
10755
  title = "Unable to load PDF";
10336
10756
  description = "The PDF file could not be loaded. It may be corrupted or in an unsupported format.";
10337
- icon = /* @__PURE__ */ jsx35("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx35(
10757
+ icon = /* @__PURE__ */ jsx36("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx36(
10338
10758
  "path",
10339
10759
  {
10340
10760
  strokeLinecap: "round",
@@ -10346,7 +10766,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10346
10766
  } else if (isNetworkError) {
10347
10767
  title = "Network error";
10348
10768
  description = "Unable to fetch the PDF file. Please check your internet connection and try again.";
10349
- icon = /* @__PURE__ */ jsx35("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx35(
10769
+ icon = /* @__PURE__ */ jsx36("svg", { className: "w-12 h-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx36(
10350
10770
  "path",
10351
10771
  {
10352
10772
  strokeLinecap: "round",
@@ -10356,7 +10776,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10356
10776
  }
10357
10777
  ) });
10358
10778
  }
10359
- return /* @__PURE__ */ jsxs29(
10779
+ return /* @__PURE__ */ jsxs30(
10360
10780
  "div",
10361
10781
  {
10362
10782
  className: cn(
@@ -10369,14 +10789,14 @@ function DefaultErrorUI({ error, onReset, className }) {
10369
10789
  ),
10370
10790
  children: [
10371
10791
  icon,
10372
- /* @__PURE__ */ jsx35("h2", { className: "mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100", children: title }),
10373
- /* @__PURE__ */ jsx35("p", { className: "mt-2 text-sm text-gray-600 dark:text-gray-400 max-w-md", children: description }),
10374
- /* @__PURE__ */ jsxs29("details", { className: "mt-4 text-left max-w-md w-full", children: [
10375
- /* @__PURE__ */ jsx35("summary", { className: "cursor-pointer text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200", children: "Technical details" }),
10376
- /* @__PURE__ */ jsx35("pre", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded text-xs overflow-auto", children: error.stack || error.message })
10792
+ /* @__PURE__ */ jsx36("h2", { className: "mt-4 text-xl font-semibold text-gray-900 dark:text-gray-100", children: title }),
10793
+ /* @__PURE__ */ jsx36("p", { className: "mt-2 text-sm text-gray-600 dark:text-gray-400 max-w-md", children: description }),
10794
+ /* @__PURE__ */ jsxs30("details", { className: "mt-4 text-left max-w-md w-full", children: [
10795
+ /* @__PURE__ */ jsx36("summary", { className: "cursor-pointer text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200", children: "Technical details" }),
10796
+ /* @__PURE__ */ jsx36("pre", { className: "mt-2 p-2 bg-gray-100 dark:bg-gray-800 rounded text-xs overflow-auto", children: error.stack || error.message })
10377
10797
  ] }),
10378
- /* @__PURE__ */ jsxs29("div", { className: "mt-6 flex gap-3", children: [
10379
- /* @__PURE__ */ jsx35(
10798
+ /* @__PURE__ */ jsxs30("div", { className: "mt-6 flex gap-3", children: [
10799
+ /* @__PURE__ */ jsx36(
10380
10800
  "button",
10381
10801
  {
10382
10802
  onClick: onReset,
@@ -10390,7 +10810,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10390
10810
  children: "Try again"
10391
10811
  }
10392
10812
  ),
10393
- /* @__PURE__ */ jsx35(
10813
+ /* @__PURE__ */ jsx36(
10394
10814
  "button",
10395
10815
  {
10396
10816
  onClick: () => window.location.reload(),
@@ -10410,7 +10830,7 @@ function DefaultErrorUI({ error, onReset, className }) {
10410
10830
  );
10411
10831
  }
10412
10832
  function withErrorBoundary({ component, ...props }) {
10413
- return /* @__PURE__ */ jsx35(PDFErrorBoundary, { ...props, children: component });
10833
+ return /* @__PURE__ */ jsx36(PDFErrorBoundary, { ...props, children: component });
10414
10834
  }
10415
10835
 
10416
10836
  // src/index.ts
@@ -10433,6 +10853,7 @@ export {
10433
10853
  DocumentContainer,
10434
10854
  DrawingCanvas,
10435
10855
  DualPageContainer,
10856
+ FloatingZoomControls,
10436
10857
  FocusRegionLayer,
10437
10858
  HighlightLayer,
10438
10859
  HighlightPopover,