pdfjs-annotation-extension-for-react 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Laomai<codefee@foxmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,338 @@
1
+ # pdfjs-annotation-extension-for-react
2
+
3
+ A lightweight, extensible React PDF viewer and annotator built on top of PDF.js, designed for enterprise-grade document reading and annotation scenarios.
4
+
5
+ [![NPM](https://img.shields.io/npm/v/pdfjs-annotation-extension-for-react.svg)](https://www.npmjs.com/package/pdfjs-annotation-extension-for-react)
6
+ [![License](https://img.shields.io/npm/l/pdfjs-annotation-extension-for-react)](./LICENSE)
7
+
8
+ ## ✨ Features
9
+
10
+ - 📄 High-fidelity PDF rendering based on PDF.js
11
+ - ✍️ Rich annotation system
12
+ - Highlight, drawing, shapes, text notes
13
+ - Signatures (draw / enter / upload)
14
+ - Stamps with editor support
15
+ - Edit native PDF annotations directly
16
+ - 🎨 Theme system based on Radix UI Themes
17
+ - 🌍 Internationalization (zh-CN, en-US)
18
+ - 🧩 Highly customizable UI
19
+ - Toolbar / Sidebar / Actions fully overridable
20
+ - 🏢 Enterprise-friendly configuration
21
+ - `defaultOptions` supports DeepPartial + Deep Merge
22
+ - 💾 Export
23
+ - Export annotations to PDF
24
+ - Export annotations to Excel
25
+ - 🧠 Designed for extensibility
26
+ - Clean context & extension architecture
27
+
28
+ ## Online Demo
29
+
30
+ [![Demo](https://img.shields.io/badge/🔥_Live_Demo-React_PDF_Viewer_Plus-FF6F61?style=for-the-badge&logo=github&logoColor=white)](https://laomai-codefee.github.io/pdfjs-annotation-extension-for-react-demo/)
31
+
32
+ ## 📦 Installation
33
+
34
+ ```bash
35
+ npm install pdfjs-annotation-extension-for-react
36
+ or
37
+ yarn add pdfjs-annotation-extension-for-react
38
+ ```
39
+
40
+ # 🚀 Quick Start
41
+
42
+ ## Basic PDF Viewer
43
+
44
+ ```jsx
45
+ import { PdfViewer } from 'pdfjs-annotation-extension-for-react'
46
+ import 'pdfjs-annotation-extension-for-react/style'
47
+
48
+ export default function App() {
49
+ return (
50
+ <PdfViewer
51
+ title="PDF Viewer"
52
+ url="https://example.com/sample.pdf"
53
+ layoutStyle={{ width: '100vw', height: '100vh' }}
54
+ />
55
+ )
56
+ }
57
+ ```
58
+
59
+ ## PDF Annotator
60
+
61
+ ```jsx
62
+ import { PdfAnnotator } from 'pdfjs-annotation-extension-for-react'
63
+ import 'pdfjs-annotation-extension-for-react/style'
64
+
65
+ export default function App() {
66
+ return (
67
+ <PdfAnnotator
68
+ title="PDF Annotator"
69
+ url="https://example.com/sample.pdf"
70
+ user={{ id: 'u1', name: 'Alice' }}
71
+ onSave={(annotations) => {
72
+ console.log('Saved annotations:', annotations)
73
+ }}
74
+ />
75
+ )
76
+ }
77
+ ```
78
+
79
+ # 🧩 Components
80
+
81
+ ## 📄 PdfViewer
82
+
83
+ A lightweight PDF viewer with toolbar, sidebar, actions and extensible UI slots.
84
+
85
+ ### Props
86
+
87
+
88
+ | Prop | Type | Default | Description |
89
+ | -------------------- | -------------------------------- | ------------------------------------- | ----------------------- |
90
+ | `theme` | Radix Theme Color | `'violet'` | Viewer theme color |
91
+ | `title` | `ReactNode` | - | Page title |
92
+ | `url` | `string | URL` | **required** | PDF file URL |
93
+ | `locale` | `'zh-CN' | 'en-US'` | `'zh-CN'` | UI language |
94
+ | `initialScale` | `PdfScale` | `'auto'` | Initial zoom |
95
+ | `layoutStyle` | `CSSProperties` | `{ width: '100vw', height: '100vh' }` | Container style |
96
+ | `isSidebarCollapsed` | `boolean` | `true` | Sidebar collapsed state |
97
+ | `showSidebarTrigger` | `boolean` | `false` | Show sidebar toggle |
98
+ | `showTextLayer` | `boolean` | `true` | Enable text selection |
99
+ | `actions` | `ReactNode | (ctx) => ReactNode` | - | Custom action area |
100
+ | `sidebar` | `ReactNode | (ctx) => ReactNode` | - | Custom sidebar |
101
+ | `toolbar` | `ReactNode | (ctx) => ReactNode` | ZoomTool | Custom toolbar |
102
+ | `onDocumentLoaded` | `(pdfViewer) => void` | - | PDF loaded callback |
103
+ | `onEventBusReady` | `(eventBus) => void` | - | PDF.js EventBus ready |
104
+
105
+ ### 🎨 Custom UI
106
+
107
+ #### Custom Toolbar
108
+
109
+ ```jsx
110
+ <PdfViewer
111
+ url={pdfUrl}
112
+ toolbar={(context) => (
113
+ <>
114
+ <button onClick={() => console.log(context.pdfViewer)}>
115
+ PDF Viewer
116
+ </button>
117
+ <button onClick={context.toggleSidebar}>
118
+ Toggle Sidebar
119
+ </button>
120
+ <button onClick={() => context.setSidebarCollapsed(false)}>
121
+ Open Sidebar
122
+ </button>
123
+ <button onClick={() => context.setSidebarCollapsed(true)}>
124
+ Close Sidebar
125
+ </button>
126
+ </>
127
+ )}
128
+ />
129
+ ```
130
+
131
+ ### Custom Sidebar
132
+
133
+ ```jsx
134
+ <PdfViewer
135
+ url={pdfUrl}
136
+ sidebar={(context) => (
137
+ <>
138
+ <button onClick={() => console.log(context.pdfViewer)}>
139
+ PDF Viewer
140
+ </button>
141
+ <button onClick={() => {
142
+ context.pdfViewer?.scrollPageIntoView({
143
+ pageNumber: 1
144
+ })
145
+ }}>
146
+ page1
147
+ </button>
148
+ <button onClick={() => {
149
+ context.pdfViewer?.scrollPageIntoView({
150
+ pageNumber: 10
151
+ })
152
+ }}>
153
+ page 10
154
+ </button>
155
+ <button onClick={() => {
156
+ context.pdfViewer?.scrollPageIntoView({
157
+ pageNumber: 100
158
+ })
159
+ }}>
160
+ page 100
161
+ </button>
162
+ </>
163
+ )}
164
+ />
165
+ ```
166
+
167
+ ### Custom Actions
168
+
169
+ ```jsx
170
+ <PdfViewer
171
+ url={pdfUrl}
172
+ actions={(context) => (
173
+ <>
174
+ <button onClick={() => console.log(context.pdfViewer)}>
175
+ PDF Viewer
176
+ </button>
177
+ <button onClick={context.toggleSidebar}>
178
+ Toggle Sidebar
179
+ </button>
180
+ <button onClick={() => context.setSidebarCollapsed(false)}>
181
+ Open Sidebar
182
+ </button>
183
+ <button onClick={() => context.setSidebarCollapsed(true)}>
184
+ Close Sidebar
185
+ </button>
186
+ </>
187
+ )}
188
+ />
189
+ ```
190
+
191
+ ---
192
+
193
+ ## ✍️ PdfAnnotator
194
+
195
+ An advanced PDF viewer with annotation capabilities.
196
+
197
+ ### Props
198
+
199
+
200
+ | Prop | Type | Default | Description |
201
+ | ------------------------- | ------------------------------- | --------------------------------- | --------------------------- |
202
+ | `user` | `{ id: string; name: string }` | `{ id: 'null', name: 'unknown' }` | Annotation author |
203
+ | `enableNativeAnnotations` | `boolean` | `false` | Load native PDF annotations |
204
+ | `initialAnnotations` | `IAnnotationStore[]` | `[]` | Existing annotations |
205
+ | `defaultOptions` | `DeepPartial` | - | Default annotator options |
206
+ | `onSave` | `(annotations) => void` | - | Save callback |
207
+ | `onLoad` | `() => void` | - | Load complete |
208
+ | `onAnnotationAdded` | `(annotation) => void` | - | Add callback |
209
+ | `onAnnotationDeleted` | `(id) => void` | - | Delete callback |
210
+ | `onAnnotationUpdated` | `(annotation) => void` | - | Update callback |
211
+ | `onAnnotationSelected` | `(annotation, isClick) => void` | - | Select callback |
212
+ | `actions` | `ReactNode | Component` | - | Custom action buttons |
213
+
214
+ ### ⚙️ defaultOptions (Enterprise Design)
215
+
216
+ #### ✅ DeepPartial + Deep Merge
217
+
218
+ `defaultOptions` is not a full config override.
219
+
220
+ - It is defined as `DeepPartial<PdfAnnotatorOptions> `
221
+ - It will be deep merged with the system default configuration
222
+
223
+ This ensures:
224
+
225
+ - You only override what you need
226
+ - System defaults remain stable
227
+ - Safe for long-term enterprise use
228
+
229
+ #### Example
230
+ ```tsx
231
+ import qiantubifengshouxietiFont from './fonts/qiantubifengshouxieti.ttf';
232
+
233
+ <PdfAnnotator
234
+ url="sample.pdf"
235
+ defaultOptions={{
236
+ colors: ['#000', '#1677ff'],
237
+ signature: {
238
+ colors: ['#000000', '#ff0000', '#1677ff'],
239
+ type: 'Upload',
240
+ maxSize: 1024 * 1024 * 5,
241
+ accept: '.png,.jpg,.jpeg,.bmp',
242
+ defaultSignature: ['data:image/png;base64,...'],
243
+ defaultFont: [
244
+ {
245
+ label: '楷体',
246
+ value: 'STKaiti',
247
+ external: false
248
+ },
249
+ {
250
+ label: '千图笔锋手写体',
251
+ value: 'qiantubifengshouxieti',
252
+ external: true,
253
+ url: qiantubifengshouxietiFont
254
+ },
255
+ {
256
+ label: '平方长安体',
257
+ value: 'PingFangChangAnTi-2',
258
+ external: true,
259
+ url: 'http://server/PingFangChangAnTi-2.ttf'
260
+ }
261
+ ]
262
+ },
263
+ stamp: {
264
+ maxSize: 1024 * 1024 * 5,
265
+ accept: '.png,.jpg,.jpeg,.bmp',
266
+ defaultStamp: ['data:image/png;base64,...'],
267
+ editor: {
268
+ defaultBackgroundColor: '#2f9e44',
269
+ defaultBorderColor: '#2b8a3e',
270
+ defaultBorderStyle: 'none',
271
+ defaultTextColor: '#fff',
272
+ defaultFont: [
273
+ {
274
+ label: '楷体',
275
+ value: 'STKaiti'
276
+ }
277
+ ]
278
+ }
279
+ }
280
+ }}
281
+ />
282
+ ```
283
+
284
+ ### 🎨 Custom UI
285
+
286
+ #### Custom Actions
287
+
288
+ ```jsx
289
+ <PdfAnnotator
290
+ url={pdfUrl}
291
+ actions={({ save, exportToPdf, exportToExcel }) => (
292
+ <>
293
+ <button onClick={save}>Save</button>
294
+ <button onClick={() => exportToPdf('annotations')}>
295
+ Export PDF
296
+ </button>
297
+ <button onClick={() => exportToExcel('annotations')}>
298
+ Export Excel
299
+ </button>
300
+ </>
301
+ )}
302
+ />
303
+ ```
304
+
305
+ ### 🖋 Signature & Stamp Configuration
306
+
307
+ ```jsx
308
+ <PdfAnnotator
309
+ url={pdfUrl}
310
+ defaultOptions={{
311
+ signature: {
312
+ defaultSignature: ['data:image/png;base64,...'],
313
+ defaultFont: [
314
+ {
315
+ label: 'Custom Font',
316
+ value: 'MyFont',
317
+ external: true,
318
+ url: '/fonts/myfont.ttf'
319
+ }
320
+ ]
321
+ },
322
+ stamp: {
323
+ defaultStamp: ['data:image/png;base64,...']
324
+ }
325
+ }}
326
+ />
327
+ ```
328
+
329
+ # 🌍 Browser Support
330
+
331
+ - Chrome (latest)
332
+ - Firefox (latest)
333
+ - Safari (latest)
334
+ - Edge (latest)
335
+
336
+ # 📄 License
337
+
338
+ MIT
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={};exports.default=e;
@@ -0,0 +1,4 @@
1
+ const e = {};
2
+ export {
3
+ e as default
4
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var z={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},Z=/([astvzqmhlc])([^astvzqmhlc]*)/gi,_=/-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;function g(o){const n=o.match(_);return n?n.map(Number):[]}function V(o){const n=[],t=String(o).trim();return t[0]!=="M"&&t[0]!=="m"||t.replace(Z,(l,r,a)=>{const s=g(a);let i=r.toLowerCase(),c=r;if(i==="m"&&s.length>2&&(n.push([c,...s.splice(0,2)]),i="l",c=c==="m"?"l":"L"),s.length<z[i])return"";for(n.push([c,...s.splice(0,z[i])]);s.length>=z[i]&&s.length&&z[i];)n.push([c,...s.splice(0,z[i])]);return""}),n}function B(o,n){const t=o.x*Math.cos(n)-o.y*Math.sin(n),l=o.y*Math.cos(n)+o.x*Math.sin(n);o.x=t,o.y=l}function j(o,n,t){o.x+=n,o.y+=t}function H(o,n){o.x*=n,o.y*=n}var C=class L{constructor(n){this.commands=[],n&&n instanceof L?this.commands.push(...n.commands):n&&(this.commands=V(n))}addPath(n){n&&n instanceof L&&this.commands.push(...n.commands)}moveTo(n,t){this.commands.push(["M",n,t])}lineTo(n,t){this.commands.push(["L",n,t])}arc(n,t,l,r,a,s){this.commands.push(["AC",n,t,l,r,a,!!s])}arcTo(n,t,l,r,a){this.commands.push(["AT",n,t,l,r,a])}ellipse(n,t,l,r,a,s,i,c){this.commands.push(["E",n,t,l,r,a,s,i,!!c])}closePath(){this.commands.push(["Z"])}bezierCurveTo(n,t,l,r,a,s){this.commands.push(["C",n,t,l,r,a,s])}quadraticCurveTo(n,t,l,r){this.commands.push(["Q",n,t,l,r])}rect(n,t,l,r){this.commands.push(["R",n,t,l,r])}roundRect(n,t,l,r,a){typeof a>"u"?this.commands.push(["RR",n,t,l,r,0]):this.commands.push(["RR",n,t,l,r,a])}};function A(o,n){let t=0,l=0,r,a,s,i,c,u,m,q,F,d,$,G,E,p,f,w,I,b,k,S,Q,P=null,R=null,y=null,T=null,v=null,M=null;o.beginPath();for(let h=0;h<n.length;++h){b=n[h][0],b!=="S"&&b!=="s"&&b!=="C"&&b!=="c"&&(P=null,R=null),b!=="T"&&b!=="t"&&b!=="Q"&&b!=="q"&&(y=null,T=null);let e;switch(b){case"m":case"M":e=n[h],b==="m"?(t+=e[1],l+=e[2]):(t=e[1],l=e[2]),(b==="M"||!v)&&(v={x:t,y:l}),o.moveTo(t,l);break;case"l":e=n[h],t+=e[1],l+=e[2],o.lineTo(t,l);break;case"L":e=n[h],t=e[1],l=e[2],o.lineTo(t,l);break;case"H":e=n[h],t=e[1],o.lineTo(t,l);break;case"h":e=n[h],t+=e[1],o.lineTo(t,l);break;case"V":e=n[h],l=e[1],o.lineTo(t,l);break;case"v":e=n[h],l+=e[1],o.lineTo(t,l);break;case"a":case"A":if(e=n[h],M===null)throw new Error("This should never happen");b==="a"?(t+=e[6],l+=e[7]):(t=e[6],l=e[7]),p=e[1],f=e[2],m=e[3]*Math.PI/180,s=!!e[4],i=!!e[5],c={x:t,y:l},u={x:(M.x-c.x)/2,y:(M.y-c.y)/2},B(u,-m),q=u.x*u.x/(p*p)+u.y*u.y/(f*f),q>1&&(q=Math.sqrt(q),p*=q,f*=q),k={x:p*u.y/f,y:-(f*u.x)/p},F=p*p*f*f,d=p*p*u.y*u.y+f*f*u.x*u.x,i!==s?H(k,Math.sqrt((F-d)/d)||0):H(k,-Math.sqrt((F-d)/d)||0),a=Math.atan2((u.y-k.y)/f,(u.x-k.x)/p),r=Math.atan2(-(u.y+k.y)/f,-(u.x+k.x)/p),B(k,m),j(k,(c.x+M.x)/2,(c.y+M.y)/2),o.save(),o.translate(k.x,k.y),o.rotate(m),o.scale(p,f),o.arc(0,0,1,a,r,!i),o.restore();break;case"C":e=n[h],P=e[3],R=e[4],t=e[5],l=e[6],o.bezierCurveTo(e[1],e[2],P,R,t,l);break;case"c":e=n[h],o.bezierCurveTo(e[1]+t,e[2]+l,e[3]+t,e[4]+l,e[5]+t,e[6]+l),P=e[3]+t,R=e[4]+l,t+=e[5],l+=e[6];break;case"S":e=n[h],(P===null||R===null)&&(P=t,R=l),o.bezierCurveTo(2*t-P,2*l-R,e[1],e[2],e[3],e[4]),P=e[1],R=e[2],t=e[3],l=e[4];break;case"s":e=n[h],(P===null||R===null)&&(P=t,R=l),o.bezierCurveTo(2*t-P,2*l-R,e[1]+t,e[2]+l,e[3]+t,e[4]+l),P=e[1]+t,R=e[2]+l,t+=e[3],l+=e[4];break;case"Q":e=n[h],y=e[1],T=e[2],t=e[3],l=e[4],o.quadraticCurveTo(y,T,t,l);break;case"q":e=n[h],y=e[1]+t,T=e[2]+l,t+=e[3],l+=e[4],o.quadraticCurveTo(y,T,t,l);break;case"T":e=n[h],(y===null||T===null)&&(y=t,T=l),y=2*t-y,T=2*l-T,t=e[1],l=e[2],o.quadraticCurveTo(y,T,t,l);break;case"t":e=n[h],(y===null||T===null)&&(y=t,T=l),y=2*t-y,T=2*l-T,t+=e[1],l+=e[2],o.quadraticCurveTo(y,T,t,l);break;case"z":case"Z":v&&(t=v.x,l=v.y),v=null,o.closePath();break;case"AC":e=n[h],t=e[1],l=e[2],E=e[3],a=e[4],r=e[5],S=e[6],o.arc(t,l,E,a,r,S);break;case"AT":e=n[h],$=e[1],G=e[2],t=e[3],l=e[4],E=e[5],o.arcTo($,G,t,l,E);break;case"E":e=n[h],t=e[1],l=e[2],p=e[3],f=e[4],m=e[5],a=e[6],r=e[7],S=e[8],o.save(),o.translate(t,l),o.rotate(m),o.scale(p,f),o.arc(0,0,1,a,r,S),o.restore();break;case"R":e=n[h],t=e[1],l=e[2],w=e[3],I=e[4],v={x:t,y:l},o.rect(t,l,w,I);break;case"RR":e=n[h],t=e[1],l=e[2],w=e[3],I=e[4],Q=e[5],v={x:t,y:l},o.roundRect(t,l,w,I,Q);break;default:throw new Error(`Invalid path command: ${b}`)}M?(M.x=t,M.y=l):M={x:t,y:l}}}function N(o,n,t,l,r=0){if(typeof r=="number"&&(r=[r]),Array.isArray(r)){if(r.length===0||r.length>4)throw new RangeError(`Failed to execute 'roundRect' on '${this.constructor.name}': ${r.length} radii provided. Between one and four radii are necessary.`);r.forEach(m=>{if(m<0)throw new RangeError(`Failed to execute 'roundRect' on '${this.constructor.name}': Radius value ${m} is negative.`)})}else return;if(r.length===1&&r[0]===0){this.rect(o,n,t,l);return}const a=Math.min(t,l)/2,s=Math.min(a,r[0]);let i=s,c=s,u=s;r.length===2&&(i=Math.min(a,r[1]),u=i),r.length===3&&(i=Math.min(a,r[1]),u=i,c=Math.min(a,r[2])),r.length===4&&(i=Math.min(a,r[1]),c=Math.min(a,r[2]),u=Math.min(a,r[3])),this.moveTo(o,n+l-u),this.arcTo(o,n,o+s,n,s),this.arcTo(o+t,n,o+t,n+i,i),this.arcTo(o+t,n+l,o+t-c,n+l,c),this.arcTo(o,n+l,o,n+l-u,u),this.closePath()}function O(o){if(!o)return;const n=o.prototype.clip,t=o.prototype.fill,l=o.prototype.stroke,r=o.prototype.isPointInPath;o.prototype.clip=function(...s){if(s[0]instanceof C){const c=s[0],u=s[1]||"nonzero";return A(this,c.commands),n.apply(this,[u])}const i=s[0]||"nonzero";return n.apply(this,[i])},o.prototype.fill=function(...s){if(s[0]instanceof C){const c=s[0],u=s[1]||"nonzero";return A(this,c.commands),t.apply(this,[u])}const i=s[0]||"nonzero";return t.apply(this,[i])},o.prototype.stroke=function(s){s&&A(this,s.commands),l.apply(this)},o.prototype.isPointInPath=function(...s){if(s[0]instanceof C){const i=s[0],c=s[1],u=s[2],m=s[3]||"nonzero";return A(this,i.commands),r.apply(this,[c,u,m])}return r.apply(this,s)}}function U(o){o&&!o.prototype.roundRect&&(o.prototype.roundRect=N)}function J(o){o&&!o.prototype.roundRect&&(o.prototype.roundRect=N)}exports.Path2D=C;exports.applyPath2DToCanvasRenderingContext=O;exports.applyRoundRectToCanvasRenderingContext2D=U;exports.applyRoundRectToPath2D=J;exports.buildPath=A;exports.parsePath=V;exports.roundRect=N;
@@ -0,0 +1,230 @@
1
+ var A = {
2
+ a: 7,
3
+ c: 6,
4
+ h: 1,
5
+ l: 2,
6
+ m: 2,
7
+ q: 4,
8
+ s: 4,
9
+ t: 2,
10
+ v: 1,
11
+ z: 0
12
+ }, V = /([astvzqmhlc])([^astvzqmhlc]*)/gi, Z = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
13
+ function _(o) {
14
+ const n = o.match(Z);
15
+ return n ? n.map(Number) : [];
16
+ }
17
+ function U(o) {
18
+ const n = [], t = String(o).trim();
19
+ return t[0] !== "M" && t[0] !== "m" || t.replace(V, (l, r, a) => {
20
+ const s = _(a);
21
+ let c = r.toLowerCase(), i = r;
22
+ if (c === "m" && s.length > 2 && (n.push([i, ...s.splice(0, 2)]), c = "l", i = i === "m" ? "l" : "L"), s.length < A[c])
23
+ return "";
24
+ for (n.push([i, ...s.splice(0, A[c])]); s.length >= A[c] && s.length && A[c]; )
25
+ n.push([i, ...s.splice(0, A[c])]);
26
+ return "";
27
+ }), n;
28
+ }
29
+ function B(o, n) {
30
+ const t = o.x * Math.cos(n) - o.y * Math.sin(n), l = o.y * Math.cos(n) + o.x * Math.sin(n);
31
+ o.x = t, o.y = l;
32
+ }
33
+ function j(o, n, t) {
34
+ o.x += n, o.y += t;
35
+ }
36
+ function C(o, n) {
37
+ o.x *= n, o.y *= n;
38
+ }
39
+ var N = class S {
40
+ constructor(n) {
41
+ this.commands = [], n && n instanceof S ? this.commands.push(...n.commands) : n && (this.commands = U(n));
42
+ }
43
+ addPath(n) {
44
+ n && n instanceof S && this.commands.push(...n.commands);
45
+ }
46
+ moveTo(n, t) {
47
+ this.commands.push(["M", n, t]);
48
+ }
49
+ lineTo(n, t) {
50
+ this.commands.push(["L", n, t]);
51
+ }
52
+ arc(n, t, l, r, a, s) {
53
+ this.commands.push(["AC", n, t, l, r, a, !!s]);
54
+ }
55
+ arcTo(n, t, l, r, a) {
56
+ this.commands.push(["AT", n, t, l, r, a]);
57
+ }
58
+ ellipse(n, t, l, r, a, s, c, i) {
59
+ this.commands.push(["E", n, t, l, r, a, s, c, !!i]);
60
+ }
61
+ closePath() {
62
+ this.commands.push(["Z"]);
63
+ }
64
+ bezierCurveTo(n, t, l, r, a, s) {
65
+ this.commands.push(["C", n, t, l, r, a, s]);
66
+ }
67
+ quadraticCurveTo(n, t, l, r) {
68
+ this.commands.push(["Q", n, t, l, r]);
69
+ }
70
+ rect(n, t, l, r) {
71
+ this.commands.push(["R", n, t, l, r]);
72
+ }
73
+ roundRect(n, t, l, r, a) {
74
+ typeof a > "u" ? this.commands.push(["RR", n, t, l, r, 0]) : this.commands.push(["RR", n, t, l, r, a]);
75
+ }
76
+ };
77
+ function F(o, n) {
78
+ let t = 0, l = 0, r, a, s, c, i, u, k, q, L, z, $, G, E, p, f, w, I, b, R, d, Q, m = null, P = null, y = null, T = null, v = null, M = null;
79
+ o.beginPath();
80
+ for (let h = 0; h < n.length; ++h) {
81
+ b = n[h][0], b !== "S" && b !== "s" && b !== "C" && b !== "c" && (m = null, P = null), b !== "T" && b !== "t" && b !== "Q" && b !== "q" && (y = null, T = null);
82
+ let e;
83
+ switch (b) {
84
+ case "m":
85
+ case "M":
86
+ e = n[h], b === "m" ? (t += e[1], l += e[2]) : (t = e[1], l = e[2]), (b === "M" || !v) && (v = { x: t, y: l }), o.moveTo(t, l);
87
+ break;
88
+ case "l":
89
+ e = n[h], t += e[1], l += e[2], o.lineTo(t, l);
90
+ break;
91
+ case "L":
92
+ e = n[h], t = e[1], l = e[2], o.lineTo(t, l);
93
+ break;
94
+ case "H":
95
+ e = n[h], t = e[1], o.lineTo(t, l);
96
+ break;
97
+ case "h":
98
+ e = n[h], t += e[1], o.lineTo(t, l);
99
+ break;
100
+ case "V":
101
+ e = n[h], l = e[1], o.lineTo(t, l);
102
+ break;
103
+ case "v":
104
+ e = n[h], l += e[1], o.lineTo(t, l);
105
+ break;
106
+ case "a":
107
+ case "A":
108
+ if (e = n[h], M === null)
109
+ throw new Error("This should never happen");
110
+ b === "a" ? (t += e[6], l += e[7]) : (t = e[6], l = e[7]), p = e[1], f = e[2], k = e[3] * Math.PI / 180, s = !!e[4], c = !!e[5], i = { x: t, y: l }, u = {
111
+ x: (M.x - i.x) / 2,
112
+ y: (M.y - i.y) / 2
113
+ }, B(u, -k), q = u.x * u.x / (p * p) + u.y * u.y / (f * f), q > 1 && (q = Math.sqrt(q), p *= q, f *= q), R = {
114
+ x: p * u.y / f,
115
+ y: -(f * u.x) / p
116
+ }, L = p * p * f * f, z = p * p * u.y * u.y + f * f * u.x * u.x, c !== s ? C(R, Math.sqrt((L - z) / z) || 0) : C(R, -Math.sqrt((L - z) / z) || 0), a = Math.atan2((u.y - R.y) / f, (u.x - R.x) / p), r = Math.atan2(-(u.y + R.y) / f, -(u.x + R.x) / p), B(R, k), j(R, (i.x + M.x) / 2, (i.y + M.y) / 2), o.save(), o.translate(R.x, R.y), o.rotate(k), o.scale(p, f), o.arc(0, 0, 1, a, r, !c), o.restore();
117
+ break;
118
+ case "C":
119
+ e = n[h], m = e[3], P = e[4], t = e[5], l = e[6], o.bezierCurveTo(e[1], e[2], m, P, t, l);
120
+ break;
121
+ case "c":
122
+ e = n[h], o.bezierCurveTo(e[1] + t, e[2] + l, e[3] + t, e[4] + l, e[5] + t, e[6] + l), m = e[3] + t, P = e[4] + l, t += e[5], l += e[6];
123
+ break;
124
+ case "S":
125
+ e = n[h], (m === null || P === null) && (m = t, P = l), o.bezierCurveTo(2 * t - m, 2 * l - P, e[1], e[2], e[3], e[4]), m = e[1], P = e[2], t = e[3], l = e[4];
126
+ break;
127
+ case "s":
128
+ e = n[h], (m === null || P === null) && (m = t, P = l), o.bezierCurveTo(2 * t - m, 2 * l - P, e[1] + t, e[2] + l, e[3] + t, e[4] + l), m = e[1] + t, P = e[2] + l, t += e[3], l += e[4];
129
+ break;
130
+ case "Q":
131
+ e = n[h], y = e[1], T = e[2], t = e[3], l = e[4], o.quadraticCurveTo(y, T, t, l);
132
+ break;
133
+ case "q":
134
+ e = n[h], y = e[1] + t, T = e[2] + l, t += e[3], l += e[4], o.quadraticCurveTo(y, T, t, l);
135
+ break;
136
+ case "T":
137
+ e = n[h], (y === null || T === null) && (y = t, T = l), y = 2 * t - y, T = 2 * l - T, t = e[1], l = e[2], o.quadraticCurveTo(y, T, t, l);
138
+ break;
139
+ case "t":
140
+ e = n[h], (y === null || T === null) && (y = t, T = l), y = 2 * t - y, T = 2 * l - T, t += e[1], l += e[2], o.quadraticCurveTo(y, T, t, l);
141
+ break;
142
+ case "z":
143
+ case "Z":
144
+ v && (t = v.x, l = v.y), v = null, o.closePath();
145
+ break;
146
+ case "AC":
147
+ e = n[h], t = e[1], l = e[2], E = e[3], a = e[4], r = e[5], d = e[6], o.arc(t, l, E, a, r, d);
148
+ break;
149
+ case "AT":
150
+ e = n[h], $ = e[1], G = e[2], t = e[3], l = e[4], E = e[5], o.arcTo($, G, t, l, E);
151
+ break;
152
+ case "E":
153
+ e = n[h], t = e[1], l = e[2], p = e[3], f = e[4], k = e[5], a = e[6], r = e[7], d = e[8], o.save(), o.translate(t, l), o.rotate(k), o.scale(p, f), o.arc(0, 0, 1, a, r, d), o.restore();
154
+ break;
155
+ case "R":
156
+ e = n[h], t = e[1], l = e[2], w = e[3], I = e[4], v = { x: t, y: l }, o.rect(t, l, w, I);
157
+ break;
158
+ case "RR":
159
+ e = n[h], t = e[1], l = e[2], w = e[3], I = e[4], Q = e[5], v = { x: t, y: l }, o.roundRect(t, l, w, I, Q);
160
+ break;
161
+ default:
162
+ throw new Error(`Invalid path command: ${b}`);
163
+ }
164
+ M ? (M.x = t, M.y = l) : M = { x: t, y: l };
165
+ }
166
+ }
167
+ function H(o, n, t, l, r = 0) {
168
+ if (typeof r == "number" && (r = [r]), Array.isArray(r)) {
169
+ if (r.length === 0 || r.length > 4)
170
+ throw new RangeError(
171
+ `Failed to execute 'roundRect' on '${this.constructor.name}': ${r.length} radii provided. Between one and four radii are necessary.`
172
+ );
173
+ r.forEach((k) => {
174
+ if (k < 0)
175
+ throw new RangeError(
176
+ `Failed to execute 'roundRect' on '${this.constructor.name}': Radius value ${k} is negative.`
177
+ );
178
+ });
179
+ } else
180
+ return;
181
+ if (r.length === 1 && r[0] === 0) {
182
+ this.rect(o, n, t, l);
183
+ return;
184
+ }
185
+ const a = Math.min(t, l) / 2, s = Math.min(a, r[0]);
186
+ let c = s, i = s, u = s;
187
+ r.length === 2 && (c = Math.min(a, r[1]), u = c), r.length === 3 && (c = Math.min(a, r[1]), u = c, i = Math.min(a, r[2])), r.length === 4 && (c = Math.min(a, r[1]), i = Math.min(a, r[2]), u = Math.min(a, r[3])), this.moveTo(o, n + l - u), this.arcTo(o, n, o + s, n, s), this.arcTo(o + t, n, o + t, n + c, c), this.arcTo(o + t, n + l, o + t - i, n + l, i), this.arcTo(o, n + l, o, n + l - u, u), this.closePath();
188
+ }
189
+ function J(o) {
190
+ if (!o) return;
191
+ const n = o.prototype.clip, t = o.prototype.fill, l = o.prototype.stroke, r = o.prototype.isPointInPath;
192
+ o.prototype.clip = function(...s) {
193
+ if (s[0] instanceof N) {
194
+ const i = s[0], u = s[1] || "nonzero";
195
+ return F(this, i.commands), n.apply(this, [u]);
196
+ }
197
+ const c = s[0] || "nonzero";
198
+ return n.apply(this, [c]);
199
+ }, o.prototype.fill = function(...s) {
200
+ if (s[0] instanceof N) {
201
+ const i = s[0], u = s[1] || "nonzero";
202
+ return F(this, i.commands), t.apply(this, [u]);
203
+ }
204
+ const c = s[0] || "nonzero";
205
+ return t.apply(this, [c]);
206
+ }, o.prototype.stroke = function(s) {
207
+ s && F(this, s.commands), l.apply(this);
208
+ }, o.prototype.isPointInPath = function(...s) {
209
+ if (s[0] instanceof N) {
210
+ const c = s[0], i = s[1], u = s[2], k = s[3] || "nonzero";
211
+ return F(this, c.commands), r.apply(this, [i, u, k]);
212
+ }
213
+ return r.apply(this, s);
214
+ };
215
+ }
216
+ function K(o) {
217
+ o && !o.prototype.roundRect && (o.prototype.roundRect = H);
218
+ }
219
+ function O(o) {
220
+ o && !o.prototype.roundRect && (o.prototype.roundRect = H);
221
+ }
222
+ export {
223
+ N as Path2D,
224
+ J as applyPath2DToCanvasRenderingContext,
225
+ K as applyRoundRectToCanvasRenderingContext2D,
226
+ O as applyRoundRectToPath2D,
227
+ F as buildPath,
228
+ U as parsePath,
229
+ H as roundRect
230
+ };