zynx-pdf 0.1.2 → 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/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2026 Hafiz Muhammad Zunnoorain.
4
+
5
+ Zynx PDF is proprietary software. This software may not be copied, modified, distributed, sublicensed, resold, or used for commercial purposes without written permission from the copyright holder.
6
+
7
+ This project uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
package/README.md CHANGED
@@ -1,20 +1,16 @@
1
1
  # Zynx PDF
2
2
 
3
- **Zynx PDF** is a modern React PDF viewer and editor for web applications. It is built on top of **Mozilla PDF.js** for PDF rendering and **pdf-lib** for PDF export and editing operations.
3
+ **Zynx PDF** is a modern React PDF viewer and editor built with **Mozilla PDF.js** and **pdf-lib**.
4
4
 
5
5
  Developed by **Hafiz Muhammad Zunnoorain**.
6
6
 
7
- ---
8
-
9
7
  ## Install
10
8
 
11
9
  ```bash
12
10
  npm install zynx-pdf
13
11
  ```
14
12
 
15
- ---
16
-
17
- ## Basic Usage
13
+ ## Frontend usage
18
14
 
19
15
  ```tsx
20
16
  import { PdfEditor } from "zynx-pdf";
@@ -24,117 +20,113 @@ export default function App() {
24
20
  return (
25
21
  <PdfEditor
26
22
  height="100vh"
27
- onSave={(pdfBytes, annotations) => {
28
- console.log("Saved PDF:", pdfBytes);
29
- console.log("Annotations:", annotations);
30
- }}
23
+ licenseKey={import.meta.env.VITE_ZYNX_LICENSE_KEY}
24
+ licenseApiUrl={import.meta.env.VITE_ZYNX_LICENSE_API_URL}
25
+ engineApiUrl={import.meta.env.VITE_ZYNX_ENGINE_URL}
26
+ showProTools
27
+ autoFocusOnUpload
31
28
  />
32
29
  );
33
30
  }
34
31
  ```
35
32
 
36
- ---
33
+ ## Local test license
37
34
 
38
- ## Features
35
+ ```env
36
+ VITE_ZYNX_LICENSE_KEY=zpx_test_9F2D-7KLA-ZYNX-PRO-2026
37
+ VITE_ZYNX_LICENSE_API_URL=https://cyranix-lab-be-production.up.railway.app/api/zynx/license/validate
38
+ VITE_ZYNX_ENGINE_URL=http://localhost:5050
39
+ ```
39
40
 
40
- - PDF upload and viewing
41
- - Page navigation
42
- - Zoom in and zoom out
43
- - Add new text
44
- - Visually replace existing PDF text
45
- - Add highlights
46
- - Freehand drawing
47
- - Add images
48
- - Add signatures
49
- - Select, move, resize, and delete edits
50
- - Undo and redo support
51
- - Export edited PDF
52
- - TypeScript support
53
- - React component API
54
- - Clean purple SaaS-style editor UI
41
+ ## Frontend dev
42
+
43
+ ```bash
44
+ npm install
45
+ npm run dev
46
+ ```
55
47
 
56
- ---
48
+ ## Backend engine dev
57
49
 
58
- ## Existing Text Editing
50
+ The included backend engine provides local license validation, MongoDB storage, and a server-side PDF text edit endpoint.
59
51
 
60
- Zynx PDF supports **visual text replacement**.
52
+ Local MongoDB URI:
61
53
 
62
- This means when you edit existing PDF text:
54
+ ```env
55
+ MONGODB_URI=mongodb://127.0.0.1:27017/zynx_pdf
56
+ ```
63
57
 
64
- 1. The original text area is visually covered.
65
- 2. New text is placed on top.
66
- 3. The final exported PDF looks edited.
58
+ Install backend dependencies:
67
59
 
68
- This is the practical frontend-only method for browser-based PDF editing.
60
+ ```bash
61
+ npm install --prefix server
62
+ ```
69
63
 
70
- > Note: True internal PDF text stream editing is not currently supported. Scanned image PDFs require OCR.
64
+ Run backend:
71
65
 
72
- ---
66
+ ```bash
67
+ npm run dev:server
68
+ ```
73
69
 
74
- ## Component Props
70
+ Run frontend and backend together:
75
71
 
76
- ```tsx
77
- <PdfEditor
78
- file={null}
79
- height="100vh"
80
- defaultScale={1}
81
- enableUpload={true}
82
- showDevJson={false}
83
- onSave={(pdfBytes, annotations) => {}}
84
- onAnnotationsChange={(annotations) => {}}
85
- />
72
+ ```bash
73
+ npm run dev:all
86
74
  ```
87
75
 
88
- | Prop | Type | Description |
89
- |---|---|---|
90
- | `file` | `File \| string \| ArrayBuffer \| Uint8Array \| null` | Optional PDF file source |
91
- | `height` | `string \| number` | Editor height |
92
- | `defaultScale` | `number` | Initial zoom scale |
93
- | `enableUpload` | `boolean` | Show or hide upload option |
94
- | `showDevJson` | `boolean` | Show developer JSON panel |
95
- | `onSave` | `function` | Called when PDF is exported |
96
- | `onAnnotationsChange` | `function` | Called when annotations change |
76
+ ## Features
97
77
 
98
- ---
78
+ ### Free tools
99
79
 
100
- ## Example with Theme
80
+ - PDF upload and viewing
81
+ - Page navigation
82
+ - Zoom in and zoom out
83
+ - Add text
84
+ - Highlight
85
+ - Freehand drawing
86
+ - Add image
87
+ - Add signature
88
+ - Undo and redo
89
+ - Export edited PDF
101
90
 
102
- ```tsx
103
- import { PdfEditor } from "zynx-pdf";
104
- import "zynx-pdf/style.css";
91
+ ### Pro gated tools
105
92
 
106
- export default function App() {
107
- return (
108
- <PdfEditor
109
- height="90vh"
110
- theme={{
111
- primary: "#6d5dfc",
112
- background: "#f6f3ff",
113
- surface: "#ffffff",
114
- border: "#e4def8",
115
- text: "#16142f"
116
- }}
117
- />
118
- );
119
- }
120
- ```
93
+ - True Text Edit with Advanced Engine v1
94
+ - Visual Replace Text fallback
95
+ - Watermark
96
+ - Stamp
97
+ - Redaction box
98
+ - Page tools
99
+ - Merge PDFs
100
+ - Split PDF
101
+ - Crop page
102
+ - Forms
103
+ - OCR slot
104
+ - Compression slot
105
+ - Password protection slot
106
+ - White-label slot
107
+
108
+ ## Advanced Engine v1 note
109
+
110
+ The **True Text Edit** tool does not create a frontend overlay layer. It sends the selected text to the backend engine. Advanced Engine v1 tries to decode the page content stream, find the matching `Tj` or `TJ` text operator, remove that original operator, and insert the updated text into the PDF.
111
+
112
+ Supported in v1: literal strings, hex strings, basic escaped strings, basic `TJ` arrays, basic `ToUnicode` CMap decoding, and coordinate-assisted matching.
121
113
 
122
- ---
114
+ If the engine cannot locate editable text in the content stream, it returns a clear error and does not fake a visual layer. Use `/api/pdf/debug-text-spans` to inspect how the page text is stored.
123
115
 
124
- ## Keyboard Shortcuts
116
+ ## Build library
125
117
 
126
- | Shortcut | Action |
127
- |---|---|
128
- | `Ctrl + Z` | Undo |
129
- | `Ctrl + Y` | Redo |
130
- | `Ctrl + Shift + Z` | Redo |
131
- | `Ctrl + S` | Export PDF |
132
- | `Delete` | Delete selected edit |
118
+ ```bash
119
+ npm run build:lib
120
+ ```
121
+
122
+ ## Publish update
133
123
 
134
- ---
124
+ ```bash
125
+ npm run release
126
+ ```
135
127
 
136
128
  ## License
137
129
 
138
130
  Zynx PDF is proprietary software.
139
131
 
140
- This package uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
132
+ This project uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
@@ -0,0 +1,19 @@
1
+ import type { TextReplaceAnnotation, TrueTextEditDraft } from '../types/annotations';
2
+ export declare const ENGINE_API_URL_LOCAL = "https://cyranix-lab-be-production.up.railway.app";
3
+ export declare const ENGINE_API_URL_LIVE = "https://cyranix-lab-be-production.up.railway.app";
4
+ type EngineTextEditPayload = TextReplaceAnnotation | TrueTextEditDraft;
5
+ type ApplyTrueTextEditArgs = {
6
+ engineApiUrl?: string;
7
+ licenseKey?: string;
8
+ originalBytes: Uint8Array;
9
+ annotation: EngineTextEditPayload;
10
+ };
11
+ type DebugTextSpansArgs = {
12
+ engineApiUrl?: string;
13
+ licenseKey?: string;
14
+ originalBytes: Uint8Array;
15
+ pageIndex: number;
16
+ };
17
+ export declare function applyTrueTextEditWithEngine({ engineApiUrl, licenseKey, originalBytes, annotation }: ApplyTrueTextEditArgs): Promise<Uint8Array>;
18
+ export declare function debugTextSpansWithEngine({ engineApiUrl, licenseKey, originalBytes, pageIndex }: DebugTextSpansArgs): Promise<any>;
19
+ export {};
@@ -1,4 +1,4 @@
1
- import type { AnnotationPatch, PdfAnnotation, PdfTextItem, PdfTool } from '../types/annotations';
1
+ import type { AnnotationPatch, PdfAnnotation, PdfTextItem, PdfTool, TrueTextEditDraft } from '../types/annotations';
2
2
  type PendingImage = {
3
3
  type: 'image' | 'signature';
4
4
  dataUrl: string;
@@ -23,6 +23,12 @@ type AnnotationLayerProps = {
23
23
  onCommitHistoryTransaction: () => void;
24
24
  onCancelHistoryTransaction: () => void;
25
25
  onSelect: (id: string | null) => void;
26
+ onTrueTextItemSelect?: (item: PdfTextItem) => void;
27
+ trueTextDraft?: TrueTextEditDraft | null;
28
+ onUpdateTrueTextDraft?: (patch: Partial<TrueTextEditDraft>) => void;
29
+ onCommitTrueTextDraft?: (draft: TrueTextEditDraft) => void;
30
+ onClearTrueTextDraft?: () => void;
31
+ isApplyingTrueTextEdit?: boolean;
26
32
  };
27
33
  export declare function AnnotationLayer(props: AnnotationLayerProps): import("react").JSX.Element;
28
34
  export {};
@@ -1,3 +1,3 @@
1
1
  import type { PdfEditorProps } from '../types/annotations';
2
2
  import '../styles.css';
3
- export declare function PdfEditor({ file, height, defaultScale, enableUpload, showDevJson, theme, onSave, onAnnotationsChange }: PdfEditorProps): import("react").JSX.Element;
3
+ export declare function PdfEditor({ file, height, defaultScale, enableUpload, showDevJson, theme, licenseKey, licenseApiUrl, engineApiUrl, preferBackendTextEdit, showProTools, autoFocusOnUpload, onSave, onAnnotationsChange, onLicenseChange }: PdfEditorProps): import("react").JSX.Element;
@@ -1,9 +1,19 @@
1
- import type { AnnotationPatch, PdfAnnotation } from '../types/annotations';
1
+ import type { AnnotationPatch, PdfAnnotation, TextReplaceAnnotation, TrueTextEditDraft } from '../types/annotations';
2
2
  type PropertiesPanelProps = {
3
3
  annotation: PdfAnnotation | null;
4
+ trueTextDraft?: TrueTextEditDraft | null;
4
5
  onUpdate: (id: string, patch: AnnotationPatch, recordHistory?: boolean) => void;
5
6
  onDelete: () => void;
7
+ onDuplicate: () => void;
6
8
  onClose?: () => void;
9
+ canApplyBackendTextEdit?: boolean;
10
+ isApplyingBackendTextEdit?: boolean;
11
+ onApplyBackendTextEdit?: (annotation: TextReplaceAnnotation) => void;
12
+ onUpdateTrueTextDraft?: (patch: Partial<TrueTextEditDraft>) => void;
13
+ onApplyTrueTextDraft?: (draft: TrueTextEditDraft) => void;
14
+ onDebugTrueTextDraft?: (draft: TrueTextEditDraft) => void;
15
+ onClearTrueTextDraft?: () => void;
16
+ engineStatus?: string;
7
17
  };
8
- export declare function PropertiesPanel({ annotation, onUpdate, onDelete, onClose }: PropertiesPanelProps): import("react").JSX.Element | null;
18
+ export declare function PropertiesPanel({ annotation, trueTextDraft, onUpdate, onDelete, onDuplicate, onClose, canApplyBackendTextEdit, isApplyingBackendTextEdit, onApplyBackendTextEdit, onUpdateTrueTextDraft, onApplyTrueTextDraft, onDebugTrueTextDraft, onClearTrueTextDraft, engineStatus }: PropertiesPanelProps): import("react").JSX.Element | null;
9
19
  export {};
@@ -0,0 +1,24 @@
1
+ import type { PageAction } from '../utils/pdfPageTools';
2
+ import type { PdfFeature, PdfTool, ZynxLicenseState } from '../types/annotations';
3
+ type ToolSidebarProps = {
4
+ tool: PdfTool;
5
+ defaultText: string;
6
+ showProTools: boolean;
7
+ licenseState: ZynxLicenseState;
8
+ pageIndex: number;
9
+ pageCount: number;
10
+ canUseDocument: boolean;
11
+ processingTool: PdfTool | 'pageAction' | 'engineTextEdit' | null;
12
+ onToolChange: (tool: PdfTool) => void;
13
+ onLockedToolClick: (tool: PdfTool, feature: PdfFeature) => void;
14
+ onDefaultTextChange: (text: string) => void;
15
+ onUploadImage: (file: File, type: 'image' | 'signature') => void;
16
+ onMergePdfs: (files: File[]) => void;
17
+ onSplitCurrentPage: () => void;
18
+ onPageAction: (action: PageAction) => void;
19
+ onCompressPdf: () => void;
20
+ collapsed?: boolean;
21
+ onToggleCollapsed?: () => void;
22
+ };
23
+ export declare function ToolSidebar(props: ToolSidebarProps): import("react").JSX.Element;
24
+ export {};
@@ -1,26 +1,24 @@
1
- import type { PdfTool } from '../types/annotations';
2
1
  type ToolbarProps = {
3
- tool: PdfTool;
4
2
  scale: number;
5
3
  pageIndex: number;
6
4
  pageCount: number;
7
- defaultText: string;
8
5
  canExport: boolean;
9
6
  canUndo: boolean;
10
7
  canRedo: boolean;
11
8
  enableUpload: boolean;
12
- onToolChange: (tool: PdfTool) => void;
9
+ isFocusMode: boolean;
10
+ isProActive: boolean;
11
+ isLicenseLoading: boolean;
12
+ licenseStatusLabel: string;
13
13
  onScaleChange: (scale: number) => void;
14
14
  onPageChange: (pageIndex: number) => void;
15
- onDefaultTextChange: (text: string) => void;
16
15
  onUploadPdf: (file: File) => void;
17
- onUploadImage: (file: File, type: 'image' | 'signature') => void;
18
- onDeleteSelected: () => void;
19
16
  onUndo: () => void;
20
17
  onRedo: () => void;
21
18
  onExport: () => void;
22
- selectedId?: string | null;
19
+ onEnterFocusMode: () => void;
20
+ onExitFocusMode: () => void;
21
+ onOpenLicenseModal: () => void;
23
22
  };
24
- declare function fileToDataUrl(file: File): Promise<string>;
25
23
  export declare function Toolbar(props: ToolbarProps): import("react").JSX.Element;
26
- export { fileToDataUrl };
24
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,6 +2,10 @@ export { PdfEditor } from './components/PdfEditor';
2
2
  export { Toolbar } from './components/Toolbar';
3
3
  export { AnnotationLayer } from './components/AnnotationLayer';
4
4
  export { PdfCanvas } from './components/PdfCanvas';
5
- export type { PdfAnnotation, PdfEditorProps, PdfEditorTheme, PdfPoint, PdfTool, TextAnnotation, TextReplaceAnnotation, PdfTextItem, HighlightAnnotation, ImageAnnotation, DrawAnnotation } from './types/annotations';
5
+ export type { PdfAnnotation, PdfEditorProps, PdfEditorTheme, PdfFeature, PdfPoint, PdfTool, ZynxLicensePlan, ZynxLicenseState, ZynxLicenseStatus, TextAnnotation, TextReplaceAnnotation, PdfTextItem, HighlightAnnotation, ImageAnnotation, DrawAnnotation, WatermarkAnnotation, StampAnnotation, RedactionAnnotation, CropAnnotation, FormTextAnnotation, FormCheckboxAnnotation } from './types/annotations';
6
+ export { FREE_FEATURES, PRO_FEATURES, ZYNX_TEST_LICENSE_KEY, getToolFeature, hasFeature, validateZynxLicense } from './utils/license';
6
7
  export { exportPdfWithAnnotations } from './utils/pdfExport';
7
8
  export { downloadBytes } from './utils/file';
9
+ export { mergePdfFiles, extractSinglePage, applyPageAction, optimizePdfBytes } from './utils/pdfPageTools';
10
+ export type { PageAction } from './utils/pdfPageTools';
11
+ export { applyTrueTextEditWithEngine } from './api/engineClient';
@@ -1,4 +1,15 @@
1
- export type PdfTool = 'select' | 'replaceText' | 'text' | 'highlight' | 'draw' | 'image' | 'signature';
1
+ export type PdfFeature = 'basic_edit' | 'advanced_text' | 'true_text_edit' | 'page_tools' | 'watermark' | 'stamps' | 'forms' | 'redaction' | 'ocr' | 'compression' | 'white_label';
2
+ export type PdfTool = 'select' | 'replaceText' | 'trueTextEdit' | 'text' | 'highlight' | 'draw' | 'image' | 'signature' | 'watermark' | 'stamp' | 'redaction' | 'pageTools' | 'forms' | 'formText' | 'formCheckbox' | 'ocr' | 'compress' | 'merge' | 'split' | 'crop' | 'password' | 'whiteLabel';
3
+ export type ZynxLicensePlan = 'free' | 'pro' | 'enterprise';
4
+ export type ZynxLicenseStatus = 'loading' | 'free' | 'valid' | 'invalid' | 'expired';
5
+ export type ZynxLicenseState = {
6
+ status: ZynxLicenseStatus;
7
+ plan: ZynxLicensePlan;
8
+ licenseKey?: string;
9
+ features: PdfFeature[];
10
+ message?: string;
11
+ expiresAt?: string;
12
+ };
2
13
  export type PdfPoint = {
3
14
  x: number;
4
15
  y: number;
@@ -12,6 +23,21 @@ export type PdfTextItem = {
12
23
  width: number;
13
24
  height: number;
14
25
  fontSize: number;
26
+ fontFamily?: string;
27
+ fontName?: string;
28
+ };
29
+ export type TrueTextEditDraft = {
30
+ sourceTextId: string;
31
+ pageIndex: number;
32
+ originalText: string;
33
+ text: string;
34
+ x: number;
35
+ y: number;
36
+ width: number;
37
+ height: number;
38
+ fontSize: number;
39
+ fontFamily?: string;
40
+ fontName?: string;
15
41
  };
16
42
  export type BaseAnnotation = {
17
43
  id: string;
@@ -26,14 +52,17 @@ export type TextAnnotation = BaseAnnotation & {
26
52
  text: string;
27
53
  fontSize: number;
28
54
  color: string;
55
+ fontFamily?: string;
29
56
  };
30
57
  export type TextReplaceAnnotation = BaseAnnotation & {
31
58
  type: 'text-replace';
59
+ sourceTextId?: string;
32
60
  originalText: string;
33
61
  text: string;
34
62
  fontSize: number;
35
63
  color: string;
36
64
  backgroundColor: string;
65
+ fontFamily?: string;
37
66
  };
38
67
  export type HighlightAnnotation = BaseAnnotation & {
39
68
  type: 'highlight';
@@ -50,21 +79,73 @@ export type DrawAnnotation = BaseAnnotation & {
50
79
  color: string;
51
80
  strokeWidth: number;
52
81
  };
53
- export type PdfAnnotation = TextAnnotation | TextReplaceAnnotation | HighlightAnnotation | ImageAnnotation | DrawAnnotation;
82
+ export type WatermarkAnnotation = BaseAnnotation & {
83
+ type: 'watermark';
84
+ text: string;
85
+ fontSize: number;
86
+ color: string;
87
+ opacity: number;
88
+ rotation: number;
89
+ fontFamily?: string;
90
+ };
91
+ export type StampAnnotation = BaseAnnotation & {
92
+ type: 'stamp';
93
+ text: string;
94
+ fontSize: number;
95
+ color: string;
96
+ backgroundColor: string;
97
+ opacity: number;
98
+ };
99
+ export type RedactionAnnotation = BaseAnnotation & {
100
+ type: 'redaction';
101
+ color: string;
102
+ opacity: number;
103
+ };
104
+ export type CropAnnotation = BaseAnnotation & {
105
+ type: 'crop';
106
+ borderColor: string;
107
+ backgroundColor: string;
108
+ opacity: number;
109
+ };
110
+ export type FormTextAnnotation = BaseAnnotation & {
111
+ type: 'form-text';
112
+ name: string;
113
+ value: string;
114
+ fontSize: number;
115
+ color: string;
116
+ backgroundColor: string;
117
+ borderColor: string;
118
+ };
119
+ export type FormCheckboxAnnotation = BaseAnnotation & {
120
+ type: 'form-checkbox';
121
+ name: string;
122
+ checked: boolean;
123
+ color: string;
124
+ backgroundColor: string;
125
+ borderColor: string;
126
+ };
127
+ export type PdfAnnotation = TextAnnotation | TextReplaceAnnotation | HighlightAnnotation | ImageAnnotation | DrawAnnotation | WatermarkAnnotation | StampAnnotation | RedactionAnnotation | CropAnnotation | FormTextAnnotation | FormCheckboxAnnotation;
54
128
  export type AnnotationPatch = Partial<{
55
129
  x: number;
56
130
  y: number;
57
131
  width: number;
58
132
  height: number;
59
133
  text: string;
134
+ sourceTextId: string;
60
135
  originalText: string;
61
136
  fontSize: number;
137
+ fontFamily: string;
62
138
  color: string;
63
139
  backgroundColor: string;
140
+ borderColor: string;
64
141
  opacity: number;
65
142
  dataUrl: string;
66
143
  points: PdfPoint[];
67
144
  strokeWidth: number;
145
+ rotation: number;
146
+ name: string;
147
+ value: string;
148
+ checked: boolean;
68
149
  }>;
69
150
  export type PdfEditorTheme = {
70
151
  primary?: string;
@@ -80,6 +161,13 @@ export type PdfEditorProps = {
80
161
  enableUpload?: boolean;
81
162
  showDevJson?: boolean;
82
163
  theme?: PdfEditorTheme;
164
+ licenseKey?: string;
165
+ licenseApiUrl?: string;
166
+ engineApiUrl?: string;
167
+ preferBackendTextEdit?: boolean;
168
+ showProTools?: boolean;
169
+ autoFocusOnUpload?: boolean;
83
170
  onSave?: (pdfBytes: Uint8Array, annotations: PdfAnnotation[]) => void;
84
171
  onAnnotationsChange?: (annotations: PdfAnnotation[]) => void;
172
+ onLicenseChange?: (license: ZynxLicenseState) => void;
85
173
  };
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_ENGINE_API_URL = "https://cyranix-lab-be-production.up.railway.app";
2
+ export declare const DEFAULT_LICENSE_API_URL = "https://cyranix-lab-be-production.up.railway.app/api/zynx/license/validate";
@@ -0,0 +1,9 @@
1
+ import type { PdfFeature, PdfTool, ZynxLicenseState } from '../types/annotations';
2
+ export declare const ZYNX_TEST_LICENSE_KEY = "zpx_test_9F2D-7KLA-ZYNX-PRO-2026";
3
+ export declare const FREE_FEATURES: PdfFeature[];
4
+ export declare const PRO_FEATURES: PdfFeature[];
5
+ export declare const FREE_LICENSE_STATE: ZynxLicenseState;
6
+ export declare const TEST_PRO_LICENSE_STATE: ZynxLicenseState;
7
+ export declare function getToolFeature(tool: PdfTool): PdfFeature | null;
8
+ export declare function hasFeature(license: ZynxLicenseState, feature: PdfFeature | null | undefined): boolean;
9
+ export declare function validateZynxLicense(licenseKey?: string, licenseApiUrl?: string): Promise<ZynxLicenseState>;
@@ -0,0 +1,8 @@
1
+ export type PageAction = 'rotate' | 'delete' | 'duplicate' | 'insertBlank';
2
+ export declare function mergePdfFiles(currentBytes: Uint8Array, files: File[]): Promise<Uint8Array>;
3
+ export declare function extractSinglePage(currentBytes: Uint8Array, pageIndex: number): Promise<Uint8Array>;
4
+ export declare function applyPageAction(currentBytes: Uint8Array, pageIndex: number, action: PageAction): Promise<{
5
+ bytes: Uint8Array;
6
+ pageIndex: number;
7
+ }>;
8
+ export declare function optimizePdfBytes(currentBytes: Uint8Array): Promise<Uint8Array>;
package/dist/zynx-pdf.css CHANGED
@@ -1,2 +1,2 @@
1
- :root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.mpe-root{--mpe-primary:#6d5dfc;--mpe-primary-dark:#28245f;--mpe-primary-soft:#f1efff;--mpe-background:#f6f3ff;--mpe-surface:#fff;--mpe-border:#e4def8;--mpe-text:#16142f;--mpe-muted:#746f91;--mpe-shadow:0 24px 70px #32238c2e;background:radial-gradient(circle at top left, #8168ff29, transparent 28%), linear-gradient(135deg, #fbf9ff 0%, var(--mpe-background) 42%, #eeeaff 100%);color:var(--mpe-text);box-shadow:var(--mpe-shadow);border:1px solid #6d5dfc24;border-radius:24px;flex-direction:column;display:flex;overflow:hidden}.mpe-root *{box-sizing:border-box}.mpe-toolbar{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);z-index:20;background:#ffffffdb;border-bottom:1px solid #6d5dfc21;align-items:center;gap:14px;min-height:78px;padding:12px 14px;display:flex;position:relative}.mpe-toolbar__brand{align-items:center;gap:11px;min-width:210px;padding-right:4px;display:flex}.mpe-toolbar__logo{color:#fff;letter-spacing:.02em;background:linear-gradient(135deg,#7c5cff,#382d8e);border-radius:14px;place-items:center;width:42px;height:42px;font-size:12px;font-weight:900;display:grid;box-shadow:0 14px 30px #5c4acf3d}.mpe-toolbar__brand strong,.mpe-toolbar__brand small{display:block}.mpe-toolbar__brand strong{letter-spacing:-.01em;font-size:14px}.mpe-toolbar__brand small{max-width:280px;color:var(--mpe-muted);margin-top:2px;font-size:11px;line-height:1.35}.mpe-toolbar__section{align-items:center;gap:7px;min-width:0;display:flex}.mpe-toolbar__section--view{background:#f6f3ffb8;border:1px solid #6d5dfc24;border-radius:18px;padding:8px}.mpe-toolbar__section--edit{scrollbar-width:thin;flex:1;justify-content:center;overflow-x:auto}.mpe-toolbar__section--actions{margin-left:auto}.mpe-button,.mpe-tool-button,.mpe-icon-button{color:var(--mpe-text);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;background:#fff;border:1px solid #6d5dfc29;border-radius:13px;justify-content:center;align-items:center;gap:7px;min-height:38px;padding:9px 11px;font-size:12px;font-weight:800;transition:transform .14s,border-color .14s,background .14s,box-shadow .14s;display:inline-flex}.mpe-button:hover:not(:disabled),.mpe-tool-button:hover:not(:disabled),.mpe-icon-button:hover:not(:disabled){border-color:#6d5dfc73;transform:translateY(-1px);box-shadow:0 10px 24px #4d39b41f}.mpe-button:disabled,.mpe-tool-button:disabled,.mpe-icon-button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}.mpe-button--primary,.mpe-tool-button--active{color:#fff;background:linear-gradient(135deg,#7c5cff,#5140d7);border-color:#0000;box-shadow:0 14px 26px #5c4acf38}.mpe-button--save{padding-inline:14px}.mpe-button--danger{color:#b91c1c;background:#fff7f7;border-color:#dc262629}.mpe-icon-button{width:38px;padding:0}.mpe-icon-button--ghost{width:32px;min-height:32px;box-shadow:none;background:0 0;border-radius:10px}.mpe-page-chip{text-align:center;min-width:66px;color:var(--mpe-primary-dark);background:#fff;border:1px solid #6d5dfc24;border-radius:999px;padding:8px 10px;font-size:12px;font-weight:900}.mpe-editor-shell{flex:1;grid-template-rows:auto minmax(0,1fr);min-height:0;display:grid;position:relative}.mpe-editor-hint{min-height:40px;color:var(--mpe-muted);text-align:center;background:#ffffff80;border-bottom:1px solid #6d5dfc1a;justify-content:center;align-items:center;gap:12px;padding:8px 14px;font-size:12px;display:flex}.mpe-editor-hint strong{color:var(--mpe-primary-dark)}.mpe-stage{background:linear-gradient(90deg,#7a68ff0e 1px,#0000 1px) 0 0/32px 32px,linear-gradient(#7a68ff0e 1px,#0000 1px) 0 0/32px 32px,radial-gradient(circle at 50% 0,#fffffff2,#f4f0ffd9 42%,#e8e2ffe6);justify-content:center;align-items:flex-start;min-height:0;padding:34px;display:flex;overflow:auto}.mpe-page-shell{background:#fff;border-radius:10px;flex:none;position:relative;overflow:hidden;box-shadow:0 28px 80px #1c175240}.mpe-page-canvas{background:#fff;display:block}.mpe-render-badge,.mpe-render-error{z-index:6;border-radius:999px;max-width:calc(100% - 24px);padding:8px 10px;font-size:12px;font-weight:800;position:absolute;top:12px;left:12px}.mpe-render-badge{color:#fff;background:#1f194edb}.mpe-render-error{color:#b91c1c;background:#fff1f2;border:1px solid #fecaca}.mpe-annotation-layer{touch-action:none;z-index:3;position:absolute;inset:0;overflow:hidden}.mpe-annotation-layer--text,.mpe-annotation-layer--highlight,.mpe-annotation-layer--image,.mpe-annotation-layer--signature,.mpe-annotation-layer--replaceText{cursor:crosshair}.mpe-annotation-layer--draw{cursor:cell}.mpe-annotation-layer--select{cursor:default}.mpe-text-target{z-index:2;color:#0000;cursor:text;background:#6d5dfc0f;border:1px dashed #6d5dfc6b;border-radius:3px;margin:0;padding:0;position:absolute}.mpe-text-target span{opacity:0;pointer-events:none}.mpe-text-target:hover{background:#6d5dfc2e;border-color:#6d5dfcc7;box-shadow:0 0 0 2px #6d5dfc21}.mpe-annotation{box-sizing:border-box;cursor:move;-webkit-user-select:none;user-select:none;z-index:4;border-radius:4px;position:absolute}.mpe-annotation--selected{box-shadow:0 0 0 4px #6d5dfc26}.mpe-annotation--editing{cursor:text}.mpe-annotation-text,.mpe-annotation-replacement{width:100%;height:100%}.mpe-annotation-text{white-space:pre-wrap;pointer-events:none;justify-content:flex-start;align-items:flex-start;font-weight:650;line-height:1.15;display:flex;overflow:hidden}.mpe-annotation-replacement{border-radius:2px;padding:1px 2px;overflow:hidden}.mpe-annotation-highlight{pointer-events:none;border-radius:4px;width:100%;height:100%}.mpe-annotation-image{object-fit:contain;pointer-events:none;width:100%;height:100%}.mpe-annotation-ink{pointer-events:none;position:absolute;inset:0;overflow:visible}.mpe-annotation-textarea{resize:none;width:100%;height:100%;font:inherit;white-space:pre-wrap;pointer-events:auto;border:0;border-radius:3px;outline:0;margin:0;padding:2px;font-weight:650;line-height:1.15;display:block;overflow:auto}.mpe-resize-handle{background:var(--mpe-primary);cursor:nwse-resize;border:2px solid #fff;border-radius:999px;width:13px;height:13px;position:absolute;bottom:-7px;right:-7px;box-shadow:0 5px 14px #1e185047}.mpe-floating-inspector{z-index:30;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#fffffff5;border:1px solid #6d5dfc29;border-radius:20px;width:min(320px,100% - 36px);padding:14px;position:absolute;top:58px;right:18px;box-shadow:0 22px 60px #23196e2e}.mpe-inspector-head{justify-content:space-between;align-items:center;gap:10px;margin-bottom:12px;display:flex}.mpe-inspector-head span,.mpe-inspector-head strong{display:block}.mpe-inspector-head span{color:var(--mpe-muted);text-transform:uppercase;letter-spacing:.08em;font-size:11px;font-weight:800}.mpe-inspector-head strong{margin-top:2px;font-size:14px}.mpe-inspector-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.mpe-inspector-grid--position{margin-top:10px}.mpe-inspector-field{color:var(--mpe-muted);gap:6px;margin-bottom:10px;font-size:11px;font-weight:900;display:grid}.mpe-inspector-field--full{grid-column:1/-1}.mpe-inspector-field input,.mpe-inspector-field textarea{border:1px solid var(--mpe-border);width:100%;font:inherit;color:var(--mpe-text);background:#fff;border-radius:12px;outline:none;padding:9px 10px;font-size:13px}.mpe-inspector-field input:focus,.mpe-inspector-field textarea:focus{border-color:#6d5dfcb3;box-shadow:0 0 0 3px #6d5dfc1f}.mpe-inspector-field textarea{resize:vertical}.mpe-original-text-note{background:var(--mpe-primary-soft);color:var(--mpe-muted);border-radius:12px;margin:-2px 0 10px;padding:8px 10px;font-size:11px;line-height:1.35}.mpe-original-text-note span{color:var(--mpe-primary-dark);font-weight:800}.mpe-inspector-preview{object-fit:contain;border:1px solid var(--mpe-border);background:#faf9ff;border-radius:14px;width:100%;max-height:160px;margin-bottom:10px}.mpe-inspector-delete{width:100%;margin-top:10px}.mpe-dev-drawer{z-index:25;background:#fffffff0;border:1px solid #6d5dfc29;border-radius:16px;width:min(420px,100% - 36px);max-height:300px;padding:10px 12px;position:absolute;bottom:18px;left:18px;overflow:auto;box-shadow:0 18px 40px #23196e24}.mpe-dev-drawer summary{cursor:pointer;color:var(--mpe-primary-dark);font-weight:900}.mpe-dev-drawer pre{white-space:pre-wrap;word-break:break-word;font-size:11px}.mpe-empty-state,.mpe-error{text-align:center;background:#fffffff0;border:1px solid #6d5dfc24;border-radius:28px;width:min(620px,100%);margin:70px auto;padding:34px;box-shadow:0 24px 60px #23196e24}.mpe-empty-icon{color:#fff;background:linear-gradient(135deg,#7c5cff,#382d8e);border-radius:22px;place-items:center;width:66px;height:66px;margin:0 auto 16px;font-weight:900;display:grid;box-shadow:0 14px 30px #5c4acf38}.mpe-empty-state h2{letter-spacing:-.03em;margin:0 0 8px;font-size:clamp(24px,4vw,34px)}.mpe-empty-state p{max-width:480px;color:var(--mpe-muted);margin:0 auto 18px;line-height:1.58}.mpe-error{color:#b91c1c;background:#fff1f2;border-color:#fecaca}@media (width<=1280px){.mpe-toolbar{flex-wrap:wrap}.mpe-toolbar__brand{min-width:100%}.mpe-toolbar__section--edit{order:3;justify-content:flex-start;width:100%}}@media (width<=780px){.mpe-root{border-radius:18px}.mpe-toolbar{gap:10px}.mpe-toolbar__section--view,.mpe-toolbar__section--actions{width:100%;overflow-x:auto}.mpe-toolbar__section--actions{justify-content:flex-start}.mpe-stage{justify-content:flex-start;padding:16px}.mpe-editor-hint{text-align:left;flex-direction:column;align-items:flex-start}.mpe-floating-inspector{width:auto;top:52px;left:12px;right:12px}}
1
+ :root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.mpe-root{--mpe-primary:#6d5dfc;--mpe-primary-dark:#28245f;--mpe-primary-soft:#f1efff;--mpe-background:#f6f3ff;--mpe-surface:#fff;--mpe-border:#e4def8;--mpe-text:#16142f;--mpe-muted:#746f91;--mpe-shadow:0 24px 70px #32238c2e;background:radial-gradient(circle at top left, #8168ff29, transparent 28%), linear-gradient(135deg, #fbf9ff 0%, var(--mpe-background) 42%, #eeeaff 100%);color:var(--mpe-text);box-shadow:var(--mpe-shadow);border:1px solid #6d5dfc24;border-radius:24px;flex-direction:column;display:flex;overflow:hidden}.mpe-root *{box-sizing:border-box}.mpe-toolbar{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);z-index:20;background:#ffffffdb;border-bottom:1px solid #6d5dfc21;align-items:center;gap:14px;min-height:78px;padding:12px 14px;display:flex;position:relative}.mpe-toolbar__brand{align-items:center;gap:11px;min-width:210px;padding-right:4px;display:flex}.mpe-toolbar__logo{color:#fff;letter-spacing:.02em;background:linear-gradient(135deg,#7c5cff,#382d8e);border-radius:14px;place-items:center;width:42px;height:42px;font-size:12px;font-weight:900;display:grid;box-shadow:0 14px 30px #5c4acf3d}.mpe-toolbar__brand strong,.mpe-toolbar__brand small{display:block}.mpe-toolbar__brand strong{letter-spacing:-.01em;font-size:14px}.mpe-toolbar__brand small{max-width:280px;color:var(--mpe-muted);margin-top:2px;font-size:11px;line-height:1.35}.mpe-toolbar__section{align-items:center;gap:7px;min-width:0;display:flex}.mpe-toolbar__section--view{background:#f6f3ffb8;border:1px solid #6d5dfc24;border-radius:18px;padding:8px}.mpe-toolbar__section--edit{scrollbar-width:thin;flex:1;justify-content:center;overflow-x:auto}.mpe-toolbar__section--actions{margin-left:auto}.mpe-button,.mpe-tool-button,.mpe-icon-button{color:var(--mpe-text);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;background:#fff;border:1px solid #6d5dfc29;border-radius:13px;justify-content:center;align-items:center;gap:7px;min-height:38px;padding:9px 11px;font-size:12px;font-weight:800;transition:transform .14s,border-color .14s,background .14s,box-shadow .14s;display:inline-flex}.mpe-button:hover:not(:disabled),.mpe-tool-button:hover:not(:disabled),.mpe-icon-button:hover:not(:disabled){border-color:#6d5dfc73;transform:translateY(-1px);box-shadow:0 10px 24px #4d39b41f}.mpe-button:disabled,.mpe-tool-button:disabled,.mpe-icon-button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}.mpe-button--primary,.mpe-tool-button--active{color:#fff;background:linear-gradient(135deg,#7c5cff,#5140d7);border-color:#0000;box-shadow:0 14px 26px #5c4acf38}.mpe-button--save{padding-inline:14px}.mpe-button--danger{color:#b91c1c;background:#fff7f7;border-color:#dc262629}.mpe-icon-button{width:38px;padding:0}.mpe-icon-button--ghost{width:32px;min-height:32px;box-shadow:none;background:0 0;border-radius:10px}.mpe-page-chip{text-align:center;min-width:66px;color:var(--mpe-primary-dark);background:#fff;border:1px solid #6d5dfc24;border-radius:999px;padding:8px 10px;font-size:12px;font-weight:900}.mpe-editor-shell{flex:1;grid-template-rows:auto minmax(0,1fr);min-height:0;display:grid;position:relative}.mpe-editor-hint{min-height:40px;color:var(--mpe-muted);text-align:center;background:#ffffff80;border-bottom:1px solid #6d5dfc1a;justify-content:center;align-items:center;gap:12px;padding:8px 14px;font-size:12px;display:flex}.mpe-editor-hint strong{color:var(--mpe-primary-dark)}.mpe-stage{background:linear-gradient(90deg,#7a68ff0e 1px,#0000 1px) 0 0/32px 32px,linear-gradient(#7a68ff0e 1px,#0000 1px) 0 0/32px 32px,radial-gradient(circle at 50% 0,#fffffff2,#f4f0ffd9 42%,#e8e2ffe6);justify-content:center;align-items:flex-start;min-height:0;padding:34px;display:flex;overflow:auto}.mpe-page-shell{background:#fff;border-radius:10px;flex:none;position:relative;overflow:hidden;box-shadow:0 28px 80px #1c175240}.mpe-page-canvas{background:#fff;display:block}.mpe-render-badge,.mpe-render-error{z-index:6;border-radius:999px;max-width:calc(100% - 24px);padding:8px 10px;font-size:12px;font-weight:800;position:absolute;top:12px;left:12px}.mpe-render-badge{color:#fff;background:#1f194edb}.mpe-render-error{color:#b91c1c;background:#fff1f2;border:1px solid #fecaca}.mpe-annotation-layer{touch-action:none;z-index:3;position:absolute;inset:0;overflow:hidden}.mpe-annotation-layer--text,.mpe-annotation-layer--highlight,.mpe-annotation-layer--image,.mpe-annotation-layer--signature,.mpe-annotation-layer--replaceText{cursor:crosshair}.mpe-annotation-layer--draw{cursor:cell}.mpe-annotation-layer--select{cursor:default}.mpe-text-target{z-index:2;color:#0000;cursor:text;background:#6d5dfc0f;border:1px dashed #6d5dfc6b;border-radius:3px;margin:0;padding:0;position:absolute}.mpe-text-target span{opacity:0;pointer-events:none}.mpe-text-target:hover{background:#6d5dfc2e;border-color:#6d5dfcc7;box-shadow:0 0 0 2px #6d5dfc21}.mpe-annotation{box-sizing:border-box;cursor:move;-webkit-user-select:none;user-select:none;z-index:4;border-radius:4px;position:absolute}.mpe-annotation--selected{box-shadow:0 0 0 4px #6d5dfc26}.mpe-annotation--editing{cursor:text}.mpe-annotation-text,.mpe-annotation-replacement{width:100%;height:100%}.mpe-annotation-text{white-space:pre-wrap;pointer-events:none;justify-content:flex-start;align-items:flex-start;font-weight:650;line-height:1.15;display:flex;overflow:hidden}.mpe-annotation-highlight{pointer-events:none;border-radius:4px;width:100%;height:100%}.mpe-annotation-image{object-fit:contain;pointer-events:none;width:100%;height:100%}.mpe-annotation-ink{pointer-events:none;position:absolute;inset:0;overflow:visible}.mpe-annotation-textarea{resize:none;width:100%;height:100%;font:inherit;white-space:pre-wrap;pointer-events:auto;border:0;border-radius:3px;outline:0;margin:0;padding:2px;font-weight:650;line-height:1.15;display:block;overflow:auto}.mpe-resize-handle{background:var(--mpe-primary);cursor:nwse-resize;border:2px solid #fff;border-radius:999px;width:13px;height:13px;position:absolute;bottom:-7px;right:-7px;box-shadow:0 5px 14px #1e185047}.mpe-floating-inspector{z-index:30;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#fffffff5;border:1px solid #6d5dfc29;border-radius:20px;width:min(320px,100% - 36px);padding:14px;position:absolute;top:58px;right:18px;box-shadow:0 22px 60px #23196e2e}.mpe-inspector-head{justify-content:space-between;align-items:center;gap:10px;margin-bottom:12px;display:flex}.mpe-inspector-head span,.mpe-inspector-head strong{display:block}.mpe-inspector-head span{color:var(--mpe-muted);text-transform:uppercase;letter-spacing:.08em;font-size:11px;font-weight:800}.mpe-inspector-head strong{margin-top:2px;font-size:14px}.mpe-inspector-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.mpe-inspector-grid--position{margin-top:10px}.mpe-inspector-field{color:var(--mpe-muted);gap:6px;margin-bottom:10px;font-size:11px;font-weight:900;display:grid}.mpe-inspector-field--full{grid-column:1/-1}.mpe-inspector-field input,.mpe-inspector-field textarea{border:1px solid var(--mpe-border);width:100%;font:inherit;color:var(--mpe-text);background:#fff;border-radius:12px;outline:none;padding:9px 10px;font-size:13px}.mpe-inspector-field input:focus,.mpe-inspector-field textarea:focus{border-color:#6d5dfcb3;box-shadow:0 0 0 3px #6d5dfc1f}.mpe-inspector-field textarea{resize:vertical}.mpe-original-text-note{background:var(--mpe-primary-soft);color:var(--mpe-muted);border-radius:12px;margin:-2px 0 10px;padding:8px 10px;font-size:11px;line-height:1.35}.mpe-original-text-note span{color:var(--mpe-primary-dark);font-weight:800}.mpe-inspector-preview{object-fit:contain;border:1px solid var(--mpe-border);background:#faf9ff;border-radius:14px;width:100%;max-height:160px;margin-bottom:10px}.mpe-inspector-delete{width:100%;margin-top:10px}.mpe-dev-drawer{z-index:25;background:#fffffff0;border:1px solid #6d5dfc29;border-radius:16px;width:min(420px,100% - 36px);max-height:300px;padding:10px 12px;position:absolute;bottom:18px;left:18px;overflow:auto;box-shadow:0 18px 40px #23196e24}.mpe-dev-drawer summary{cursor:pointer;color:var(--mpe-primary-dark);font-weight:900}.mpe-dev-drawer pre{white-space:pre-wrap;word-break:break-word;font-size:11px}.mpe-empty-state,.mpe-error{text-align:center;background:#fffffff0;border:1px solid #6d5dfc24;border-radius:28px;width:min(620px,100%);margin:70px auto;padding:34px;box-shadow:0 24px 60px #23196e24}.mpe-empty-icon{color:#fff;background:linear-gradient(135deg,#7c5cff,#382d8e);border-radius:22px;place-items:center;width:66px;height:66px;margin:0 auto 16px;font-weight:900;display:grid;box-shadow:0 14px 30px #5c4acf38}.mpe-empty-state h2{letter-spacing:-.03em;margin:0 0 8px;font-size:clamp(24px,4vw,34px)}.mpe-empty-state p{max-width:480px;color:var(--mpe-muted);margin:0 auto 18px;line-height:1.58}.mpe-error{color:#b91c1c;background:#fff1f2;border-color:#fecaca}@media (width<=1280px){.mpe-toolbar{flex-wrap:wrap}.mpe-toolbar__brand{min-width:100%}.mpe-toolbar__section--edit{order:3;justify-content:flex-start;width:100%}}@media (width<=780px){.mpe-root{border-radius:18px}.mpe-toolbar{gap:10px}.mpe-toolbar__section--view,.mpe-toolbar__section--actions{width:100%;overflow-x:auto}.mpe-toolbar__section--actions{justify-content:flex-start}.mpe-stage{justify-content:flex-start;padding:16px}.mpe-editor-hint{text-align:left;flex-direction:column;align-items:flex-start}.mpe-floating-inspector{width:auto;top:52px;left:12px;right:12px}}.mpe-root--focus{z-index:9999;width:100vw;box-shadow:none;border:0;border-radius:0;position:fixed;inset:0;height:100vh!important}.mpe-root--focus .mpe-toolbar{min-height:72px}.mpe-root--focus .mpe-stage{padding:26px}.mpe-button--subtle{color:var(--mpe-primary-dark);background:#f7f4ff}.mpe-toolbar__section--edit{scrollbar-width:thin;justify-content:flex-start;padding-bottom:2px}.mpe-pro-tools{border-left:1px solid #6d5dfc29;align-items:center;gap:7px;margin-left:2px;padding-left:8px;display:inline-flex}.mpe-license-pill{color:#6b5ca4;white-space:nowrap;background:#f6f3ffe6;border:1px solid #6d5dfc24;border-radius:999px;align-items:center;gap:6px;min-height:34px;padding:7px 10px;font-size:11px;font-weight:950;display:inline-flex}.mpe-license-pill--valid{color:#166534;background:#ecfdf3;border-color:#bbf7d0}.mpe-tool-button--pro{position:relative}.mpe-tool-button--locked{color:#8278a7;background:#ffffffa3;border-style:dashed;overflow:hidden}.mpe-tool-button--locked span{filter:blur(.8px);opacity:.6}.mpe-tool-button--locked em{color:#fff;letter-spacing:.03em;background:linear-gradient(135deg,#7c5cff,#5140d7);border-radius:999px;margin-left:2px;padding:1px 6px;font-size:9px;font-style:normal;font-weight:950}.mpe-annotation-layer--watermark,.mpe-annotation-layer--stamp,.mpe-annotation-layer--redaction{cursor:crosshair}.mpe-annotation-watermark,.mpe-annotation-stamp,.mpe-annotation-redaction{pointer-events:none;width:100%;height:100%}.mpe-annotation-watermark{letter-spacing:.08em;text-transform:uppercase;transform-origin:50%;white-space:nowrap;justify-content:center;align-items:center;font-weight:950;display:flex}.mpe-annotation-stamp{letter-spacing:.1em;text-transform:uppercase;border:2px solid;border-radius:12px;place-items:center;font-weight:950;display:grid}.mpe-annotation-redaction{border-radius:2px}.mpe-modal-backdrop{z-index:100;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#16142f61;place-items:center;padding:20px;display:grid;position:absolute;inset:0}.mpe-root--focus .mpe-modal-backdrop{position:fixed}.mpe-modal-card{text-align:center;background:#fffffffa;border:1px solid #6d5dfc29;border-radius:26px;width:min(520px,100%);padding:26px;box-shadow:0 30px 90px #1a145a42}.mpe-modal-icon{color:#fff;background:linear-gradient(135deg,#7c5cff,#382d8e);border-radius:20px;place-items:center;width:58px;height:58px;margin:0 auto 14px;font-weight:950;display:grid}.mpe-modal-card h3{color:var(--mpe-text);letter-spacing:-.03em;margin:0 0 8px;font-size:22px}.mpe-modal-card p{max-width:430px;color:var(--mpe-muted);margin:0 auto 14px;line-height:1.55}.mpe-modal-card code{color:#28245f;word-break:break-all;background:#f6f3ff;border-radius:14px;margin:12px 0 16px;padding:12px;font-size:12px;display:block}.mpe-modal-card small{color:#b91c1c;margin:-6px 0 14px;display:block}@media (width<=1280px){.mpe-pro-tools{border-left:0;padding-left:0}}.mpe-toolbar{flex-wrap:nowrap}.mpe-toolbar__section--view{max-width:min(720px,52vw);margin-left:auto;overflow-x:auto}.mpe-toolbar__section--actions{flex:none}.mpe-workspace{grid-template-columns:286px minmax(0,1fr);min-height:0;display:grid;position:relative}.mpe-tool-sidebar{-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);background:radial-gradient(circle at 0 0,#7c5cff21,#0000 34%),#ffffffc7;border-right:1px solid #6d5dfc1f;grid-template-rows:auto auto minmax(0,1fr);gap:12px;min-height:0;padding:14px;display:grid;overflow:hidden}.mpe-tool-sidebar__head{justify-content:space-between;align-items:center;gap:10px;padding:8px 4px 2px;display:flex}.mpe-tool-sidebar__head span,.mpe-tool-sidebar__head strong{display:block}.mpe-tool-sidebar__head>div>span{color:var(--mpe-primary);letter-spacing:.14em;text-transform:uppercase;font-size:10px;font-weight:950}.mpe-tool-sidebar__head strong{color:var(--mpe-text);letter-spacing:-.02em;margin-top:3px;font-size:14px}.mpe-license-dot{text-align:center;color:#6b5ca4;background:#f6f3ff;border:1px solid #6d5dfc29;border-radius:999px;min-width:48px;padding:6px 9px;font-size:11px;font-weight:950}.mpe-license-dot--valid{color:#166534;background:#ecfdf3;border-color:#bbf7d0}.mpe-tool-tabs{background:#f6f3ffdb;border:1px solid #6d5dfc1f;border-radius:18px;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:4px;display:grid}.mpe-tool-tabs button{color:#675f87;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:14px;min-height:52px;padding:8px 10px;font-weight:950;transition:background .14s,box-shadow .14s,color .14s,transform .14s}.mpe-tool-tabs button:hover,.mpe-tool-tabs button.active{color:var(--mpe-primary-dark);background:#fff;transform:translateY(-1px);box-shadow:0 10px 24px #35298d1c}.mpe-tool-tabs small{color:var(--mpe-muted);margin-top:2px;font-size:10px;font-weight:800;display:block}.mpe-tool-sidebar__body{scrollbar-width:thin;min-height:0;padding:2px 2px 16px;overflow-y:auto}.mpe-tool-group{gap:8px;margin-bottom:14px;display:grid}.mpe-tool-group__title{color:#706a8f;letter-spacing:.12em;text-transform:uppercase;align-items:center;gap:6px;padding:0 3px;font-size:10px;font-weight:950;display:inline-flex}.mpe-side-tool{width:100%;min-height:62px;color:var(--mpe-text);cursor:pointer;text-align:left;background:#ffffffd6;border:1px solid #6d5dfc24;border-radius:17px;grid-template-columns:38px minmax(0,1fr) auto;align-items:center;gap:10px;padding:10px;transition:transform .14s,border-color .14s,background .14s,box-shadow .14s;display:grid;position:relative}.mpe-side-tool:hover{border-color:#6d5dfc6b;transform:translateY(-1px);box-shadow:0 14px 30px #35298d1f}.mpe-side-tool--active{background:linear-gradient(135deg,#fffffffa,#f6f3fffa);border-color:#6d5dfc94;box-shadow:0 16px 34px #35298d24}.mpe-side-tool__icon{width:38px;height:38px;color:var(--mpe-primary);background:#6d5dfc1a;border-radius:13px;place-items:center;display:grid}.mpe-side-tool--active .mpe-side-tool__icon{color:#fff;background:linear-gradient(135deg,#7c5cff,#5140d7)}.mpe-side-tool__copy{min-width:0;display:block}.mpe-side-tool__copy strong,.mpe-side-tool__copy small{display:block}.mpe-side-tool__copy strong{color:var(--mpe-text);white-space:nowrap;text-overflow:ellipsis;font-size:12px;font-weight:950;overflow:hidden}.mpe-side-tool__copy small{color:var(--mpe-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-top:2px;font-size:10.5px;line-height:1.25;display:-webkit-box;overflow:hidden}.mpe-side-tool em,.mpe-side-tool b{letter-spacing:.02em;border-radius:999px;align-self:start;padding:2px 7px;font-size:9px;font-style:normal;font-weight:950}.mpe-side-tool em{color:#fff;background:linear-gradient(135deg,#f97316,#db2777)}.mpe-side-tool b{color:#fff;background:linear-gradient(135deg,#7c5cff,#5140d7)}.mpe-side-tool--locked{background:#ffffff8c;border-style:dashed}.mpe-side-tool--locked .mpe-side-tool__copy{filter:blur(.75px);opacity:.56}.mpe-side-tool--locked .mpe-side-tool__icon{color:#7b72a3;background:#6d5dfc14}.mpe-sidebar-input{color:var(--mpe-muted);background:#ffffffb8;border:1px solid #6d5dfc1f;border-radius:18px;gap:7px;padding:12px;font-size:11px;font-weight:950;display:grid}.mpe-sidebar-input input{width:100%;color:var(--mpe-text);background:#fff;border:1px solid #6d5dfc24;border-radius:13px;outline:none;padding:10px 11px;font-weight:800}.mpe-sidebar-input input:focus{border-color:#6d5dfc9e;box-shadow:0 0 0 3px #6d5dfc1f}.mpe-pro-status{color:#6b5ca4;background:#f6f3ffe6;border:1px dashed #6d5dfc38;border-radius:18px;align-items:flex-start;gap:10px;margin-bottom:14px;padding:12px;display:flex}.mpe-pro-status svg{color:var(--mpe-primary);flex:none;margin-top:1px}.mpe-pro-status strong,.mpe-pro-status small{display:block}.mpe-pro-status strong{color:var(--mpe-primary-dark);font-size:12px}.mpe-pro-status small{margin-top:2px;font-size:10.5px;line-height:1.35}.mpe-pro-status--active{color:#166534;background:#ecfdf3;border-color:#bbf7d0}.mpe-pro-status--active svg,.mpe-pro-status--active strong{color:#166534}.mpe-workspace .mpe-stage{min-width:0}@media (width<=1280px){.mpe-toolbar{flex-wrap:wrap}.mpe-toolbar__brand{min-width:100%}.mpe-toolbar__section--view{max-width:100%;margin-left:0}.mpe-workspace{grid-template-columns:254px minmax(0,1fr)}}@media (width<=860px){.mpe-workspace{grid-template-rows:auto minmax(0,1fr);grid-template-columns:1fr}.mpe-tool-sidebar{border-bottom:1px solid #6d5dfc1f;border-right:0;max-height:310px}.mpe-tool-sidebar__body{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;display:grid}}.mpe-side-tool{grid-template-columns:42px minmax(0,1fr) auto;min-height:68px;padding:12px}.mpe-side-tool__icon{width:42px;height:42px}.mpe-side-tool__copy small{-webkit-line-clamp:2;font-size:11px}.mpe-pro-action-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.mpe-pro-action{min-height:40px;color:var(--mpe-primary-dark);cursor:pointer;background:#ffffffdb;border:1px solid #6d5dfc24;border-radius:13px;justify-content:center;align-items:center;gap:7px;font-size:11px;font-weight:900;transition:transform .14s,border-color .14s,box-shadow .14s;display:inline-flex}.mpe-pro-action:hover:not(:disabled){border-color:#6d5dfc6b;transform:translateY(-1px);box-shadow:0 12px 24px #35298d1f}.mpe-pro-action:disabled{opacity:.5;cursor:not-allowed}.mpe-pro-help{color:var(--mpe-muted);margin-top:6px;font-size:10.5px;line-height:1.35;display:block}.mpe-annotation-text{font-weight:500;line-height:1.05}.mpe-annotation-replacement{border-radius:1px;padding:0 1px;overflow:hidden}.mpe-annotation--text-replace.mpe-annotation--editing{z-index:8}.mpe-annotation--text-replace:not(.mpe-annotation--selected){box-shadow:none}.mpe-annotation-textarea{font-weight:500;line-height:1.05;box-shadow:inset 0 0 0 1px #6d5dfc6b}.mpe-annotation-crop{width:100%;height:100%;color:var(--mpe-primary);pointer-events:none;border:2px dashed;place-items:center;display:grid}.mpe-annotation-crop span{color:var(--mpe-primary-dark);background:#ffffffeb;border-radius:999px;padding:5px 9px;font-size:11px;font-weight:950}.mpe-annotation-form-text{pointer-events:none;border:1.5px solid;border-radius:5px;width:100%;height:100%;padding:6px 8px;font-weight:750;overflow:hidden}.mpe-annotation-form-checkbox{pointer-events:none;border:1.8px solid;border-radius:4px;place-items:center;width:100%;height:100%;font-weight:950;display:grid}.mpe-inspector-check{border:1px solid var(--mpe-border);color:var(--mpe-text);background:#fff;border-radius:12px;align-items:center;gap:8px;margin-bottom:10px;padding:9px 10px;font-size:12px;font-weight:850;display:flex}@media (width<=1280px){.mpe-workspace{grid-template-columns:330px minmax(0,1fr)}}@media (width<=860px){.mpe-workspace{grid-template-columns:1fr}}.mpe-annotation-layer--crop,.mpe-annotation-layer--formText,.mpe-annotation-layer--formCheckbox{cursor:crosshair}.mpe-engine-box{background:linear-gradient(135deg,#6d5dfc14,#ffffffeb);border:1px solid #6d5dfc38;border-radius:16px;gap:10px;padding:12px;display:grid}.mpe-engine-box p{color:#5f5a7c;margin:0;font-size:12px;line-height:1.45}.mpe-engine-box small{color:#8b5cf6;font-size:11px;line-height:1.35}.mpe-engine-apply{justify-content:center;width:100%}.mpe-annotation-layer--trueTextEdit{cursor:crosshair}.mpe-text-target--true{background:#0ea5e917;border-color:#0ea5e98c}.mpe-text-target--true:hover{background:#0ea5e933;border-color:#0ea5e9f2;box-shadow:0 0 0 2px #0ea5e929}.mpe-button--secondary{color:#3b3278;background:#f7f4ff;border:1px solid #6d5dfc33}.mpe-button--secondary:hover{background:#eee9ff}.mpe-engine-box--true{background:linear-gradient(135deg,#0ea5e914,#fffffff2);border-color:#0ea5e940}.mpe-engine-warning{color:#7c3aed;margin-top:10px;font-size:11px;line-height:1.4;display:block}.mpe-workspace{min-width:0;grid-template-columns:var(--mpe-left-panel-width,318px) minmax(0, 1fr) var(--mpe-right-panel-width,330px)!important}.mpe-tool-sidebar{padding:12px!important}.mpe-tool-sidebar__head-actions{align-items:center;gap:6px;display:inline-flex}.mpe-side-collapse,.mpe-inspector-collapse{width:32px;height:32px;color:var(--mpe-primary-dark);cursor:pointer;background:#ffffffd1;border:1px solid #6d5dfc29;border-radius:11px;place-items:center;font-weight:950;display:grid}.mpe-side-collapse:hover,.mpe-inspector-collapse:hover{border-color:#6d5dfc6b;box-shadow:0 10px 22px #35298d1f}.mpe-side-tool__copy strong{font-size:12px!important}.mpe-side-tool__copy small{font-size:10px!important;line-height:1.2!important}.mpe-pro-status{border-radius:15px!important;margin-bottom:10px!important;padding:10px!important}.mpe-tool-tabs button{min-height:48px!important}.mpe-tool-sidebar--collapsed{padding:10px 8px!important}.mpe-tool-sidebar--collapsed .mpe-tool-sidebar__head{justify-content:center;padding:4px 0}.mpe-tool-sidebar--collapsed .mpe-tool-sidebar__head>div,.mpe-tool-sidebar--collapsed .mpe-license-dot,.mpe-tool-sidebar--collapsed .mpe-tool-tabs,.mpe-tool-sidebar--collapsed .mpe-tool-group__title,.mpe-tool-sidebar--collapsed .mpe-side-tool__copy,.mpe-tool-sidebar--collapsed .mpe-side-tool em,.mpe-tool-sidebar--collapsed .mpe-side-tool b,.mpe-tool-sidebar--collapsed .mpe-sidebar-input,.mpe-tool-sidebar--collapsed .mpe-pro-status,.mpe-tool-sidebar--collapsed .mpe-pro-action-grid,.mpe-tool-sidebar--collapsed .mpe-pro-help{display:none!important}.mpe-tool-sidebar--collapsed .mpe-tool-sidebar__body{padding:0;overflow:hidden}.mpe-tool-sidebar--collapsed .mpe-side-tool{justify-items:center;grid-template-columns:1fr!important;width:40px!important;height:40px!important;min-height:40px!important;margin:0 auto 7px!important;padding:3px!important}.mpe-tool-sidebar--collapsed .mpe-side-tool__icon{width:32px!important;height:32px!important}.mpe-inspector-sidebar{-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);background:#ffffffc7;border-left:1px solid #6d5dfc1f;flex-direction:column;min-width:0;min-height:0;padding:12px;display:flex;position:relative;overflow:hidden}.mpe-inspector-sidebar--collapsed{align-items:center;padding:10px 8px}.mpe-inspector-resizer{cursor:ew-resize;z-index:3;width:8px;height:100%;position:absolute;top:0;left:-4px}.mpe-inspector-resizer:hover{background:#6d5dfc1f}.mpe-inspector-collapse{align-self:flex-end;margin-bottom:8px}.mpe-inspector-rail{gap:8px;margin-top:44px;display:grid}.mpe-inspector-rail button{width:38px;height:38px;color:var(--mpe-primary-dark);cursor:pointer;background:#ffffffdb;border:1px solid #6d5dfc29;border-radius:13px;font-weight:950}.mpe-true-edit-inline{z-index:12;background:#fffffffa;border-radius:4px;position:absolute;box-shadow:0 0 0 2px #6d5dfc52,0 10px 24px #1e18502e}.mpe-true-edit-inline textarea{resize:both;color:#111827;background:#fffffffa;border:0;outline:0;width:100%;min-height:100%;margin:0;padding:0 2px;font-weight:500;line-height:1.05;display:block;overflow:hidden}.mpe-true-edit-inline span{color:#fff;white-space:nowrap;background:#28245f;border-radius:999px;padding:4px 8px;font-size:10px;font-weight:900;position:absolute;top:calc(100% + 5px);left:0}.mpe-true-edit-inline--busy textarea{opacity:.58;cursor:progress}@media (width<=1180px){.mpe-workspace{grid-template-columns:var(--mpe-left-panel-width,280px) minmax(0, 1fr) var(--mpe-right-panel-width,290px)!important}}@media (width<=860px){.mpe-workspace{grid-template-rows:auto minmax(0,1fr) auto;grid-template-columns:1fr!important}.mpe-inspector-sidebar{border-top:1px solid #6d5dfc1f;border-left:0;max-height:260px}}.mpe-workspace{grid-template-columns:var(--mpe-left-panel-width,340px) minmax(0, 1fr)!important}.mpe-workspace--with-inspector{grid-template-columns:var(--mpe-left-panel-width,340px) minmax(0, 1fr) var(--mpe-right-panel-width,330px)!important}.mpe-tool-sidebar{gap:8px!important;padding:9px 10px!important}.mpe-tool-sidebar__head{padding:4px 2px 0!important}.mpe-tool-tabs button{min-height:39px!important;padding:7px 10px!important}.mpe-pro-status{margin-bottom:7px!important;padding:8px 9px!important}.mpe-side-tool{border-radius:12px!important;grid-template-columns:30px minmax(0,1fr) auto!important;gap:7px!important;min-height:42px!important;padding:6px 7px!important}.mpe-side-tool__icon{border-radius:10px!important;width:30px!important;height:30px!important}.mpe-side-tool__copy strong{font-size:11.5px!important;line-height:1.1!important}.mpe-side-tool__copy small{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden;font-size:9.5px!important;line-height:1.14!important}.mpe-side-tool em,.mpe-side-tool b{padding:2px 6px!important;font-size:9px!important}.mpe-tool-group{gap:6px!important;margin-bottom:8px!important}.mpe-tool-group__title{margin:4px 0 5px!important;font-size:9.5px!important}.mpe-tool-sidebar__body{gap:8px!important;padding-right:4px!important}.mpe-stage{min-width:0;padding:24px!important}.mpe-inspector-sidebar{z-index:1;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);background:#ffffffd1;border-left:1px solid #6d5dfc1f;min-width:0;min-height:0;padding:12px;display:block;overflow:hidden;position:relative!important}.mpe-inspector-sidebar .mpe-floating-inspector{background:#fffffff0;height:auto;max-height:calc(100vh - 170px);overflow:auto;width:100%!important;max-width:none!important;box-shadow:none!important;position:static!important;inset:auto!important}.mpe-annotation--text-replace{border-radius:1px!important}.mpe-annotation--text-replace:not(.mpe-annotation--selected):not(.mpe-annotation--editing){box-shadow:none!important;outline:none!important}.mpe-annotation-replacement,.mpe-annotation-text{font-weight:500!important;line-height:1.02!important}.mpe-annotation-textarea,.mpe-true-edit-inline textarea{font-weight:500!important;line-height:1.02!important;box-shadow:inset 0 0 0 1px #6d5dfc52!important}.mpe-true-edit-inline{z-index:18;background:#fffffffa;border-radius:2px!important}.mpe-true-edit-inline textarea{resize:none!important;padding:0 1px!important;overflow:hidden!important}@media (width<=1180px){.mpe-workspace,.mpe-workspace--with-inspector{grid-template-columns:var(--mpe-left-panel-width,300px) minmax(0, 1fr)!important}.mpe-workspace--with-inspector{grid-template-columns:var(--mpe-left-panel-width,300px) minmax(0, 1fr) minmax(260px, var(--mpe-right-panel-width,300px))!important}}.mpe-top-license{white-space:nowrap;border:1px solid #6d5dfc2e;border-radius:999px;justify-content:center;align-items:center;gap:7px;min-height:34px;padding:8px 12px;font-size:11px;font-weight:950;line-height:1;display:inline-flex}button.mpe-top-license{cursor:pointer;font-family:inherit}.mpe-top-license--add{color:#4936b7;background:linear-gradient(135deg,#f4f0ff,#fff);box-shadow:0 10px 22px #35298d14}.mpe-top-license--add:hover{border-color:#6d5dfc6b;transform:translateY(-1px);box-shadow:0 16px 28px #35298d24}.mpe-top-license--active{color:#166534;background:#ecfdf3;border-color:#bbf7d0}.mpe-license-form{text-align:left;gap:13px;margin-top:12px;display:grid}.mpe-license-form label{color:#31285f;gap:7px;font-size:12px;font-weight:950;display:grid}.mpe-license-form input{color:#16142f;width:100%;min-height:46px;font:inherit;background:#fbfaff;border:1px solid #6d5dfc33;border-radius:15px;outline:none;padding:0 14px;font-size:13px}.mpe-license-form input:focus{border-color:#6d5dfcb3;box-shadow:0 0 0 4px #6d5dfc1f}.mpe-license-form small{color:#b91c1c;line-height:1.4;margin:0!important}.mpe-license-form small.mpe-license-form__ok{color:#166534}.mpe-license-actions{flex-wrap:wrap;justify-content:center;align-items:center;gap:9px;margin-top:4px;display:flex}.mpe-license-actions .mpe-button{min-height:40px}@media (width<=720px){.mpe-top-license{width:100%}.mpe-license-actions{flex-direction:column;align-items:stretch}}
2
2
  /*$vite$:1*/