hazo_pdf 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -1
- package/dist/{chunk-S3AJUZ7D.js → chunk-R4SDDAZW.js} +37 -1
- package/dist/chunk-R4SDDAZW.js.map +1 -0
- package/dist/index.d.ts +487 -14
- package/dist/index.js +2260 -255
- package/dist/index.js.map +1 -1
- package/dist/{pdf_saver-P2MJN45S.js → pdf_saver-V73SQX7B.js} +2 -2
- package/dist/styles/full.css +2873 -3
- package/dist/styles/full.css.map +1 -1
- package/dist/styles/index.css +911 -111
- package/dist/styles/index.css.map +1 -1
- package/package.json +14 -5
- package/dist/chunk-S3AJUZ7D.js.map +0 -1
- /package/dist/{pdf_saver-P2MJN45S.js.map → pdf_saver-V73SQX7B.js.map} +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A React component library for viewing and annotating PDF documents with support
|
|
|
6
6
|
|
|
7
7
|
- 📄 **PDF Viewing** - Render PDF documents with customizable zoom levels
|
|
8
8
|
- ✏️ **Annotations** - Square and FreeText annotation tools
|
|
9
|
+
- 🔍 **Programmatic Highlights** - Ref-based API for creating and managing highlights programmatically
|
|
9
10
|
- 🎨 **Customizable Styling** - Extensive configuration options via INI file
|
|
10
11
|
- ⏰ **Timestamp Support** - Automatic timestamp appending to annotations
|
|
11
12
|
- 🏷️ **Custom Stamps** - Add quick-insert stamps via right-click menu
|
|
@@ -19,6 +20,16 @@ A React component library for viewing and annotating PDF documents with support
|
|
|
19
20
|
npm install hazo_pdf
|
|
20
21
|
```
|
|
21
22
|
|
|
23
|
+
### Optional Dependencies
|
|
24
|
+
|
|
25
|
+
**hazo_logs** (optional): For structured logging and debugging
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install hazo_logs
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The `hazo_logs` package is an optional peer dependency. If not installed, hazo_pdf will use console-based logging as a fallback.
|
|
32
|
+
|
|
22
33
|
## CSS Import Options
|
|
23
34
|
|
|
24
35
|
The library provides two CSS files to choose from:
|
|
@@ -68,7 +79,7 @@ import 'hazo_pdf/styles.css';
|
|
|
68
79
|
|
|
69
80
|
function App() {
|
|
70
81
|
return (
|
|
71
|
-
<PdfViewer
|
|
82
|
+
<PdfViewer
|
|
72
83
|
url="/path/to/document.pdf"
|
|
73
84
|
/>
|
|
74
85
|
);
|
|
@@ -77,6 +88,27 @@ function App() {
|
|
|
77
88
|
|
|
78
89
|
That's it! The PDF viewer will load and display your document with default styling and pan mode enabled.
|
|
79
90
|
|
|
91
|
+
### With Logging (Optional)
|
|
92
|
+
|
|
93
|
+
For debugging and monitoring, you can integrate hazo_logs:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { PdfViewer } from 'hazo_pdf';
|
|
97
|
+
import { create_logger } from 'hazo_logs';
|
|
98
|
+
import 'hazo_pdf/styles.css';
|
|
99
|
+
|
|
100
|
+
const logger = create_logger('my_app', 'config/hazo_logs_config.ini');
|
|
101
|
+
|
|
102
|
+
function App() {
|
|
103
|
+
return (
|
|
104
|
+
<PdfViewer
|
|
105
|
+
url="/path/to/document.pdf"
|
|
106
|
+
logger={logger}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
80
112
|
---
|
|
81
113
|
|
|
82
114
|
## Examples
|
|
@@ -413,6 +445,204 @@ See `config/hazo_pdf_config.ini` in the project root for all available configura
|
|
|
413
445
|
|
|
414
446
|
---
|
|
415
447
|
|
|
448
|
+
## Programmatic Highlight API
|
|
449
|
+
|
|
450
|
+
The PDF viewer exposes a ref-based API for programmatically creating, removing, and managing highlights. This allows external code to control highlights without user interaction.
|
|
451
|
+
|
|
452
|
+
### Basic Usage
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
import { PdfViewer, PdfViewerRef } from 'hazo_pdf';
|
|
456
|
+
import { useRef } from 'react';
|
|
457
|
+
import 'hazo_pdf/styles.css';
|
|
458
|
+
|
|
459
|
+
function HighlightExample() {
|
|
460
|
+
const viewer_ref = useRef<PdfViewerRef>(null);
|
|
461
|
+
|
|
462
|
+
const add_highlight = () => {
|
|
463
|
+
// Highlight region on page 0 at PDF coordinates [100, 500, 300, 550]
|
|
464
|
+
const id = viewer_ref.current?.highlight_region(0, [100, 500, 300, 550], {
|
|
465
|
+
border_color: '#FF0000',
|
|
466
|
+
background_color: '#FFFF00',
|
|
467
|
+
background_opacity: 0.4
|
|
468
|
+
});
|
|
469
|
+
console.log('Created highlight:', id);
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const remove_specific_highlight = (id: string) => {
|
|
473
|
+
const removed = viewer_ref.current?.remove_highlight(id);
|
|
474
|
+
console.log('Highlight removed:', removed);
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
const clear_all = () => {
|
|
478
|
+
viewer_ref.current?.clear_all_highlights();
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
return (
|
|
482
|
+
<div style={{ width: '100%', height: '800px' }}>
|
|
483
|
+
<button onClick={add_highlight}>Add Highlight</button>
|
|
484
|
+
<button onClick={clear_all}>Clear All Highlights</button>
|
|
485
|
+
|
|
486
|
+
<PdfViewer
|
|
487
|
+
ref={viewer_ref}
|
|
488
|
+
url="/document.pdf"
|
|
489
|
+
/>
|
|
490
|
+
</div>
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### PdfViewerRef Interface
|
|
496
|
+
|
|
497
|
+
The ref exposes three methods for highlight management:
|
|
498
|
+
|
|
499
|
+
#### `highlight_region(page_index, rect, options?)`
|
|
500
|
+
|
|
501
|
+
Creates a new highlight annotation on the specified page.
|
|
502
|
+
|
|
503
|
+
**Parameters:**
|
|
504
|
+
- `page_index` (number): Zero-based page index where the highlight should appear
|
|
505
|
+
- `rect` ([number, number, number, number]): Rectangle coordinates in PDF space [x1, y1, x2, y2]
|
|
506
|
+
- `options` (HighlightOptions, optional): Styling options
|
|
507
|
+
|
|
508
|
+
**Returns:** `string` - The unique ID of the created highlight annotation
|
|
509
|
+
|
|
510
|
+
**HighlightOptions:**
|
|
511
|
+
```typescript
|
|
512
|
+
{
|
|
513
|
+
border_color?: string; // Hex color (e.g., "#FF0000")
|
|
514
|
+
background_color?: string; // Hex color (e.g., "#FFFF00")
|
|
515
|
+
background_opacity?: number; // 0-1 (e.g., 0.4)
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Example:**
|
|
520
|
+
```tsx
|
|
521
|
+
const id = viewer_ref.current?.highlight_region(
|
|
522
|
+
0, // Page 0
|
|
523
|
+
[100, 500, 300, 550], // PDF coordinates
|
|
524
|
+
{
|
|
525
|
+
border_color: '#FF0000',
|
|
526
|
+
background_color: '#FFFF00',
|
|
527
|
+
background_opacity: 0.4
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
#### `remove_highlight(id)`
|
|
533
|
+
|
|
534
|
+
Removes a specific highlight by its ID.
|
|
535
|
+
|
|
536
|
+
**Parameters:**
|
|
537
|
+
- `id` (string): The highlight ID returned from `highlight_region()`
|
|
538
|
+
|
|
539
|
+
**Returns:** `boolean` - `true` if the highlight was found and removed, `false` otherwise
|
|
540
|
+
|
|
541
|
+
**Example:**
|
|
542
|
+
```tsx
|
|
543
|
+
const removed = viewer_ref.current?.remove_highlight('highlight-123');
|
|
544
|
+
if (removed) {
|
|
545
|
+
console.log('Highlight removed successfully');
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
#### `clear_all_highlights()`
|
|
550
|
+
|
|
551
|
+
Removes all highlights created via the `highlight_region()` API. Does not affect user-created annotations.
|
|
552
|
+
|
|
553
|
+
**Example:**
|
|
554
|
+
```tsx
|
|
555
|
+
viewer_ref.current?.clear_all_highlights();
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Advanced Example: Search Results Highlighting
|
|
559
|
+
|
|
560
|
+
A common use case is highlighting search results in a PDF:
|
|
561
|
+
|
|
562
|
+
```tsx
|
|
563
|
+
import { useState, useRef } from 'react';
|
|
564
|
+
import { PdfViewer, PdfViewerRef } from 'hazo_pdf';
|
|
565
|
+
import 'hazo_pdf/styles.css';
|
|
566
|
+
|
|
567
|
+
interface SearchResult {
|
|
568
|
+
page: number;
|
|
569
|
+
rect: [number, number, number, number];
|
|
570
|
+
text: string;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function SearchableViewer() {
|
|
574
|
+
const viewer_ref = useRef<PdfViewerRef>(null);
|
|
575
|
+
const [highlight_ids, set_highlight_ids] = useState<string[]>([]);
|
|
576
|
+
|
|
577
|
+
// Simulated search results
|
|
578
|
+
const search_results: SearchResult[] = [
|
|
579
|
+
{ page: 0, rect: [100, 500, 300, 550], text: 'Result 1' },
|
|
580
|
+
{ page: 0, rect: [100, 400, 300, 450], text: 'Result 2' },
|
|
581
|
+
{ page: 1, rect: [150, 600, 350, 650], text: 'Result 3' }
|
|
582
|
+
];
|
|
583
|
+
|
|
584
|
+
const highlight_search_results = () => {
|
|
585
|
+
// Clear previous highlights
|
|
586
|
+
viewer_ref.current?.clear_all_highlights();
|
|
587
|
+
|
|
588
|
+
// Add new highlights
|
|
589
|
+
const ids = search_results.map(result =>
|
|
590
|
+
viewer_ref.current?.highlight_region(result.page, result.rect, {
|
|
591
|
+
border_color: '#3B82F6',
|
|
592
|
+
background_color: '#DBEAFE',
|
|
593
|
+
background_opacity: 0.3
|
|
594
|
+
})
|
|
595
|
+
).filter(Boolean) as string[];
|
|
596
|
+
|
|
597
|
+
set_highlight_ids(ids);
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
const clear_search = () => {
|
|
601
|
+
viewer_ref.current?.clear_all_highlights();
|
|
602
|
+
set_highlight_ids([]);
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
return (
|
|
606
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
607
|
+
<div style={{ padding: '1rem', background: '#f0f0f0' }}>
|
|
608
|
+
<button onClick={highlight_search_results}>
|
|
609
|
+
Highlight Search Results ({search_results.length})
|
|
610
|
+
</button>
|
|
611
|
+
<button onClick={clear_search}>Clear Highlights</button>
|
|
612
|
+
<span>Highlighted: {highlight_ids.length} results</span>
|
|
613
|
+
</div>
|
|
614
|
+
|
|
615
|
+
<div style={{ flex: 1 }}>
|
|
616
|
+
<PdfViewer
|
|
617
|
+
ref={viewer_ref}
|
|
618
|
+
url="/document.pdf"
|
|
619
|
+
/>
|
|
620
|
+
</div>
|
|
621
|
+
</div>
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Coordinate System Notes
|
|
627
|
+
|
|
628
|
+
- Highlights use PDF coordinate space (points), not screen pixels
|
|
629
|
+
- PDF coordinates start at the bottom-left corner (Y increases upward)
|
|
630
|
+
- The `rect` parameter format is `[x1, y1, x2, y2]` where:
|
|
631
|
+
- `x1, y1`: Bottom-left corner
|
|
632
|
+
- `x2, y2`: Top-right corner
|
|
633
|
+
- If you need to convert screen coordinates to PDF coordinates, you'll need to use the PDF page viewport (see the test app for examples)
|
|
634
|
+
|
|
635
|
+
### Styling Defaults
|
|
636
|
+
|
|
637
|
+
If no `options` are provided to `highlight_region()`, the highlight uses default colors from the configuration file:
|
|
638
|
+
- `border_color`: From `highlight_border_color` config setting
|
|
639
|
+
- `background_color`: From `highlight_fill_color` config setting
|
|
640
|
+
- `background_opacity`: From `highlight_fill_opacity` config setting
|
|
641
|
+
|
|
642
|
+
You can override any or all of these on a per-highlight basis.
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
416
646
|
## API Reference
|
|
417
647
|
|
|
418
648
|
### PdfViewer Props
|
|
@@ -433,6 +663,7 @@ See `config/hazo_pdf_config.ini` in the project root for all available configura
|
|
|
433
663
|
| `scale` | `number` | `1.0` | Initial zoom level. Values > 1.0 zoom in, < 1.0 zoom out. |
|
|
434
664
|
| `background_color` | `string` | `"#2d2d2d"` | Background color for areas outside PDF pages (hex format: `#RRGGBB`). Overrides config file value. |
|
|
435
665
|
| `config_file` | `string` | `undefined` | Path to configuration INI file (e.g., `"config/hazo_pdf_config.ini"`). If not provided, uses default configuration. |
|
|
666
|
+
| `logger` | `Logger` | `undefined` | Logger instance from hazo_logs or custom logger matching the Logger interface. If not provided, falls back to console-based logging. Useful for debugging and monitoring PDF operations. |
|
|
436
667
|
|
|
437
668
|
##### Event Callbacks
|
|
438
669
|
|
|
@@ -573,6 +804,107 @@ interface PdfAnnotation {
|
|
|
573
804
|
}
|
|
574
805
|
```
|
|
575
806
|
|
|
807
|
+
**Note:** Highlights created via the programmatic API (`PdfViewerRef.highlight_region()`) will have `type: 'Highlight'` and `flags: 'api_highlight'` to distinguish them from user-created annotations.
|
|
808
|
+
|
|
809
|
+
### PdfViewerRef Interface
|
|
810
|
+
|
|
811
|
+
Interface for the ref exposed by `PdfViewer`. Use with `useRef<PdfViewerRef>()` to access programmatic highlight methods.
|
|
812
|
+
|
|
813
|
+
```typescript
|
|
814
|
+
interface PdfViewerRef {
|
|
815
|
+
highlight_region: (
|
|
816
|
+
page_index: number,
|
|
817
|
+
rect: [number, number, number, number],
|
|
818
|
+
options?: HighlightOptions
|
|
819
|
+
) => string;
|
|
820
|
+
|
|
821
|
+
remove_highlight: (id: string) => boolean;
|
|
822
|
+
|
|
823
|
+
clear_all_highlights: () => void;
|
|
824
|
+
}
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
See [Programmatic Highlight API](#programmatic-highlight-api) for detailed usage.
|
|
828
|
+
|
|
829
|
+
### HighlightOptions Interface
|
|
830
|
+
|
|
831
|
+
Options for customizing highlights created via the API.
|
|
832
|
+
|
|
833
|
+
```typescript
|
|
834
|
+
interface HighlightOptions {
|
|
835
|
+
border_color?: string; // Hex format (e.g., "#FF0000")
|
|
836
|
+
background_color?: string; // Hex format (e.g., "#FFFF00")
|
|
837
|
+
background_opacity?: number; // 0-1 (e.g., 0.4)
|
|
838
|
+
}
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Logger Interface
|
|
842
|
+
|
|
843
|
+
Interface for custom logging integration. Compatible with hazo_logs and custom logger implementations.
|
|
844
|
+
|
|
845
|
+
```typescript
|
|
846
|
+
interface Logger {
|
|
847
|
+
info: (message: string, data?: Record<string, unknown>) => void;
|
|
848
|
+
debug: (message: string, data?: Record<string, unknown>) => void;
|
|
849
|
+
warn: (message: string, data?: Record<string, unknown>) => void;
|
|
850
|
+
error: (message: string, data?: Record<string, unknown>) => void;
|
|
851
|
+
}
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
**Usage with hazo_logs:**
|
|
855
|
+
|
|
856
|
+
```tsx
|
|
857
|
+
import { PdfViewer } from 'hazo_pdf';
|
|
858
|
+
import { create_logger } from 'hazo_logs';
|
|
859
|
+
|
|
860
|
+
const logger = create_logger('my_app', 'config/hazo_logs_config.ini');
|
|
861
|
+
|
|
862
|
+
<PdfViewer
|
|
863
|
+
url="/document.pdf"
|
|
864
|
+
logger={logger}
|
|
865
|
+
/>
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**Usage with custom logger:**
|
|
869
|
+
|
|
870
|
+
```tsx
|
|
871
|
+
import { PdfViewer } from 'hazo_pdf';
|
|
872
|
+
|
|
873
|
+
const custom_logger = {
|
|
874
|
+
info: (message, data) => console.log('[INFO]', message, data),
|
|
875
|
+
debug: (message, data) => console.debug('[DEBUG]', message, data),
|
|
876
|
+
warn: (message, data) => console.warn('[WARN]', message, data),
|
|
877
|
+
error: (message, data) => console.error('[ERROR]', message, data),
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
<PdfViewer
|
|
881
|
+
url="/document.pdf"
|
|
882
|
+
logger={custom_logger}
|
|
883
|
+
/>
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
**Logger Utilities:**
|
|
887
|
+
|
|
888
|
+
```typescript
|
|
889
|
+
import { set_logger, get_logger } from 'hazo_pdf';
|
|
890
|
+
|
|
891
|
+
// Set logger globally for all hazo_pdf components
|
|
892
|
+
set_logger(my_logger);
|
|
893
|
+
|
|
894
|
+
// Get current logger instance
|
|
895
|
+
const current_logger = get_logger();
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
**Logging Output:**
|
|
899
|
+
|
|
900
|
+
The library logs operations such as:
|
|
901
|
+
- PDF conversion events (image to PDF, text to PDF, Excel to PDF)
|
|
902
|
+
- PDF loading and rendering
|
|
903
|
+
- Annotation operations
|
|
904
|
+
- Error conditions
|
|
905
|
+
|
|
906
|
+
If no logger is provided, hazo_pdf falls back to console-based logging with a `[hazo_pdf]` prefix.
|
|
907
|
+
|
|
576
908
|
### PDFDocumentProxy
|
|
577
909
|
|
|
578
910
|
Type from `pdfjs-dist`. Contains PDF metadata and page proxies.
|
|
@@ -105,6 +105,42 @@ var default_config = {
|
|
|
105
105
|
toolbar_save_label: "Save",
|
|
106
106
|
toolbar_saving_label: "Saving...",
|
|
107
107
|
toolbar_metadata_label: "Metadata"
|
|
108
|
+
},
|
|
109
|
+
file_manager: {
|
|
110
|
+
file_manager_enabled: false,
|
|
111
|
+
show_file_list: true,
|
|
112
|
+
allow_delete: true,
|
|
113
|
+
show_popout_button: true,
|
|
114
|
+
file_list_height: 60,
|
|
115
|
+
selected_color: "#3b82f6",
|
|
116
|
+
file_list_background_color: "#f9fafb",
|
|
117
|
+
file_list_border_color: "#e5e7eb"
|
|
118
|
+
},
|
|
119
|
+
file_upload: {
|
|
120
|
+
upload_enabled: true,
|
|
121
|
+
allowed_types: "application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel",
|
|
122
|
+
max_file_size: 10485760,
|
|
123
|
+
// 10MB
|
|
124
|
+
max_files: 10,
|
|
125
|
+
show_add_button: true,
|
|
126
|
+
dropzone_border_color: "#d1d5db",
|
|
127
|
+
dropzone_border_color_active: "#3b82f6",
|
|
128
|
+
dropzone_background_color: "#f9fafb"
|
|
129
|
+
},
|
|
130
|
+
pdf_conversion: {
|
|
131
|
+
conversion_enabled: true,
|
|
132
|
+
page_size: "letter",
|
|
133
|
+
image_quality: 0.85,
|
|
134
|
+
image_fit: "fit",
|
|
135
|
+
margin: 36
|
|
136
|
+
},
|
|
137
|
+
file_button: {
|
|
138
|
+
icon_size: 24,
|
|
139
|
+
icon_color: "#6b7280",
|
|
140
|
+
icon_color_hover: "#374151",
|
|
141
|
+
icon_color_with_files: "#3b82f6",
|
|
142
|
+
badge_background: "#3b82f6",
|
|
143
|
+
badge_text_color: "#ffffff"
|
|
108
144
|
}
|
|
109
145
|
};
|
|
110
146
|
|
|
@@ -312,4 +348,4 @@ export {
|
|
|
312
348
|
download_pdf,
|
|
313
349
|
save_and_download_pdf
|
|
314
350
|
};
|
|
315
|
-
//# sourceMappingURL=chunk-
|
|
351
|
+
//# sourceMappingURL=chunk-R4SDDAZW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/default_config.ts","../src/utils/pdf_saver.ts"],"sourcesContent":["/**\n * Default configuration values for hazo_pdf\n * All styling defaults organized by category\n */\n\nimport type { PdfViewerConfig } from '../types/config';\n\n/**\n * Default PDF Viewer Configuration\n * These values are used when no config file is provided or when values are missing\n */\nexport const default_config: PdfViewerConfig = {\n fonts: {\n freetext_font_family: 'Arial, sans-serif',\n freetext_font_size_min: 12,\n freetext_font_size_max: 24,\n freetext_font_size_default: 14,\n font_foreground_color: '#000000', // Black by default\n },\n\n highlight_annotation: {\n highlight_fill_color: '#FFFF00',\n highlight_fill_opacity: 0.3,\n highlight_border_color: '#FFD700',\n highlight_border_color_hover: '#FFD700',\n highlight_fill_opacity_hover: 0.4,\n },\n\n square_annotation: {\n square_fill_color: '#FF0000',\n square_fill_opacity: 0.2,\n square_border_color: '#FF0000',\n square_border_color_hover: '#CC0000',\n square_fill_opacity_hover: 0.3,\n },\n\n freetext_annotation: {\n freetext_text_color: '#000000',\n freetext_text_color_hover: '#000000',\n freetext_border_color: '#003366',\n freetext_border_width: 1,\n freetext_background_color: '#E6F3FF',\n freetext_background_opacity: 0.1,\n freetext_font_weight: 'normal',\n freetext_font_style: 'normal',\n freetext_text_decoration: 'none',\n freetext_padding_horizontal: 4,\n freetext_padding_vertical: 2,\n },\n\n page_styling: {\n page_border_color: '#999999',\n page_box_shadow: '0 2px 8px rgba(0, 0, 0, 0.3)',\n page_background_color: '#ffffff',\n },\n\n viewer: {\n viewer_background_color: '#2d2d2d',\n append_timestamp_to_text_edits: false,\n annotation_text_suffix_fixed_text: '',\n add_enclosing_brackets_to_suffixes: true,\n suffix_enclosing_brackets: '[]',\n suffix_text_position: 'below_multi_line',\n },\n\n context_menu: {\n context_menu_background_color: '#ffffff',\n context_menu_border_color: '#d1d5db',\n context_menu_item_hover_background: '#f3f4f6',\n context_menu_item_disabled_opacity: 0.5,\n right_click_custom_stamps: '', // Empty string means no custom stamps\n },\n\n dialog: {\n dialog_backdrop_opacity: 0.2,\n dialog_background_color: '#ffffff',\n dialog_border_color: '#d1d5db',\n dialog_button_submit_color: '#16a34a',\n dialog_button_submit_color_hover: '#15803d',\n dialog_button_cancel_color: '#6b7280',\n dialog_button_cancel_color_hover: '#4b5563',\n dialog_button_disabled_opacity: 0.4,\n },\n\n toolbar: {\n toolbar_background_color: '#f9fafb',\n toolbar_border_color: '#e5e7eb',\n toolbar_font_family: 'system-ui, -apple-system, sans-serif',\n toolbar_font_size: 14,\n toolbar_font_color: '#111827',\n toolbar_button_background_color: '#ffffff',\n toolbar_button_background_color_hover: '#f3f4f6',\n toolbar_button_text_color: '#374151',\n toolbar_button_active_background_color: '#3b82f6',\n toolbar_button_active_text_color: '#ffffff',\n toolbar_button_save_background_color: '#10b981',\n toolbar_button_save_background_color_hover: '#059669',\n toolbar_button_save_text_color: '#ffffff',\n toolbar_button_disabled_opacity: 0.5,\n toolbar_show_zoom_controls: true,\n toolbar_show_square_button: true,\n toolbar_show_undo_button: true,\n toolbar_show_redo_button: true,\n toolbar_show_save_button: true,\n toolbar_show_metadata_button: true,\n toolbar_show_annotate_button: true,\n toolbar_zoom_out_label: '−',\n toolbar_zoom_in_label: '+',\n toolbar_zoom_reset_label: 'Reset',\n toolbar_square_label: 'Square',\n toolbar_undo_label: 'Undo',\n toolbar_redo_label: 'Redo',\n toolbar_save_label: 'Save',\n toolbar_saving_label: 'Saving...',\n toolbar_metadata_label: 'Metadata',\n },\n\n file_manager: {\n file_manager_enabled: false,\n show_file_list: true,\n allow_delete: true,\n show_popout_button: true,\n file_list_height: 60,\n selected_color: '#3b82f6',\n file_list_background_color: '#f9fafb',\n file_list_border_color: '#e5e7eb',\n },\n\n file_upload: {\n upload_enabled: true,\n allowed_types: 'application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',\n max_file_size: 10485760, // 10MB\n max_files: 10,\n show_add_button: true,\n dropzone_border_color: '#d1d5db',\n dropzone_border_color_active: '#3b82f6',\n dropzone_background_color: '#f9fafb',\n },\n\n pdf_conversion: {\n conversion_enabled: true,\n page_size: 'letter',\n image_quality: 0.85,\n image_fit: 'fit',\n margin: 36,\n },\n\n file_button: {\n icon_size: 24,\n icon_color: '#6b7280',\n icon_color_hover: '#374151',\n icon_color_with_files: '#3b82f6',\n badge_background: '#3b82f6',\n badge_text_color: '#ffffff',\n },\n};\n","/**\n * PDF Saver Utility\n * Saves annotations directly into PDF documents using pdf-lib\n * This allows annotations to be embedded in the PDF file itself\n */\n\nimport type { PdfAnnotation, PdfViewerConfig } from '../types';\nimport { default_config } from '../config/default_config';\n\n/**\n * Save annotations into a PDF document\n * This function fetches the PDF, adds annotations, and downloads the modified PDF\n * @param pdf_url - URL of the PDF file\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n * @returns Promise that resolves when the PDF is saved\n */\nexport async function save_annotations_to_pdf(\n pdf_url: string,\n annotations: PdfAnnotation[],\n _output_filename?: string, // Currently unused, kept for API compatibility\n config?: PdfViewerConfig | null\n): Promise<Uint8Array> {\n try {\n // Dynamically import pdf-lib\n const { PDFDocument, rgb } = await import('pdf-lib');\n \n // Fetch the original PDF\n console.log('[PDF Saver] Fetching PDF from:', pdf_url);\n const pdf_response = await fetch(pdf_url);\n if (!pdf_response.ok) {\n throw new Error(`Failed to fetch PDF: ${pdf_response.status} ${pdf_response.statusText}`);\n }\n \n const pdf_bytes = await pdf_response.arrayBuffer();\n console.log('[PDF Saver] PDF fetched, size:', pdf_bytes.byteLength, 'bytes');\n \n // Load the PDF document\n const pdf_doc = await PDFDocument.load(pdf_bytes);\n console.log('[PDF Saver] PDF loaded, pages:', pdf_doc.getPageCount());\n \n // Get config values or use defaults\n const fonts_config = config?.fonts || default_config.fonts;\n const highlight_config = config?.highlight_annotation || default_config.highlight_annotation;\n const square_config = config?.square_annotation || default_config.square_annotation;\n const freetext_config = config?.freetext_annotation || default_config.freetext_annotation;\n \n // Add annotations to each page\n for (const annotation of annotations) {\n if (annotation.page_index >= pdf_doc.getPageCount()) {\n console.warn(`[PDF Saver] Annotation ${annotation.id} references page ${annotation.page_index}, but PDF only has ${pdf_doc.getPageCount()} pages. Skipping.`);\n continue;\n }\n \n const page = pdf_doc.getPage(annotation.page_index);\n const [x1, y1, x2, y2] = annotation.rect;\n \n // PDF coordinate system: bottom-left is origin (pdfjs-dist)\n // pdf-lib uses bottom-left as origin too, so coordinates should be fine\n // But we need to ensure rect is normalized\n const rect_x = Math.min(x1, x2);\n const rect_y = Math.min(y1, y2);\n const rect_width = Math.abs(x2 - x1);\n const rect_height = Math.abs(y2 - y1);\n \n // Parse color (hex or rgb to RGB for pdf-lib)\n // Supports both hex (#RRGGBB) and rgb(r, g, b) formats\n let color = rgb(0, 0, 0); // Default black\n if (annotation.color) {\n const color_str = annotation.color.trim();\n \n // Handle rgb(r, g, b) format\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = color_str.match(rgb_pattern);\n if (rgb_match) {\n const r = parseInt(rgb_match[1], 10);\n const g = parseInt(rgb_match[2], 10);\n const b = parseInt(rgb_match[3], 10);\n // Validate RGB values (0-255) and convert to 0-1 range for pdf-lib\n if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {\n color = rgb(r / 255, g / 255, b / 255);\n } else {\n console.warn(`[PDF Saver] Invalid RGB values for annotation ${annotation.id}: r=${r}, g=${g}, b=${b}`);\n }\n } else if (color_str.startsWith('#')) {\n // Handle hex format (#RRGGBB)\n const hex = color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n color = rgb(r, g, b);\n } else {\n console.warn(`[PDF Saver] Invalid hex color format for annotation ${annotation.id}: ${color_str}`);\n }\n } else {\n console.warn(`[PDF Saver] Unrecognized color format for annotation ${annotation.id}: ${color_str}`);\n }\n }\n \n // Create annotation based on type using pdf-lib's annotation methods\n try {\n switch (annotation.type) {\n case 'Square': {\n // Create a rectangle/square annotation\n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n borderColor: color,\n borderWidth: 2,\n borderOpacity: 0.8,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n const comment_color_str = (annotation.color || square_config.square_border_color).trim();\n let comment_r = 0, comment_g = 0, comment_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = comment_color_str.match(rgb_pattern);\n if (rgb_match) {\n comment_r = parseInt(rgb_match[1], 10) / 255;\n comment_g = parseInt(rgb_match[2], 10) / 255;\n comment_b = parseInt(rgb_match[3], 10) / 255;\n } else if (comment_color_str.startsWith('#')) {\n const hex = comment_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n comment_r = parseInt(hex.substring(0, 2), 16) / 255;\n comment_g = parseInt(hex.substring(2, 4), 16) / 255;\n comment_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(comment_r, comment_g, comment_b),\n });\n }\n break;\n }\n \n case 'Highlight': {\n // Create a highlight annotation (semi-transparent rectangle)\n const highlight_color_str = (annotation.color || highlight_config.highlight_fill_color).trim();\n let highlight_r = 255 / 255, highlight_g = 255 / 255, highlight_b = 0 / 255; // Default yellow\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = highlight_color_str.match(rgb_pattern);\n if (rgb_match) {\n highlight_r = parseInt(rgb_match[1], 10) / 255;\n highlight_g = parseInt(rgb_match[2], 10) / 255;\n highlight_b = parseInt(rgb_match[3], 10) / 255;\n } else if (highlight_color_str.startsWith('#')) {\n const hex = highlight_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n highlight_r = parseInt(hex.substring(0, 2), 16) / 255;\n highlight_g = parseInt(hex.substring(2, 4), 16) / 255;\n highlight_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n const highlight_color = rgb(highlight_r, highlight_g, highlight_b);\n \n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n color: highlight_color,\n opacity: highlight_config.highlight_fill_opacity,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(0, 0, 0),\n });\n }\n break;\n }\n \n case 'FreeText': {\n // Create a free text annotation\n if (annotation.contents) {\n // Text color priority: annotation.color > freetext_text_color > font_foreground_color > default black\n const text_color_str = (annotation.color || \n freetext_config.freetext_text_color || \n fonts_config.font_foreground_color || \n '#000000').trim();\n let text_r = 0, text_g = 0, text_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = text_color_str.match(rgb_pattern);\n if (rgb_match) {\n text_r = parseInt(rgb_match[1], 10) / 255;\n text_g = parseInt(rgb_match[2], 10) / 255;\n text_b = parseInt(rgb_match[3], 10) / 255;\n } else if (text_color_str.startsWith('#')) {\n const hex = text_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n text_r = parseInt(hex.substring(0, 2), 16) / 255;\n text_g = parseInt(hex.substring(2, 4), 16) / 255;\n text_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y,\n size: fonts_config.freetext_font_size_default,\n color: rgb(text_r, text_g, text_b),\n maxWidth: rect_width,\n });\n }\n break;\n }\n \n default:\n console.warn(`[PDF Saver] Unsupported annotation type: ${annotation.type}`);\n }\n } catch (annotation_error) {\n console.error(`[PDF Saver] Error adding annotation ${annotation.id}:`, annotation_error);\n // Continue with other annotations\n }\n }\n \n // Save the PDF\n const modified_pdf_bytes = await pdf_doc.save();\n console.log('[PDF Saver] PDF modified, size:', modified_pdf_bytes.length, 'bytes');\n \n return modified_pdf_bytes;\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error && \n typeof error.message === 'string' && error.message.includes('pdf-lib')) {\n throw new Error('pdf-lib is required to save annotations to PDF. Please install it: npm install pdf-lib');\n }\n console.error('[PDF Saver] Error saving PDF:', error);\n throw error;\n }\n}\n\n/**\n * Download PDF bytes as a file\n * @param pdf_bytes - PDF file bytes\n * @param filename - Name for the downloaded file\n */\nexport function download_pdf(pdf_bytes: Uint8Array, filename: string): void {\n // Create a new ArrayBuffer view to ensure compatibility with Blob constructor\n // Uint8Array.buffer can be SharedArrayBuffer, which Blob doesn't accept directly\n const buffer = new Uint8Array(pdf_bytes).buffer;\n const blob = new Blob([buffer], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * Save annotations to PDF and download\n * @param pdf_url - URL of the PDF file\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n */\nexport async function save_and_download_pdf(\n pdf_url: string,\n annotations: PdfAnnotation[],\n output_filename?: string,\n config?: PdfViewerConfig | null\n): Promise<void> {\n const pdf_bytes = await save_annotations_to_pdf(pdf_url, annotations, output_filename, config);\n \n // Generate output filename\n const original_filename = pdf_url.split('/').pop() || 'document.pdf';\n const filename_without_ext = original_filename.replace(/\\.pdf$/i, '');\n const final_filename = output_filename || `${filename_without_ext}_annotated.pdf`;\n \n // Download the modified PDF\n download_pdf(pdf_bytes, final_filename);\n console.log('[PDF Saver] PDF saved as:', final_filename);\n}\n\n"],"mappings":"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","names":[]}
|