pretext-pdf 0.9.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +126 -110
  2. package/README.md +122 -1
  3. package/dist/allowed-props.d.ts +40 -0
  4. package/dist/allowed-props.d.ts.map +1 -0
  5. package/dist/allowed-props.js +130 -0
  6. package/dist/allowed-props.js.map +1 -0
  7. package/dist/assets.d.ts +4 -2
  8. package/dist/assets.d.ts.map +1 -1
  9. package/dist/assets.js +22 -1
  10. package/dist/assets.js.map +1 -1
  11. package/dist/benchmarks/corpora.d.ts +11 -0
  12. package/dist/benchmarks/corpora.d.ts.map +1 -0
  13. package/dist/benchmarks/corpora.js +228 -0
  14. package/dist/benchmarks/corpora.js.map +1 -0
  15. package/dist/builder.d.ts +10 -2
  16. package/dist/builder.d.ts.map +1 -1
  17. package/dist/builder.js +12 -4
  18. package/dist/builder.js.map +1 -1
  19. package/dist/element-types.d.ts +16 -0
  20. package/dist/element-types.d.ts.map +1 -0
  21. package/dist/element-types.js +16 -0
  22. package/dist/element-types.js.map +1 -0
  23. package/dist/errors.d.ts +8 -1
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +4 -0
  26. package/dist/errors.js.map +1 -1
  27. package/dist/fonts.d.ts +2 -1
  28. package/dist/fonts.d.ts.map +1 -1
  29. package/dist/fonts.js.map +1 -1
  30. package/dist/index.d.ts +23 -14
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +27 -310
  33. package/dist/index.js.map +1 -1
  34. package/dist/layout-state.d.ts +39 -0
  35. package/dist/layout-state.d.ts.map +1 -0
  36. package/dist/layout-state.js +46 -0
  37. package/dist/layout-state.js.map +1 -0
  38. package/dist/measure-blocks.d.ts +2 -1
  39. package/dist/measure-blocks.d.ts.map +1 -1
  40. package/dist/measure-blocks.js.map +1 -1
  41. package/dist/measure.d.ts +4 -2
  42. package/dist/measure.d.ts.map +1 -1
  43. package/dist/measure.js +15 -5
  44. package/dist/measure.js.map +1 -1
  45. package/dist/page-sizes.d.ts +1 -0
  46. package/dist/page-sizes.d.ts.map +1 -1
  47. package/dist/page-sizes.js.map +1 -1
  48. package/dist/paginate.d.ts +1 -1
  49. package/dist/paginate.d.ts.map +1 -1
  50. package/dist/paginate.js +11 -2
  51. package/dist/paginate.js.map +1 -1
  52. package/dist/pipeline-footnotes.d.ts +18 -0
  53. package/dist/pipeline-footnotes.d.ts.map +1 -0
  54. package/dist/pipeline-footnotes.js +98 -0
  55. package/dist/pipeline-footnotes.js.map +1 -0
  56. package/dist/pipeline-toc.d.ts +11 -0
  57. package/dist/pipeline-toc.d.ts.map +1 -0
  58. package/dist/pipeline-toc.js +28 -0
  59. package/dist/pipeline-toc.js.map +1 -0
  60. package/dist/pipeline.d.ts +24 -0
  61. package/dist/pipeline.d.ts.map +1 -0
  62. package/dist/pipeline.js +116 -0
  63. package/dist/pipeline.js.map +1 -0
  64. package/dist/plugin-registry.d.ts +40 -0
  65. package/dist/plugin-registry.d.ts.map +1 -0
  66. package/dist/plugin-registry.js +104 -0
  67. package/dist/plugin-registry.js.map +1 -0
  68. package/dist/plugin-types.d.ts +185 -0
  69. package/dist/plugin-types.d.ts.map +1 -0
  70. package/dist/plugin-types.js +27 -0
  71. package/dist/plugin-types.js.map +1 -0
  72. package/dist/post-process.d.ts +16 -0
  73. package/dist/post-process.d.ts.map +1 -0
  74. package/dist/post-process.js +80 -0
  75. package/dist/post-process.js.map +1 -0
  76. package/dist/render-blocks.d.ts +2 -1
  77. package/dist/render-blocks.d.ts.map +1 -1
  78. package/dist/render-blocks.js.map +1 -1
  79. package/dist/render-extras.d.ts +2 -2
  80. package/dist/render-extras.d.ts.map +1 -1
  81. package/dist/render-extras.js.map +1 -1
  82. package/dist/render.d.ts +4 -2
  83. package/dist/render.d.ts.map +1 -1
  84. package/dist/render.js +23 -4
  85. package/dist/render.js.map +1 -1
  86. package/dist/types-internal.d.ts +302 -0
  87. package/dist/types-internal.d.ts.map +1 -0
  88. package/dist/types-internal.js +9 -0
  89. package/dist/types-internal.js.map +1 -0
  90. package/dist/types-public.d.ts +1031 -0
  91. package/dist/types-public.d.ts.map +1 -0
  92. package/dist/types-public.js +2 -0
  93. package/dist/types-public.js.map +1 -0
  94. package/dist/types.d.ts +6 -1224
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js +7 -0
  97. package/dist/types.js.map +1 -1
  98. package/dist/validate.d.ts +6 -2
  99. package/dist/validate.d.ts.map +1 -1
  100. package/dist/validate.js +148 -5
  101. package/dist/validate.js.map +1 -1
  102. package/package.json +31 -23
  103. package/docs/screenshots/showcase-invoice.png +0 -0
  104. package/docs/screenshots/showcase-report.png +0 -0
  105. package/docs/screenshots/showcase-resume.png +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,131 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.0.0] — 2026-05-02
11
+
12
+ First stable release. Completes the plugin extension API, closes all v1.0 gate requirements,
13
+ and ships a fully verified public surface with zero breaking changes from 0.9.x.
14
+
15
+ ### Added
16
+
17
+ - **Plugin extension API** — Register custom element types via `RenderOptions.plugins`.
18
+ Each `PluginDefinition` participates in all four pipeline stages: `validate`, `loadAsset`,
19
+ `measure`, and `render`. Plugins are fully typed and tree-shaken from documents
20
+ that don't use them. See README § Custom element types (plugins) and
21
+ `examples/plugin-custom-element.ts` for a runnable example.
22
+ - **`PluginDefinition`, `PluginMeasureContext`, `PluginMeasureResult`, `PluginRenderContext`**
23
+ exported from `pretext-pdf` public surface (previously internal).
24
+ - **`PdfBuilder` and `PdfBuilderOptions`** exported from `pretext-pdf` (enables type-safe
25
+ builder construction in downstream code without re-declaring the interface).
26
+ - **`TocEntryElement`** exported from `pretext-pdf` public surface (was in the `ContentElement`
27
+ union but not individually importable).
28
+ - **`plugins` option on `createPdf()`** — `PdfBuilderOptions.plugins` threads plugins through
29
+ the builder's `build()` call automatically.
30
+ - **`Intl.Segmenter` pre-flight guard** in `render()` — throws `RENDER_FAILED` with a clear
31
+ message on Node.js < 16 or runtimes without full-ICU data, instead of silently producing
32
+ incorrect line breaks.
33
+ - **`PluginRenderContext.pageWidth/pageHeight/margins`** — render hooks now receive full page
34
+ geometry for layout calculations (page-relative positioning, bleed boxes, etc.).
35
+ - **`render` context Y-coordinate docs** — expanded JSDoc with multi-line text example showing
36
+ how to position text baselines relative to `context.y`.
37
+ - **Benchmark corpora manifest** and **smoke staging** tests wired into `npm test`
38
+ (previously orphaned). Total test count: 672.
39
+ - `examples/plugin-custom-element.ts` — runnable plugin example (`npm run example:plugin`).
40
+
41
+ ### Fixed
42
+
43
+ - **`SIGNATURE_CERT_AND_ENCRYPTION` error code** — was declared in the `ErrorCode` union
44
+ but never thrown; validate.ts now uses it correctly when a document specifies both
45
+ signatures and encryption (previously threw a generic `VALIDATION_ERROR`).
46
+ - **Build break under `exactOptionalPropertyTypes: true`** — `PdfBuilder.build()` no longer
47
+ passes `{ plugins: undefined }` to `runPipeline` when no plugins are configured.
48
+ - **Plugin `validate` hook empty-string normalization** — `plugin.validate()` returning `''`
49
+ now correctly accepts the element (was previously treated as a rejection message).
50
+ - **`toc` element reaching render default arm** — `render.ts` now has an explicit
51
+ `case 'toc': return` guard before the default arm; TOC elements are pre-processed
52
+ during pagination and should never reach the renderer.
53
+ - **`RichLine` and `RichFragment`** demoted from `@public` to `@internal`; these are
54
+ implementation details of the rich-text pipeline, not intended for external use.
55
+ - **Sentinel value documentation** — `MeasuredBlock` comment now explicitly states that
56
+ `lines: []`, `fontSize: 0`, `lineHeight: 0`, `fontKey: ''` applies to spacers, tables,
57
+ images, hr, *and plugin blocks* — not a bug but a documented convention.
58
+
59
+ ### Internal
60
+
61
+ - `src/plugin-registry.ts` (new): Pure orchestration helpers for the four plugin injection
62
+ points (`findPlugin`, `runPluginValidate`, `runPluginLoadAsset`, `runPluginMeasure`,
63
+ `runPluginRender`).
64
+ - `src/plugin-types.ts` (new): `PluginDefinition` interface and context/result types.
65
+ - `src/layout-state.ts`: `prepareLayoutState` now accepts `options?: RenderOptions` and
66
+ threads plugins to `stageValidate`, `stageLoadAssets`, and `stageMeasure`.
67
+ - `docs/V1.0-RUNBOOK.md`: Full release runbook with first-principles audit, anti-hallucination
68
+ protocol, verified-facts table, and phase-by-phase plan.
69
+
70
+ ---
71
+
72
+ ## [0.9.4] — 2026-05-02
73
+
74
+ Architecture hardening + API surface snapshot. No public API changes; internal
75
+ restructuring to eliminate circular dependencies and add drift guards before v1.0 freeze.
76
+
77
+ ### Added
78
+
79
+ - **API surface snapshot** (`etc/pretext-pdf.api.md`) checked into source control as
80
+ the v1.0 baseline. The `api:check` CI step will fail on unintentional public-API drift.
81
+ - **`src/layout-state.ts`** — `prepareLayoutState()` and `summarizeLayoutState()` extracted
82
+ from the pipeline for testability; `layout-contract` and `hard-text-contract` tests
83
+ wired into `test:unit`.
84
+ - **`src/benchmarks/corpora.ts`** — benchmark corpus manifest (`getBenchmarkCorpora()`)
85
+ restored from git history; `benchmark-baseline.test.ts` wired into `test:contract`.
86
+ - **Drift guards** (`test/drift-guards.test.ts`) — asserts that `ELEMENT_TYPES`,
87
+ `ALLOWED_PROPS`, `validate.ts` cases, and `render.ts` cases all agree at test time.
88
+ Catches any future element-type addition that isn't plumbed through all four places.
89
+ - **`render.ts` default arm** — unknown element types now throw immediately instead of
90
+ silently producing a blank block.
91
+
92
+ ### Refactored
93
+
94
+ - **Circular dependency broken**: `src/post-process.ts` extracted so `builder.ts` and
95
+ `index.ts` no longer form a cycle through each other.
96
+ - **`ELEMENT_TYPES` extracted** to `src/element-types.ts` as single source of truth;
97
+ re-exported from `index.ts`, imported by `validate.ts` — eliminates the previous
98
+ per-file string-literal duplication.
99
+
100
+ ### Fixed
101
+
102
+ - `post-process.ts`: drop raw signing library error message from `SIGNATURE_FAILED`
103
+ to avoid leaking certificate or passphrase details in error output.
104
+ - `layout-state.ts`: polyfill install wrapped in try/catch; throws `CANVAS_UNAVAILABLE`
105
+ on failure instead of an untyped exception.
106
+
107
+ ---
108
+
109
+ ## [0.9.3] — 2026-04-23
110
+
111
+ Strict validation release. Opt-in property validation to catch unknown properties on elements and sub-structures via typo detection and precise JSONPath error reporting.
112
+
113
+ ### Added
114
+
115
+ - **Strict validation mode**: Pass `{ strict: true }` to `render(doc, options)` to reject unknown properties. Non-strict mode (default) remains permissive for backwards compatibility.
116
+ - **`render()` options parameter**: Updated signature to `render(doc: PdfDocument, options?: RenderOptions)` where `RenderOptions = { strict?: boolean }`.
117
+ - **`validate()` public export**: `validate()` is now exported from `pretext-pdf` for standalone validation and testing.
118
+ - **Validation error details**:
119
+ - Unknown properties reported with Levenshtein edit-distance suggestions (distance ≤2) for typo correction.
120
+ - Errors include JSONPath-like paths (`content[3].table.rows[0].cells[1].align`) for precise location reporting.
121
+ - Error accumulation: all violations collected before throwing a single VALIDATION_ERROR with formatted multi-line message.
122
+ - First 20 errors shown; overflow indicator present.
123
+ - **Compile-time drift guards**: `src/allowed-props.ts` uses `Exact<T, Keys>` TypeScript type assertions to catch property definition drift at type-check time. If element types change, `tsc --noEmit` will error if allowed-props lists don't match.
124
+ - **Property allowlists**:
125
+ - `ALLOWED_PROPS`: 22 element types (paragraph, heading, table, image, code, list, etc.)
126
+ - `ALLOWED_PROPS_SUB`: 8 sub-structures (document, metadata, table-row, table-cell, list-item, inline-span, column-def, annotation)
127
+
128
+ ### Internal
129
+
130
+ - `src/allowed-props.ts` (new): Central configuration for allowed properties with compile-time assertions.
131
+ - `src/validate.ts` (enhanced): Added `levenshteinDist()`, `closestMatch()`, `assertUnknownProps()`, and `formatErrors()` helpers; threading strict flag through `validateElement()` for nested structure validation (tables, lists, rich-paragraphs, float-groups, annotations).
132
+
133
+ ---
134
+
10
135
  ## [0.9.2] — 2026-04-22
11
136
 
12
137
  Maintenance release. Engine refresh + repo-hygiene automation. No runtime behavior changes beyond the `@chenglou/pretext` bump.
@@ -22,7 +147,7 @@ Maintenance release. Engine refresh + repo-hygiene automation. No runtime behavi
22
147
  ### Added
23
148
 
24
149
  - `scripts/verify-badges.js` + CI step — compares README shields.io badge values against `package.json` dep count and `npm test` total. Fails CI on drift. Fast path via `SKIP_TEST_RUN=1` for pre-commit use.
25
- - `.github/workflows/release-on-tag.yml` — on `v*` tag push, auto-extracts the matching `## [X.Y.Z]` section from this file and creates the GitHub release. Closes the "tag exists but no release page" gap that affected v0.9.1.
150
+ - `release` job in `ci.yml` — on `v*` tag push, auto-extracts the matching `## [X.Y.Z]` section from this file and creates the GitHub release (requires publish to succeed first). Closes the "tag exists but no release page" gap that affected v0.9.1. (Note: originally shipped as `.github/workflows/release-on-tag.yml`; merged into `ci.yml` for dependency ordering in Tier 0.5.)
26
151
  - `renovate.json` — watches dependencies, auto-merges devDependency bumps that pass CI, opens PRs (without auto-merge) for runtime, peer, and `@chenglou/pretext` engine bumps. Closes the gap that left us one release behind upstream.
27
152
 
28
153
  ### Removed
@@ -484,112 +609,3 @@ Three additive enhancements that broaden the package's surface without growing i
484
609
  - Image formats: PNG, JPG, WebP
485
610
  - Table features: custom column widths, cell padding, borders, header styling
486
611
  - Colors: hex color codes throughout (text, backgrounds, borders)
487
-
488
- ---
489
-
490
- ## Features by Phase
491
-
492
- | Phase | Feature | Status | Tests | Version |
493
- |-------|---------|--------|-------|---------|
494
- | 7A | Bookmarks / PDF Outline | ✅ Complete | 8 | 0.1.0 |
495
- | 7B | Watermarks | ✅ Complete | 8 | 0.1.0 |
496
- | 7C | Hyphenation | ✅ Complete | 10 | 0.1.0 |
497
- | 7D | Table of Contents | ✅ Complete | 10 | 0.1.0 |
498
- | 7E | SVG Support | ✅ Complete | 8 | 0.1.0 |
499
- | 7F | RTL Text Support | ✅ Complete | 12 | 0.1.0 |
500
- | 7G | Encryption | ✅ Complete | 7 | 0.1.0 |
501
- | Integration | Feature Combinations | ✅ Complete | 6 | 0.1.0 |
502
- | 6 | Advanced Features | ✅ Complete | — | 0.1.0 |
503
- | 5 | Rich Text / Builder API | ✅ Complete | — | 0.1.0 |
504
- | 1–4 | Core Engine | ✅ Complete | — | 0.1.0 |
505
-
506
- ---
507
-
508
- ## How to Use Examples
509
-
510
- All Phase 7 features have working examples in the `examples/` directory. Run them with:
511
-
512
- ```bash
513
- npm run example:watermark # Phase 7B — Watermarks
514
- npm run example:bookmarks # Phase 7A — Bookmarks
515
- npm run example:toc # Phase 7D — Table of Contents
516
- npm run example:rtl # Phase 7F — RTL Text Support
517
- npm run example:encryption # Phase 7G — Encryption
518
- ```
519
-
520
- PDF output is written to `output/phase7-*.pdf`.
521
-
522
- ---
523
-
524
- ## Test Coverage
525
-
526
- All phases include comprehensive test coverage:
527
-
528
- ```bash
529
- npm test # Run all 75+ tests
530
- npm run test:unit # Unit tests only
531
- npm run test:e2e # End-to-end tests
532
- npm run test:visual # Visual regression tests
533
- ```
534
-
535
- ---
536
-
537
- ## Dependencies
538
-
539
- ### Required
540
-
541
- - `@chenglou/pretext` — Pretext text layout engine
542
- - `pdf-lib` — PDF document manipulation
543
- - `@fontsource/inter` — Font: Inter (bundled)
544
- - `bidi-js` — Bidirectional text algorithm (Phase 7F)
545
- - `hypher` — Hyphenation algorithm (Phase 7C)
546
- - `hyphenation.en-us` — English hyphenation patterns (Phase 7C)
547
-
548
- ### Optional (Peer)
549
-
550
- - `@napi-rs/canvas` — SVG rasterization (Phase 7E)
551
- - `@cantoo/pdf-lib` — PDF encryption (Phase 7G)
552
-
553
- ---
554
-
555
- ## Architecture
556
-
557
- pretext-pdf uses a modular, layered architecture:
558
-
559
- ```
560
- render(doc) → validate → layout → paginate → render-pages → PDF bytes
561
- ```
562
-
563
- Each phase adds features orthogonally:
564
- - Phase 1–4: Core engine, pagination, typography
565
- - Phase 5: Rich text and builder patterns
566
- - Phase 6: Advanced layout and formatting
567
- - Phase 7: Security, internationalization, accessibility
568
-
569
- ---
570
-
571
- ## Future Roadmap
572
-
573
- Potential Phase 8+ features (not yet implemented):
574
- - Hyperlinks and anchors
575
- - Justified text alignment
576
- - Enhanced text decorations
577
- - Font subsetting for file size reduction
578
- - Browser compatibility improvements
579
- - Performance optimizations
580
-
581
- ---
582
-
583
- ## Contributing
584
-
585
- pretext-pdf is actively maintained. To report issues, request features, or contribute:
586
-
587
- 1. Check existing issues on the project repo
588
- 2. Write failing tests first (TDD)
589
- 3. Submit pull requests with test coverage ≥80%
590
-
591
- ---
592
-
593
- ## License
594
-
595
- Check LICENSE file in repository root.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  [![npm downloads](https://img.shields.io/npm/dw/pretext-pdf)](https://www.npmjs.com/package/pretext-pdf)
10
10
  [![CI](https://github.com/Himaan1998Y/pretext-pdf/actions/workflows/ci.yml/badge.svg)](https://github.com/Himaan1998Y/pretext-pdf/actions)
11
11
  [![TypeScript](https://img.shields.io/badge/typescript-strict-blue)](https://www.typescriptlang.org/)
12
- [![Tests](https://img.shields.io/badge/tests-624-brightgreen)](#tests)
12
+ [![Tests](https://img.shields.io/badge/tests-641-brightgreen)](#tests)
13
13
  [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
14
14
  [![Bundle](https://img.shields.io/badge/runtime%20deps-8-informational)](#runtime-footprint)
15
15
 
@@ -34,15 +34,18 @@
34
34
  - [Element catalog](#element-catalog)
35
35
  - [Document features](#document-level-features)
36
36
  - [API reference](#api-reference)
37
+ - [Strict validation](#strict-validation)
37
38
  - [India / GST invoicing](#india--gst-invoicing)
38
39
  - [Custom fonts](#custom-fonts)
39
40
  - [Rich text](#rich-text)
40
41
  - [Footnotes](#footnotes)
42
+ - [Custom element types (plugins)](#custom-element-types-plugins)
41
43
  - [Examples](#examples)
42
44
  - [Error handling](#error-handling)
43
45
  - [Troubleshooting](#troubleshooting)
44
46
  - [Non-goals](#non-goals)
45
47
  - [Runtime footprint](#runtime-footprint)
48
+ - [Compatibility matrix](#compatibility-matrix)
46
49
  - [Performance](#performance)
47
50
  - [Tests](#tests)
48
51
  - [Security](#security)
@@ -432,6 +435,47 @@ const pdf = await createPdf({ pageSize: 'A4' })
432
435
 
433
436
  ---
434
437
 
438
+ ## Strict validation
439
+
440
+ By default, `render()` uses permissive validation — unknown properties are silently ignored. Enable strict mode to catch typos and ensure property names match the schema exactly:
441
+
442
+ ```typescript
443
+ import { render } from 'pretext-pdf'
444
+
445
+ const pdf = await render(doc, { strict: true })
446
+ ```
447
+
448
+ In strict mode:
449
+
450
+ - **Unknown properties are rejected** with a `VALIDATION_ERROR` that includes:
451
+ - Property name and location (JSONPath-like: `content[3].table.rows[0].cells[1].align`)
452
+ - Typo suggestions via Levenshtein distance (edit distance ≤2)
453
+ - All violations collected before throwing, with a 20-error cap + overflow indicator
454
+
455
+ Example error:
456
+
457
+ ```
458
+ VALIDATION_ERROR:
459
+ unknown property 'fontSizee' at content[0].fontSizee (did you mean fontsize, fontSize?)
460
+ unknown property 'colorr' at content[1].inline.colorr (did you mean color?)
461
+ ```
462
+
463
+ Strict validation is useful for:
464
+ - **AI agent self-correction**: LLMs can parse error messages and fix typos
465
+ - **Template development**: catch copy-paste errors in large documents
466
+ - **Type safety**: ensure your generator is emitting well-formed documents
467
+
468
+ You can also call `validate()` standalone for testing:
469
+
470
+ ```typescript
471
+ import { validate } from 'pretext-pdf'
472
+
473
+ // Throws PretextPdfError('VALIDATION_ERROR', ...) if strict check fails
474
+ validate(doc, { strict: true })
475
+ ```
476
+
477
+ ---
478
+
435
479
  ## India / GST invoicing
436
480
 
437
481
  Built-in support for Indian invoice requirements:
@@ -539,6 +583,66 @@ await render({
539
583
 
540
584
  ---
541
585
 
586
+ ## Custom element types (plugins)
587
+
588
+ The plugin API lets you register new element types without forking the library.
589
+ Each plugin definition handles one `type` string and participates in the standard
590
+ validate → measure → render pipeline.
591
+
592
+ ```typescript
593
+ import { render } from 'pretext-pdf'
594
+ import type { PluginDefinition } from 'pretext-pdf'
595
+ import { rgb } from '@cantoo/pdf-lib'
596
+
597
+ const highlightBoxPlugin: PluginDefinition = {
598
+ type: 'highlight-box',
599
+
600
+ // Optional: reject bad elements early
601
+ validate(element) {
602
+ if (typeof element['label'] !== 'string') return '"label" must be a string'
603
+ },
604
+
605
+ // Required: return block height for layout/pagination
606
+ async measure(element) {
607
+ return { height: 48, spaceBefore: 8, spaceAfter: 8 }
608
+ },
609
+
610
+ // Required: draw onto the pdf-lib page
611
+ render({ element, pdfPage, x, y, width, height }) {
612
+ pdfPage.drawRectangle({ x, y: y - height, width, height, color: rgb(1, 0.93, 0.73) })
613
+ pdfPage.drawText(element['label'] as string, { x: x + 16, y: y - 30, size: 13 })
614
+ },
615
+ }
616
+
617
+ // Pass plugins via render() options or createPdf() options
618
+ const pdf = await render(doc, { plugins: [highlightBoxPlugin] })
619
+ ```
620
+
621
+ **How it works:**
622
+
623
+ | Hook | Stage | Required | Purpose |
624
+ | ---- | ----- | -------- | ------- |
625
+ | `validate` | 1 | No | Reject malformed custom elements; return error string or void |
626
+ | `loadAsset` | 2b | No | Embed a `PDFImage` (passed back as `context.pdfImage` in render) |
627
+ | `measure` | 3 | **Yes** | Return `height`, optional `spaceBefore`/`spaceAfter`, optional `pluginData` |
628
+ | `render` | 5 | **Yes** | Draw onto `context.pdfPage` using pdf-lib's drawing API |
629
+
630
+ **Y-coordinate note:** pdf-lib uses a bottom-left origin. `context.y` is the **top** edge of your block.
631
+ To fill the block: `drawRectangle({ x, y: y - height, width, height })`.
632
+ To draw the first line of text: `drawText(line, { x, y: y - fontSize })`.
633
+
634
+ **Constraints:** Plugin elements can only appear at the top level of `doc.content`.
635
+ They cannot be nested inside callout, blockquote, or float-group children (those
636
+ have hardcoded child type whitelists). Use top-level layout with spacers for positioning.
637
+
638
+ See `examples/plugin-custom-element.ts` for a full runnable example:
639
+
640
+ ```bash
641
+ npm run example:plugin
642
+ ```
643
+
644
+ ---
645
+
542
646
  ## Examples
543
647
 
544
648
  ```bash
@@ -555,6 +659,7 @@ npm run example:assembly # Merge + assemble multiple PDFs
555
659
  npm run example:inline # Super/subscript, letterSpacing, smallCaps
556
660
  npm run example:forms # Interactive form fields
557
661
  npm run example:callout # Callout boxes
662
+ npm run example:plugin # Custom element types (plugin API)
558
663
  ```
559
664
 
560
665
  All write to `output/*.pdf`.
@@ -653,6 +758,22 @@ All other capabilities (SVG, charts, QR, barcodes, markdown, signing) are option
653
758
 
654
759
  ---
655
760
 
761
+ ## Compatibility matrix
762
+
763
+ | Environment | Status | Notes |
764
+ | ----------- | ------ | ----- |
765
+ | **Node.js 18 / 20 / 22** | ✅ Confirmed | CI tests all three. Requires `@napi-rs/canvas` peer dep for SVG / chart / QR elements. |
766
+ | **Browser (Vite, webpack, esm.sh)** | ✅ Confirmed | Uses native `OffscreenCanvas`. No canvas peer dep needed. Bring your own font bytes via `doc.fonts` — the bundled Inter loader is Node-only. |
767
+ | **Bun** | ⚠️ Untested | Bun has Node.js compat mode. `@napi-rs/canvas` provides Bun builds but is untested end-to-end. |
768
+ | **Deno** | ⚠️ Untested | Deno's Node compat layer may work. `@napi-rs/canvas` native bindings are the unknown variable. |
769
+ | **AWS Lambda / serverless (Node runtime)** | ⚠️ Likely works | Node.js runtime, ESM supported. Cold-start impact from `@napi-rs/canvas` native addon if used. Elements that don't need canvas (paragraph, heading, table, list) have no native dep. |
770
+ | **Cloudflare Workers** | ❌ Not supported | No Node.js runtime, no native addons, no `OffscreenCanvas`. Neither the Node polyfill nor the browser path can run. |
771
+ | **Next.js (server components / API routes)** | ✅ Confirmed (Node path) | Runs on Node.js server side. Client-side rendering follows the browser path above. |
772
+
773
+ **Legend:** ✅ Confirmed in CI or end-to-end testing · ⚠️ Untested / likely works · ❌ Known not supported
774
+
775
+ ---
776
+
656
777
  ## Performance
657
778
 
658
779
  Benchmarked on Windows 11 / Node 22 / Intel i7-12th Gen. Averages over 10 runs, excluding the first cold JIT.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Strict validation: allowed properties for each element and sub-structure type.
3
+ * Enforced at runtime by strict: true validation.
4
+ * Compile-time drift guards via Exact<T, Keys> ensure types stay synchronized.
5
+ */
6
+ export declare const ALLOWED_PROPS: {
7
+ readonly paragraph: Set<"text" | "type" | "dir" | "fontSize" | "lineHeight" | "fontFamily" | "fontWeight" | "color" | "align" | "bgColor" | "spaceAfter" | "spaceBefore" | "keepTogether" | "underline" | "strikethrough" | "url" | "columns" | "columnGap" | "hyphenate" | "letterSpacing" | "smallCaps" | "tabularNumbers" | "annotation">;
8
+ readonly heading: Set<"text" | "type" | "dir" | "fontSize" | "lineHeight" | "fontFamily" | "fontWeight" | "color" | "align" | "bgColor" | "spaceAfter" | "spaceBefore" | "keepTogether" | "underline" | "strikethrough" | "url" | "hyphenate" | "letterSpacing" | "smallCaps" | "tabularNumbers" | "annotation" | "level" | "bookmark" | "anchor">;
9
+ readonly spacer: Set<"type" | "height">;
10
+ readonly table: Set<"type" | "dir" | "fontSize" | "spaceAfter" | "spaceBefore" | "columns" | "rows" | "headerRows" | "borderColor" | "borderWidth" | "headerBgColor" | "cellPaddingH" | "cellPaddingV">;
11
+ readonly image: Set<"type" | "align" | "spaceAfter" | "spaceBefore" | "height" | "width" | "src" | "format" | "float" | "floatWidth" | "floatGap" | "floatText" | "floatSpans" | "floatFontSize" | "floatFontFamily" | "floatColor">;
12
+ readonly svg: Set<"svg" | "type" | "align" | "spaceAfter" | "spaceBefore" | "height" | "width" | "src">;
13
+ readonly 'qr-code': Set<"type" | "align" | "spaceAfter" | "spaceBefore" | "data" | "size" | "errorCorrectionLevel" | "foreground" | "background" | "margin">;
14
+ readonly barcode: Set<"type" | "align" | "spaceAfter" | "spaceBefore" | "height" | "width" | "data" | "symbology" | "includeText">;
15
+ readonly chart: Set<"type" | "align" | "spaceAfter" | "spaceBefore" | "height" | "width" | "spec" | "caption">;
16
+ readonly list: Set<"type" | "fontSize" | "lineHeight" | "color" | "spaceAfter" | "spaceBefore" | "style" | "items" | "marker" | "indent" | "markerWidth" | "itemSpaceAfter" | "nestedNumberingStyle">;
17
+ readonly hr: Set<"type" | "color" | "spaceAfter" | "spaceBefore" | "thickness" | "spaceAbove" | "spaceBelow">;
18
+ readonly 'page-break': Set<"type">;
19
+ readonly code: Set<"text" | "language" | "type" | "dir" | "fontSize" | "lineHeight" | "fontFamily" | "color" | "bgColor" | "spaceAfter" | "spaceBefore" | "keepTogether" | "padding" | "highlightTheme">;
20
+ readonly 'rich-paragraph': Set<"type" | "dir" | "fontSize" | "lineHeight" | "align" | "bgColor" | "spaceAfter" | "spaceBefore" | "keepTogether" | "columns" | "columnGap" | "letterSpacing" | "smallCaps" | "tabularNumbers" | "spans">;
21
+ readonly blockquote: Set<"text" | "type" | "dir" | "fontSize" | "lineHeight" | "fontFamily" | "fontWeight" | "color" | "align" | "bgColor" | "spaceAfter" | "spaceBefore" | "keepTogether" | "underline" | "strikethrough" | "borderColor" | "borderWidth" | "padding" | "fontStyle" | "paddingH" | "paddingV">;
22
+ readonly toc: Set<"title" | "type" | "fontSize" | "fontFamily" | "spaceAfter" | "spaceBefore" | "showTitle" | "minLevel" | "maxLevel" | "titleFontSize" | "levelIndent" | "leader" | "entrySpacing">;
23
+ readonly 'toc-entry': Set<"text" | "type" | "fontFamily" | "fontWeight" | "level" | "levelIndent" | "leader" | "pageNumber">;
24
+ readonly comment: Set<"author" | "type" | "color" | "spaceAfter" | "contents" | "open">;
25
+ readonly 'form-field': Set<"type" | "fontSize" | "spaceAfter" | "spaceBefore" | "keepTogether" | "height" | "borderColor" | "width" | "backgroundColor" | "fieldType" | "name" | "label" | "placeholder" | "defaultValue" | "multiline" | "maxLength" | "checked" | "options" | "defaultSelected">;
26
+ readonly callout: Set<"content" | "title" | "type" | "dir" | "fontSize" | "lineHeight" | "fontFamily" | "fontWeight" | "color" | "spaceAfter" | "spaceBefore" | "keepTogether" | "borderColor" | "style" | "padding" | "paddingH" | "paddingV" | "backgroundColor" | "titleColor">;
27
+ readonly 'footnote-def': Set<"text" | "type" | "fontSize" | "fontFamily" | "spaceAfter" | "id">;
28
+ readonly 'float-group': Set<"image" | "content" | "type" | "spaceAfter" | "spaceBefore" | "float" | "floatWidth" | "floatGap">;
29
+ };
30
+ export declare const ALLOWED_PROPS_SUB: {
31
+ readonly document: Set<"header" | "footer" | "pageSize" | "margins" | "defaultFont" | "defaultFontSize" | "defaultLineHeight" | "fonts" | "watermark" | "encryption" | "signature" | "bookmarks" | "hyphenation" | "metadata" | "defaultParagraphStyle" | "sections" | "content" | "flattenForms" | "onImageLoadError" | "onFormFieldError" | "renderDate" | "allowedFileDirs">;
32
+ readonly metadata: Set<"title" | "author" | "subject" | "keywords" | "creator" | "language" | "producer">;
33
+ readonly 'column-def': Set<"align" | "width">;
34
+ readonly 'table-row': Set<"cells" | "isHeader">;
35
+ readonly 'table-cell': Set<"text" | "dir" | "fontSize" | "fontFamily" | "fontWeight" | "color" | "align" | "bgColor" | "tabularNumbers" | "colspan" | "rowspan">;
36
+ readonly 'list-item': Set<"text" | "dir" | "fontWeight" | "items">;
37
+ readonly 'inline-span': Set<"text" | "dir" | "fontSize" | "fontFamily" | "fontWeight" | "color" | "underline" | "strikethrough" | "url" | "letterSpacing" | "smallCaps" | "fontStyle" | "href" | "verticalAlign" | "footnoteRef">;
38
+ readonly annotation: Set<"author" | "color" | "contents" | "open">;
39
+ };
40
+ //# sourceMappingURL=allowed-props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allowed-props.d.ts","sourceRoot":"","sources":["../src/allowed-props.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8LH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;CAuBhB,CAAA;AAEV,eAAO,MAAM,iBAAiB;;;;;;;;;CASpB,CAAA"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Strict validation: allowed properties for each element and sub-structure type.
3
+ * Enforced at runtime by strict: true validation.
4
+ * Compile-time drift guards via Exact<T, Keys> ensure types stay synchronized.
5
+ */
6
+ // ─── Key arrays with compile-time assertions ──────────────────────────────────
7
+ const DOC_KEYS = [
8
+ 'pageSize', 'margins', 'defaultFont', 'defaultFontSize', 'defaultLineHeight',
9
+ 'fonts', 'header', 'footer', 'watermark', 'encryption', 'signature', 'bookmarks',
10
+ 'hyphenation', 'metadata', 'defaultParagraphStyle', 'sections', 'content',
11
+ 'flattenForms', 'onImageLoadError', 'onFormFieldError', 'renderDate', 'allowedFileDirs',
12
+ ];
13
+ const METADATA_KEYS = ['title', 'author', 'subject', 'keywords', 'creator', 'language', 'producer'];
14
+ const PARAGRAPH_KEYS = [
15
+ 'type', 'text', 'dir', 'fontSize', 'lineHeight', 'fontFamily', 'fontWeight', 'color',
16
+ 'align', 'bgColor', 'spaceAfter', 'spaceBefore', 'keepTogether', 'underline',
17
+ 'strikethrough', 'url', 'columns', 'columnGap', 'hyphenate', 'letterSpacing',
18
+ 'smallCaps', 'tabularNumbers', 'annotation',
19
+ ];
20
+ const HEADING_KEYS = [
21
+ 'type', 'level', 'text', 'dir', 'fontFamily', 'fontWeight', 'fontSize', 'lineHeight',
22
+ 'align', 'color', 'bgColor', 'spaceBefore', 'spaceAfter', 'keepTogether', 'underline',
23
+ 'strikethrough', 'bookmark', 'hyphenate', 'url', 'anchor', 'letterSpacing', 'smallCaps',
24
+ 'tabularNumbers', 'annotation',
25
+ ];
26
+ const SPACER_KEYS = ['type', 'height'];
27
+ const TABLE_KEYS = [
28
+ 'type', 'columns', 'rows', 'dir', 'headerRows', 'borderColor', 'borderWidth',
29
+ 'headerBgColor', 'fontSize', 'cellPaddingH', 'cellPaddingV', 'spaceAfter', 'spaceBefore',
30
+ ];
31
+ const COLUMN_DEF_KEYS = ['width', 'align'];
32
+ const TABLE_ROW_KEYS = ['cells', 'isHeader'];
33
+ const TABLE_CELL_KEYS = [
34
+ 'text', 'dir', 'align', 'fontWeight', 'fontFamily', 'fontSize', 'color', 'bgColor',
35
+ 'colspan', 'rowspan', 'tabularNumbers',
36
+ ];
37
+ const IMAGE_KEYS = [
38
+ 'type', 'src', 'format', 'width', 'height', 'align', 'spaceAfter', 'spaceBefore',
39
+ 'float', 'floatWidth', 'floatGap', 'floatText', 'floatSpans', 'floatFontSize',
40
+ 'floatFontFamily', 'floatColor',
41
+ ];
42
+ const SVG_KEYS = ['type', 'svg', 'src', 'width', 'height', 'align', 'spaceBefore', 'spaceAfter'];
43
+ const QR_CODE_KEYS = [
44
+ 'type', 'data', 'size', 'errorCorrectionLevel', 'foreground', 'background', 'margin',
45
+ 'align', 'spaceBefore', 'spaceAfter',
46
+ ];
47
+ const BARCODE_KEYS = [
48
+ 'type', 'symbology', 'data', 'width', 'height', 'includeText', 'align', 'spaceBefore', 'spaceAfter',
49
+ ];
50
+ const CHART_KEYS = ['type', 'spec', 'width', 'height', 'caption', 'align', 'spaceBefore', 'spaceAfter'];
51
+ const LIST_KEYS = [
52
+ 'type', 'style', 'items', 'marker', 'indent', 'markerWidth', 'fontSize', 'lineHeight',
53
+ 'itemSpaceAfter', 'spaceAfter', 'spaceBefore', 'color', 'nestedNumberingStyle',
54
+ ];
55
+ const LIST_ITEM_KEYS = ['text', 'dir', 'fontWeight', 'items'];
56
+ const HR_KEYS = ['type', 'thickness', 'color', 'spaceAbove', 'spaceBelow', 'spaceBefore', 'spaceAfter'];
57
+ const PAGE_BREAK_KEYS = ['type'];
58
+ const CODE_KEYS = [
59
+ 'type', 'text', 'dir', 'fontFamily', 'fontSize', 'lineHeight', 'bgColor', 'color',
60
+ 'padding', 'spaceAfter', 'spaceBefore', 'keepTogether', 'language', 'highlightTheme',
61
+ ];
62
+ const RICH_PARAGRAPH_KEYS = [
63
+ 'type', 'spans', 'dir', 'fontSize', 'lineHeight', 'align', 'bgColor', 'spaceBefore',
64
+ 'spaceAfter', 'keepTogether', 'columns', 'columnGap', 'letterSpacing', 'smallCaps',
65
+ 'tabularNumbers',
66
+ ];
67
+ const INLINE_SPAN_KEYS = [
68
+ 'text', 'dir', 'fontFamily', 'fontWeight', 'fontStyle', 'color', 'fontSize', 'underline',
69
+ 'strikethrough', 'url', 'href', 'verticalAlign', 'smallCaps', 'letterSpacing', 'footnoteRef',
70
+ ];
71
+ const BLOCKQUOTE_KEYS = [
72
+ 'type', 'text', 'dir', 'borderColor', 'borderWidth', 'bgColor', 'color', 'fontFamily',
73
+ 'fontWeight', 'fontStyle', 'fontSize', 'lineHeight', 'padding', 'paddingH', 'paddingV',
74
+ 'align', 'spaceBefore', 'spaceAfter', 'keepTogether', 'underline', 'strikethrough',
75
+ ];
76
+ const CALLOUT_KEYS = [
77
+ 'type', 'content', 'style', 'title', 'backgroundColor', 'borderColor', 'color', 'titleColor',
78
+ 'fontFamily', 'fontWeight', 'fontSize', 'lineHeight', 'padding', 'paddingH', 'paddingV',
79
+ 'spaceAfter', 'spaceBefore', 'keepTogether', 'dir',
80
+ ];
81
+ const COMMENT_KEYS = ['type', 'contents', 'author', 'color', 'open', 'spaceAfter'];
82
+ const FORM_FIELD_KEYS = [
83
+ 'type', 'fieldType', 'name', 'label', 'placeholder', 'defaultValue', 'multiline',
84
+ 'maxLength', 'checked', 'options', 'defaultSelected', 'width', 'height', 'fontSize',
85
+ 'borderColor', 'backgroundColor', 'spaceAfter', 'spaceBefore', 'keepTogether',
86
+ ];
87
+ const FOOTNOTE_DEF_KEYS = ['type', 'id', 'text', 'fontSize', 'fontFamily', 'spaceAfter'];
88
+ const TOC_KEYS = [
89
+ 'type', 'title', 'showTitle', 'minLevel', 'maxLevel', 'fontSize', 'titleFontSize',
90
+ 'levelIndent', 'leader', 'entrySpacing', 'fontFamily', 'spaceBefore', 'spaceAfter',
91
+ ];
92
+ const TOC_ENTRY_KEYS = ['type', 'text', 'pageNumber', 'level', 'levelIndent', 'leader', 'fontFamily', 'fontWeight'];
93
+ const FLOAT_GROUP_KEYS = ['type', 'image', 'float', 'floatWidth', 'floatGap', 'content', 'spaceBefore', 'spaceAfter'];
94
+ const ANNOTATION_KEYS = ['contents', 'author', 'color', 'open'];
95
+ // ─── Runtime Sets created from key arrays ─────────────────────────────────────
96
+ export const ALLOWED_PROPS = {
97
+ 'paragraph': new Set(PARAGRAPH_KEYS),
98
+ 'heading': new Set(HEADING_KEYS),
99
+ 'spacer': new Set(SPACER_KEYS),
100
+ 'table': new Set(TABLE_KEYS),
101
+ 'image': new Set(IMAGE_KEYS),
102
+ 'svg': new Set(SVG_KEYS),
103
+ 'qr-code': new Set(QR_CODE_KEYS),
104
+ 'barcode': new Set(BARCODE_KEYS),
105
+ 'chart': new Set(CHART_KEYS),
106
+ 'list': new Set(LIST_KEYS),
107
+ 'hr': new Set(HR_KEYS),
108
+ 'page-break': new Set(PAGE_BREAK_KEYS),
109
+ 'code': new Set(CODE_KEYS),
110
+ 'rich-paragraph': new Set(RICH_PARAGRAPH_KEYS),
111
+ 'blockquote': new Set(BLOCKQUOTE_KEYS),
112
+ 'toc': new Set(TOC_KEYS),
113
+ 'toc-entry': new Set(TOC_ENTRY_KEYS),
114
+ 'comment': new Set(COMMENT_KEYS),
115
+ 'form-field': new Set(FORM_FIELD_KEYS),
116
+ 'callout': new Set(CALLOUT_KEYS),
117
+ 'footnote-def': new Set(FOOTNOTE_DEF_KEYS),
118
+ 'float-group': new Set(FLOAT_GROUP_KEYS),
119
+ };
120
+ export const ALLOWED_PROPS_SUB = {
121
+ 'document': new Set(DOC_KEYS),
122
+ 'metadata': new Set(METADATA_KEYS),
123
+ 'column-def': new Set(COLUMN_DEF_KEYS),
124
+ 'table-row': new Set(TABLE_ROW_KEYS),
125
+ 'table-cell': new Set(TABLE_CELL_KEYS),
126
+ 'list-item': new Set(LIST_ITEM_KEYS),
127
+ 'inline-span': new Set(INLINE_SPAN_KEYS),
128
+ 'annotation': new Set(ANNOTATION_KEYS),
129
+ };
130
+ //# sourceMappingURL=allowed-props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allowed-props.js","sourceRoot":"","sources":["../src/allowed-props.ts"],"names":[],"mappings":"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"}
package/dist/assets.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { PDFDocument } from '@cantoo/pdf-lib';
2
- import type { PdfDocument, ImageMap } from './types.js';
2
+ import type { PdfDocument } from './types.js';
3
+ import type { ImageMap } from './types-internal.js';
4
+ import type { PluginDefinition } from './plugin-types.js';
3
5
  /**
4
6
  * Enforce allowedFileDirs: resolved absolute path must start with an allowed dir.
5
7
  * No-op when allowedFileDirs is unset (backwards-compatible default).
@@ -26,5 +28,5 @@ export declare function assertSafeUrl(url: string, errorCode: 'IMAGE_LOAD_FAILED
26
28
  * Images that fail to load (network error, file not found, unreachable URL) are
27
29
  * logged as warnings but do not crash the document — the document renders without that image.
28
30
  */
29
- export declare function loadImages(doc: PdfDocument, pdfDoc: PDFDocument, contentWidth: number): Promise<ImageMap>;
31
+ export declare function loadImages(doc: PdfDocument, pdfDoc: PDFDocument, contentWidth: number, plugins?: PluginDefinition[]): Promise<ImageMap>;
30
32
  //# sourceMappingURL=assets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAyE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAK9H;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAa9G;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAiDlH;AAgSD;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwI/G"}
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAyE,MAAM,YAAY,CAAA;AACpH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAKzD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAa9G;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAiDlH;AAgSD;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0J7I"}